nodejs 服务器获取用户请求真实ip

由于政策的要求,用户发布内容,需要显示ip所在地理位置,在这个问题上,我踩了一些坑。

首先,如果只是单个的nodejs 服务器,目前一般用的是koa 或者eggjs,可以直接使用`ctx.ip` 来获取。

但一般我们会把server 放在nginx 后面,这样,就需要告诉nginx 帮忙转发真实的ip 地址。可以根据eggjs 教程配置

通过设置 config.proxy = true 可以开启前置代理模式:

// config/config.default.js
exports.proxy = true;

 配置nginx

location / {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Real-Port $remote_port;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1:81;
 }

获取ip就就简单了

this.ctx.request.ip

但最终我发现我获取到的ip多数是172 开头的ip,经过层层排查,有文章说到是因为docker 网络桥接模式导致的。

network_mode

根本原因是docker 在起服务的时候,有多种网络模式,模式是桥接模式。docker-compose 默认为桥接模式,有单独的子网。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

要解决真实ip 转发问题,最简单的就是改为使用host 模式,和宿主机共用一个网络。

version:  '3.2'
  abc:
    image: abc/edf
    container_name: abc
    restart: always
    network_mode: "host"

坏处就是不能使用端口映射了,如果一台宿主机上有多服务在容器内需要使用同一个端口会冲突。

桥接模式也能实现ip 的转发,看教程是说把网桥加入到防火墙的internal(内部)区域,这个还没跑通,暂时先搁置,记录下。

Leave a Comment

邮箱地址不会被公开。 必填项已用*标注