Nginx 获取客户端真实 IP 的终极方法

Nginx/Web服务器
492
0
0
2022-03-27
标签   Nginx基础

问题描述

获取客户端真实网络地址,有时候让人头疼。尤其是多种中间件联合使用时,层层相套,而且大家又使用不同的规范,将客户端的真实 IP 地址保存在不同的请求头中。

在这篇笔记中,我们将尝试寻找一种通用的方案,该方案可以让我们方便地定位到客户端的真实 IP 地址。

该笔记将记录:在 Nginx 中,调试并获取客户端真实网络地址(IP Address)的相关方法。

解决方案

第一步、查看客户端的网络地址

客户端的真实网络地址是通过 HTTP 请求头传递的(除了 Proxy 协议,因为我们用的不多,所以这里未讨论该协议)

所以,我们打印所有的与网络地址有关的变量及请求头(至少是我们知道的),这样我们就能知道各种地址信息:

log_format client_ip_address '[$time_local] Host="$http_host", '
                             'Forwarded="$http_forwarded", '
                             'X-Forwarded-For="$http_x_forwarded_for", '
                             'X-Forwarded-Host="$http_x_forwarded_host", '
                             'X-Forwarded-Proto="$http_x_forwarded_proto", '
                             'X-REAL-IP="$http_x_real_ip", '
                             'realip_remote_addr="$realip_remote_addr", '
                             'remote_addr="$remote_addr", '
                             'server_addr="$server_addr", '
                             'upstream_addr="$upstream_addr", ' ;

server {
	...
    access_log /var/log/nginx/client-ip-address.log client_ip_address;
    ...
}

在这些地址中,如果没有出现客户端的真实网络地址,那多半表示上游下来的请求存在问题。需要修改上游服务,以传递客户端真实网络地址。

第二步、设置请求头,以传递真实地址

如果客户端的真实网络地址出现在这些字段中,那么我们需要将该地址传递给下游服务器。

这样要根据下游服务器的要求进行设置,比如下游服务器从 X-Forwarded-For 中读取客户端真实网络地址,那我们这里的 Nginx 就要设置:

# proxy_set_header X-Forwarded-For <the variable containing real_ip_address>

# 比如,如下配置行
proxy_set_header X-Forwarded-For $remote_addr;

注意事项,在 RFC 中,没有 X-Real-IP 字段的描述,该字段可能是 Web Server 自定义的字段。如果下游服务器从 X-Real-IP 中读取客户端真实网络地址,那我们就要设置 X-Real-IP 字段。

相关链接

与代理有关的 HTTP 字段

参考文献

Alphabetical index of variables