容器中的 Node.js 始终获取 docker0 ip

Posted

技术标签:

【中文标题】容器中的 Node.js 始终获取 docker0 ip【英文标题】:Node.js in container always get the docker0 ip 【发布时间】:2016-03-31 02:02:07 【问题描述】:

我在 docker 容器中托管了一个带有 express.js 的 node.js 服务器。 我的容器地址是 172.17.0.62 我使用 nginx 将流量重定向到 172.17.0.62

我可以访问我的服务器。 但是当我使用

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

记录流量。 req.ip 始终为 172.17.42.1。 我想获取我的网页浏览器的 ip

我在我的 nginx 配置中使用它

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

cat /proc/sys/net/ipv4/ip_forward # output 1

【问题讨论】:

【参考方案1】:

如果您将 docker 用于 nginx

你可以为proxy pass添加proxy header nginx配置;

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;
  

并获得 Ip Nodejs Express 波纹管代码

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
    

【讨论】:

【参考方案2】:

仅供参考,这在群体条件下是不可能的。我偶然发现了这个,试图寻找解决方案。我在 docker-compose 设置中有一个 nginx 容器,无法获取客户端的 IP,因此我需要从 swarm 中删除 nginx 路由。这显然是一个已知问题:https://github.com/moby/moby/issues/25526

【讨论】:

【参考方案3】:

我没有使用过 docker - 但你应该能够从 x-forwarded-for 获得你想要的信息: Express.js: how to get remote client address

从上面的链接:

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

哦,有趣的是 - 上述线程中的第二个答案实际上可能更适合您的需求。而不是在任何地方更改您的代码以尝试获取用户的 IP 地址。您可以更改初始化 express 的方式:

app.enable('trust proxy');

【讨论】:

有效!感谢您提供链接。它帮助我了解更多关于 ip 转发的信息。酷!

以上是关于容器中的 Node.js 始终获取 docker0 ip的主要内容,如果未能解决你的问题,请参考以下文章

node.js 中的回调是始终异步还是始终同步?或者它们可以是“有时是一个,有时是另一个”?

docker容器访问宿主机IP

无论证书有效性如何,我的 node.js https 客户端始终有效

容器安全之不使用Docker的默认网桥docker0

Node.js连接本地Docker中的Redis

更换docker容器默认网桥docker0