theturtle32 / WebSocket-Node

A WebSocket Implementation for Node.JS (Draft -08 through the final RFC 6455)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

remoteAddress is always 127.0.0.1 when the server is running behind nginx

carterw opened this issue · comments

I'm running the server behind nginx and I want to get the IP address of clients who connect.

nginx is a reverse proxy, but you should be able to properly include the remote address of a client by configuring it with;
proxy_set_header X-Real-IP $remote_addr;

That doesn't seem to help here though. Where is the 'remoteAddress' value being extracted for the connection?

wss.on('connect', function(connection){
  // connection.remoteAddress is always 127.0.0.1
}

Read the corresponding HTTP header. This is not a bug at all.

Where is the header available in the connection object? Not seeing it.

And if the remoteAddress field is incorrect it sure seems like a bug to me.

Where is the header available in the connection object? Not seeing it.

Same as for any http request. Check the docs again, please.

And if the remoteAddress field is incorrect it sure seems like a bug to me.

remoteAddress doesn't mean what you may thing.

Why the combative attitude? remoteAddress obviously should show the IP address of the remote node. Showing it as localhost is worthless, and I will note that millions of websites use nginx as the webserver so this will not be an unusual problem.

I am not seeing anything in the skimpy WebSocketServer docs about a http request, but digging around in the code I see that it is passed as an argument to the 'request' event; request.httpRequest.headers

Unfortunately the 'x-real-ip' field is not included in the headers object there, whereas it is included in conventional http requests received by my website code running on the server. Also the 'origin' field shows as the local machine, not the remote client. I'd be glad to pull the actual remote IP address from wherever it is available if you can point that out for me.

No combative attitude at all, I promise.

The HTTP header must be there (if it was in the received HTTP websocket GET request). I used it in the past so pretty sure it's there.

Remote address is the IP from where the HTTP GET is received. In this case it's Ngnix.

Right, but seeing as how nginx is the reverse proxy which fields all of the incoming requests and distributes them to the resident webapps there has to be a way to obtain the original client IP address. For conventional webapp requests this comes in as part of the header;
'x-real-ip': '65.111.119.133'

But that field does not seem to appear in the WebSocketServer header.

From the docs:

WebSocketRequest

httpRequest
A reference to the original Node HTTP request object

So, if your Nginx proxy is adding such a X-Real-IP header, then it must be there. But you are not even proving that your Nginx proxy is adding that header. Imagine that it's not doing it and you are blaming Node WebSocket server.

BTW: https://github.com/theturtle32/WebSocket-Node/blob/a2cd3065167668a9685db0d5f9c4083e8a1839f0/docs/WebSocketRequest.md#remoteaddress

So, indeed, remoteAddress will return the IP of the X-Forwarded-For header (if present). But it does not read the X-Real-IP.

Thanks for that info. I've taken steps to add the X-Forwarded-For header, and for a conventional website request I am now seeing;

  'x-real-ip': '65.111.119.133',
  'x-forwarded-for': ', 65.111.119.133',

But neither of those headers are appearing in the websocket request so it isn't clear what is happening. I do see code in WebSocketRequest.js that looks for the x-forwarded-for value. It is possible that nginx treats websocket upgrade requests differently, I will investigate.