AWS just added support to ELB for the PROXY protocol, which wraps TCP streams and adds the client IP address (as seen by the proxy) so that the backend server has access to the client's IP (since it would otherwise just see the ELB's IP).
I know that ELB can run in HTTP(S) mode, where the ELB inserts a X-Forwarded-For
header, but I run my ELBs in TCP mode so that I can serve my site over SPDY.
How can I modify my node.js app (using Express) to use the PROXY protocol?
I made a module caled proxywrap that wraps node.js Server
s and automatically strips the PROXY protocol headers from connections' streams, and resets socket.remoteAddress
and socket.remotePort
to the values found in the PROXY headers.
It works with the built-in Server
modules (like http
, https
, and net
) as a drop-in replacement for the module:
var http = require('http')
, proxiedHttp = require('proxywrap').proxy(http)
, express = require('express')
, app = express()
, srv = proxiedHttp.createServer(app); // instead of http.createServer(app)
app.get('/', function(req, res) {
res.send('IP = ' + req.connection.remoteAddress + ':' + req.connection.remotePort);
});
srv.listen(80);
It also works with the spdy module:
var proxiedSpdy = require('proxywrap').proxy(require('spdy').server);
Of course, you'll have to enable the PROXY protocol on your ELB (or whatever proxy your app is behind).