ngx_http_realip模块获取客户端真实IP

X-Forwarded-For

我们常常使用 Nginx 作为 Web 站点的反向代理服务器,如下图所示,我们可以通过 Nginx 的内置变量 $remote_addr 来获取客户端访问的 IP。

image.png

当我们的 Web 站点接入 CDN 或者 WAF 后,$remote_addr 却是 CDN 或者 WAF 的 IP,因为 CDN 获取 WAF 这里也充当了一个反向代理服务器。为了解决这个问题,RFC 7239(Forwarded HTTP Extension)标准中定义了 X-Forwareded-For,X-Forwareded-For 放在 HTTP Header 中,格式如下:

X-Forwarded-For: client1, proxy1, proxy2

其中的值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。一般来说,CDN 或者 WAF 的厂商均会准守这个协议,所以你接入 CDN 或者 WAF 后的 X-Forwarded-For 的值是 client1, CDN_IP/WAF_IP,所以,我们可以通过解析 X-Forwarded-For 来获取真正的客户端访问 IP。

ngx_http_realip_module

ngx_http_realip 模块的作用是当你的 nginx 服务器位于一个反向代理后面时,去获取客户端真实访问的 IP。这个模块默认没有编译到 Nginx 中,需要在编译时通过 --with-http_realip_module 开启。

这个模块的相关配置如下:

set_real_ip_from  192.168.1.0/24;
real_ip_header    X-Forwarded-For;
real_ip_recursive on;
  • set_real_ip_from: address | CIDR | unix:, 定义信任地址(trusted address),配合后续的 real_ip_recursive 使用。
  • real_ip_header: field | X-Real-IP | X-Forwarded-For | proxy_protocol, 默认值是 X-Real-IP, 定义真实的 IP 在请求头中的字段名。
  • real_ip_recursive: on | off, 默认值是 off,如果是 off,则使用 real_ip_header 请求头中匹配信任地址(trusted address)中最后一个作为客户端请求的真实 IP;如果是 on , 则取匹配的前一个值作为客户端真实 IP。

ngx_http_realip 模块将用获取到的客户端真实 IP 作为 Nginx 内置变量 $remote_addr 的值。这样你又能通过 $remote_addr 得到你客户端访问的真实 IP 了。

另外,除了使用 ngx_http_realip 模块,你也可以通过 Lua 脚本去解析 X-Forwarded-For,从而获取真实的 IP。

参考

  • http://nginx.org/en/docs/http/ngx_http_realip_module.html

你可能感兴趣的:(ngx_http_realip模块获取客户端真实IP)