6

I host an node.js server with express.js in a docker container. The address of my container is 172.17.0.62 And I use nginx to redirect the traffic to 172.17.0.62

I can access the my server. But when I use

console.log(req.ip + ' ' + req.protocol + ' ' + req.originalUrl);

to log the traffic. req.ip is always 172.17.42.1. I want to get the ip of viewer of my webpage

I use this in my nginx configuration

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

and

cat /proc/sys/net/ipv4/ip_forward # output 1
sundayku
  • 172
  • 1
  • 7

3 Answers3

5

I haven't used docker - but you should be able to get the information you want from x-forwarded-for: Express.js: how to get remote client address

From the above link:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

Oh and interesting to note - a second answer in the above thread might actually be superior for your needs. Instead of changing your code everywhere that gets tries to get the user's ip address. You can just change how you initialize express:

app.enable('trust proxy');
Community
  • 1
  • 1
Tim
  • 539
  • 2
  • 9
1

FYI this is not possible in a swarm condition. I stumbled across this trying to look for a solution. I have an nginx container in a docker-compose setup and can't get my client's IP, so I will need to remove nginx routing from the swarm. It's been a known issue apparently: https://github.com/moby/moby/issues/25526

Kevin Danikowski
  • 4,620
  • 6
  • 41
  • 75
0

If you are using docker for nginx;

You can add proxy header nginx config for proxy pass;

server {
  listen 80 default_server;

  location /api {
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_pass          http://localhost:8181;
    proxy_read_timeout  90;
  }
}

And get Ip Nodejs Express bellow code

private getIP(req: any) {
        // req.connection is deprecated
        const conRemoteAddress = req.connection?.remoteAddress
        // req.socket is said to replace req.connection
        const sockRemoteAddress = req.socket?.remoteAddress
        // some platforms use x-real-ip
        const xRealIP = req.headers['x-real-ip']
        // most proxies use x-forwarded-for
        const xForwardedForIP = (() => {
            const xForwardedFor = req.headers['x-forwarded-for']
            if (xForwardedFor) {
                // The x-forwarded-for header can contain a comma-separated list of
                // IP's. Further, some are comma separated with spaces, so whitespace is trimmed.
                const ips = xForwardedFor.split(',').map((ip: string) => ip.trim())
                return ips[0]
            }
        })()
        // prefer x-forwarded-for and fallback to the others
        return xForwardedForIP || xRealIP || sockRemoteAddress || conRemoteAddress
    }
Yasin Bikmazer
  • 104
  • 1
  • 8