翻译此页面

运行在反向代理后的 Express 应用

在反向代理后运行 Express 应用时,部分 Express API 的返回值可能与预期不符。 为此可配置应用设置项 trust proxy ,让 Express 接口能够获取反向代理转发的请求信息。 最常见的问题是,用于获取客户端IP的Express接口,获取到的IP实为反向代理的内网地址。

Note

配置trust proxy设置时,务必清楚反向代理的具体部署架构。 由于该配置会信任请求中携带的参数值,因此Express中的配置必须与反向代理的运行方式完全匹配,这一点至关重要。

应用设置项 trust proxy 可设置为下表所列值之一。

TypeValue
Boolean

若设为 true,客户端IP地址将被认定为X-Forwarded-For请求头中最左侧的条目。

若设为 false,表示应用直接面向客户端,客户端IP地址取自 req.socket.remoteAddress。 该值为默认配置。

将此项设为 true 时,务必确保最后一级受信反向代理会移除/覆盖以下所有HTTP请求头:X-Forwarded-ForX-Forwarded-HostX-Forwarded-Proto,否则客户端可能伪造任意值。

IP addresses

可配置为一个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'); // specify a single subnet
app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array

指定后,这些IP地址或子网将被排除在地址判定流程之外,最靠近应用服务器的非受信IP将被认定为客户端IP地址。 其工作原理是检查 req.socket.remoteAddress 是否为可信任地址。 若为可信地址,则从右向左检查X-Forwarded-For中的每个地址,直至找到第一个非可信地址。

Number

使用距离 Express 应用不超过 n 个网络跳数的地址。 req.socket.remoteAddress 为第一跳,其余地址从X-Forwarded-For请求头中从右向左查找。 取值为 0 表示:第一个非可信地址就是 req.socket.remoteAddress,即不存在反向代理。

使用该配置时,必须确保不存在多条长度不同的路径到达 Express 应用,避免客户端与服务的跳数少于配置值,否则客户端可能伪造任意值。

Function

自定义信任实现。

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 会产生以下影响:

  • The value of req.hostname is derived from the value set in the X-Forwarded-Host header, which can be set by the client or by the proxy.

  • 反向代理可通过设置X-Forwarded-Proto请求头,告知应用当前请求协议是httpshttp,或是非法协议标识。 This value is reflected by req.protocol.

  • The req.ip and req.ips values are populated based on the socket address and X-Forwarded-For header, starting at the first untrusted address.

trust proxy 配置项依托proxy-addr包实现。 更多详情请参阅该模块文档。