Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the PROXY protocol to get the client's real IP address?

Tags:

node.js

proxy

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?

like image 680
josh3736 Avatar asked Jul 31 '13 22:07

josh3736


People also ask

How does the proxy protocol work?

The Proxy Protocol preserves a client's IP address when it passes through a proxy, which maintains the correct information in server logs. Be sure to choose proxy and server solutions that support it, since it must be enabled on both the sender and receiver.

What is HTTP proxy protocol?

HTTP Proxy Meaning: An Overview An HTTP proxy acts as a high-performance content filter on traffic received by an HTTP client and HTTP server. The HTTP proxy protocol routes client requests from web browsers to the internet and supports rapid data caching.


1 Answers

I made a module caled proxywrap that wraps node.js Servers 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).

like image 199
josh3736 Avatar answered Oct 22 '22 01:10

josh3736