Express 应用与反向代理
当 Express 应用部署在反向代理之后时,某些 Express API 可能返回与预期不同的值。为了解决这个问题,可以使用 trust proxy
应用设置来让 Express API 识别反向代理提供的信息。最常见的问题是,暴露客户端 IP 地址的 Express API 可能显示反向代理的内部 IP 地址。
配置 trust proxy
设置时,由于此设置信任请求头部中提供的值,因此确保配置与代理的行为相匹配,这对安全性和功能性非常重要。
trust proxy
应用设置可以设置为以下几种值之一:
- 布尔值 (Boolean)
true
:客户端的 IP 地址被视为X-Forwarded-For
头部的最左侧条目。false
(默认值):应用被视为直接面向客户端,客户端的 IP 地址来自req.socket.remoteAddress
。- 注意: 设置为
true
时,必须确保最后一个受信任的反向代理会移除/覆盖以下所有 HTTP 头部:X-Forwarded-For
、X-Forwarded-Host
和X-Forwarded-Proto
,否则客户端可能会提供任何值。
- IP 地址
- 可以指定单个子网、IP 地址或一组 IP 地址和子网。
- 预定义的子网名称:
loopback
–127.0.0.1/8
、::1/128
linklocal
–169.254.0.0/16
、fe80::/10
uniquelocal
–10.0.0.0/8
、172.16.0.0/12
、192.168.0.0/16
、fc00::/7
- 设置 IP 地址的方式:
app.set('trust proxy', 'loopback')
// 指定单个子网app.set('trust proxy', 'loopback, 123.123.123.123')
// 指定子网和地址app.set('trust proxy', 'loopback, linklocal, uniquelocal')
// 逗号分隔指定多个子网app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal'])
// 数组指定多个子网
- 指定的 IP 地址或子网将被排除在地址确定过程中,最接近应用服务器的非信任 IP 地址将被视为客户端的 IP 地址。判断方法是检查
req.socket.remoteAddress
是否受信任。如果是,则从右向左依次检查X-Forwarded-For
中的每个地址,直到找到第一个非信任的地址。
- 数字
- 使用距离 Express 应用最多
n
跳的地址。req.socket.remoteAddress
是第一跳,其余的会从X-Forwarded-For
头部中从右向左查找。值为0
表示第一个非信任地址将是req.socket.remoteAddress
,即没有反向代理。 - 使用此设置时,必须确保 到 Express 应用的路径没有长度不同的多条路径,否则客户端可能比配置的跳数更近,从而可能提供任何值。
- 使用距离 Express 应用最多
- 函数
- 自定义信任实现。示例:
app.set('trust proxy', (ip) => {
if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs
else return false
})
启用 trust proxy
会产生以下影响:
req.hostname
的值来自X-Forwarded-Host
头部设置的值,该值可以由客户端或代理设置。X-Forwarded-Proto
可以由反向代理设置,告诉应用它是https
、http
还是甚至是一个无效的名称。此值会反映在req.protocol
中。req.ip
和req.ips
的值基于套接字地址和X-Forwarded-For
头部分别设置,从第一个非信任地址开始。
trust proxy
设置使用 proxy-addr 软件包实现。有关详细信息,请参阅其文档。