“信任代理”在 Express.js 中实际做什么,我需要使用它吗?

我正在编写一个坐落在 nginx 服务器后面的快递应用程序。我正在阅读 Express 的文档,其中提到了“信任代理”设置。上面只写了

启用反向代理支持,默认情况下禁用

我在这里阅读了一篇解释使用 nginx 的 Node 中的安全会话的小文章。

Http://blog.nikmartin.com/2013/07/secure-sessions-in-nodejs-with-nginx.html

所以我很好奇。在使用 HTTPS 时,将“信任代理”设置为 true 是否只起作用?目前我的应用程序只是客户端和 nginx 之间的 HTTP。如果我现在把它设为真实,有什么副作用/后果我需要知道吗?现在说这些还有意义吗?

64952 次浏览

This is explained in detail in the express behind the proxies guide

By enabling the "trust proxy" setting via app.enable('trust proxy'), Express will have knowledge that it's sitting behind a proxy and that the X-Forwarded-* header fields may be trusted, which otherwise may be easily spoofed.

Enabling this setting has several subtle effects. The first of which is that X-Forwarded-Proto may be set by the reverse proxy to tell the app that it is https or simply http. This value is reflected by req.protocol.

The second change this makes is the req.ip and req.ips values will be populated with X-Forwarded-For's list of addresses.

Annotated code to explain use of trust proxy

    var express = require('express');


var app = express();


// Set the ip-address of your trusted reverse proxy server such as
// haproxy or Apache mod proxy or nginx configured as proxy or others.
// The proxy server should insert the ip address of the remote client
// through request header 'X-Forwarded-For' as
// 'X-Forwarded-For: some.client.ip.address'
// Insertion of the forward header is an option on most proxy software
app.set('trust proxy', '127.0.0.1');




app.get('/test', function(req, res){
var ip = req.ip; // trust proxy sets ip to the remote client (not to the ip of the last reverse proxy server)
if (ip.substr(0,7) == '::ffff:') { // fix for if you have both ipv4 and ipv6
ip = ip.substr(7);
}
// req.ip and req.protocol are now set to ip and protocol of the client, not the ip and protocol of the reverse proxy server
// req.headers['x-forwarded-for'] is not changed
// req.headers['x-forwarded-for'] contains more than 1 forwarder when
// there are more forwarders between the client and nodejs.
// Forwarders can also be spoofed by the client, but
// app.set('trust proxy') selects the correct client ip from the list
// if the nodejs server is called directly, bypassing the trusted proxies,
// then 'trust proxy' ignores x-forwarded-for headers and
// sets req.ip to the remote client ip address


res.json({"ip": ip, "protocol": req.protocol, "headers": req.headers['x-forwarded-for']});
});


// in this example the reverse proxy is expected to forward to port 3110
var port = 3110;
app.listen(port);
// test through proxy: http://yourproxyserver/test, req.ip should be your client ip
// test direct connection: http://yournodeserver:3110/test, req.ip should be your client ip even if you insert bogus x-forwarded-for request headers
console.log('Listening at http://localhost:' + port);

TLDR : Application setting trust proxy simply intended to be used if the express application is behind a proxy. Enabling this when there's a proxy helps to resolve following properties through well known headers (mainly X-Forwarded-For, X-Forwarded-Proto)

More details

I ended up here when searching for what trust proxy really does with regards to express-session. None of the answers helped me.

Default value - false (disabled)

IMO the best documentation is at Application Settings

trust proxy

Indicates the app is behind a front-facing proxy, and to use the X-Forwarded-* headers to determine the connection and the IP address of the client. NOTE: X-Forwarded-* headers are easily spoofed and the detected IP addresses are unreliable.

When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies. The req.ips property, then contains an array of IP addresses the client is connected through. To enable it, use the values described in the trust proxy options table.

The trust proxy setting is implemented using the proxy-addr package. For more information, see its documentation.

NOTE: Sub-apps will inherit the value of this setting, even though it has a default value.

p.s - If you are trying to see how this helps with express-session, then enabling trust proxy is required to get the correct value for req.secure

Since nginx is mentioned in the question, note that in your nginx conf (e.g. /etc/nginx/sites-enabled/default) you also need to explicitly set the header variable in order to pass it through to express:

  proxy_set_header X-Forwarded-For $remote_addr;
location /api/ {
proxy_pass               "http://127.0.0.1:8000";
}

That's the bare minimum required, however something like this below will be faster by using zone of persistent connections to your upstream server(s):

upstream backendAPI {
zone       upstreamZone     64K;
server     127.0.0.1:8000   weight=1  max_fails=2 fail_timeout=4s;
keepalive  2;
}


proxy_set_header X-Forwarded-For $remote_addr;
location /api/ {
proxy_pass           http://backendAPI;
proxy_http_version   1.1;
proxy_set_header     "Connection" "";
}

Then you can enable the user's (supposed) IP address in the express server's request object by switching on "trust proxy":

const app = express();
app.set("trust proxy", true); // populate req.ip
// you can also name the proxy servers ips for increased security:
//   app.set("trust proxy", "127.0.0.1");
//   app.set("trust proxy", "192.168.3.3");


app.get("/api/myIP", (req, res) => {
const ip = req.ip;
return res.json({ ip });
});
app.listen(8000);