Nginx 获取客户端ip

本文主要介绍怎样使用 nginx 去获取客户端的 ip 地址

有的读者可能会问,什么是客户端真实IP地址呢?下面我们通过一张图来简单介绍。

上图中,浏览器请求某个页面,浏览器请求的是代理服务器,所有请求都由代理服务器替他完成。这就导致 Web 服务器不知道客户端的真实 IP 地址,获取到的 IP 地址为代理服务器的 IP 地址。nginx 为我们提供了获取客户端 IP 地址的功能,默认是没有开启的,及 nginx 默认获取的是直接上级服务器的 IP 地址,上图中获取的是代理服务器的 IP 地址。


有的读者可能还会问,为什么一定要获取客户端的真实 IP 地址呢?原因很简单,现在大部分互联网公司通过客户端的真实 IP 地址,可以分析出该公司的产品主要地域等信息。


下面我们将详细介绍怎样在 nginx 中配置获取客户端真实 IP。详细步骤如下:

(1)nginx 要获取客户端真实 IP 需要依赖 ngx_http_realip_module 模块,默认该模块是没有被编译到 nginx 的。需要我们使用 --with-http_realip_module 去编译 nginx,使 nginx 支持 ngx_http_realip_module 模块。先查看当前 nginx 有哪些编译参数,如下:

[root@S0 sbin]# ./nginx -V
nginx version: nginx/1.16.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --with-http_ssl_module

运行 ./configure --with-http_ssl_module --with-http_realip_module 命令去预编译 nginx。如下:

[root@S0 nginx-1.16.1]# ./configure --with-http_ssl_module --with-http_realip_module
checking for OS
 + Linux 2.6.32-358.el6.i686 i686
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)
...
Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

[root@S0 nginx-1.16.1]#

预编译成功后,我们就可以运行 make 命令去编译 nginx 了。如下:

[root@S0 nginx-1.16.1]# make
make -f objs/Makefile
make[1]: Entering directory `/root/nginx-1.16.1'
make[1]: Warning: File `src/core/nginx.h' has modification time 3.5e+07 s in the future
...
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
                -e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
                -e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
                -e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
                < man/nginx.8 > objs/nginx.8
make[1]: warning:  Clock skew detected.  Your build may be incomplete.
make[1]: Leaving directory `/root/nginx-1.16.1'

编译成功后。进入到当前目录的 objs 目录,将 nginx 拷贝到已有的 nginx 的 sbin 目录,替换掉旧的 nginx。如下:

[root@S0 objs]# cp nginx /usr/local/nginx/sbin/
cp: overwrite `/usr/local/nginx/sbin/nginx'? y


(2)修改 nginx.conf 配置文件。修改配置文件如下:

server {
    listen       80;
    server_name  s0.example.com;
    
    set_real_ip_from 192.168.238.0/24;
    set_real_ip_from 192.168.238.180;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    
    location / {
        return 200 "client real ip: $remote_addr\n";
    }
}

其中:

  • set_real_ip_from —— 设置真实的 IP 地址(忽略解析 X-Forwarded-For 头)。如果 IP 地址为该命令设置的 IP 地址或 IP 段,则解析 X-Forwarded-For 头字段。如果不是,则递归解析 X-Forwarded-For 字段,获取客户端真实IP地址。

  • real_ip_header —— 解析真实客户端 IP 地址需要用到的 HTTP 头字段。

  • real_ip_recursive —— 递归解析 X-Forwarded-For 头字段。


我们可以借助浏览器插件运行,例如在 Chrome 上运行:

地址栏运行 https://s0.example.com,返回结果如下:

client real ip: 192.168.38.100

客户端真实IP地址是我们通过 X-Forwarded-For 头字段指定的。


如果你有条件,可以在真实场景下面运行试一试。


游手好闲地学习,并不比学习游手好闲好。 —— 约翰·贝勒斯
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号