如何取得nginx做反向代理时的真实IP?

简介: nginx做反向代理时的真实IP.pdf 1. 编译 对于client -> nginx reverse proxy -> apache, 要想在程序中取得真实的IP,在执行nginx的configure时,必须指定参数“--with-http_realip_module”,示例: .
img_e25d4fb2f8de1caf41a735ec53088516.pngnginx做反向代理时的真实IP.pdf

1. 编译

对于client -> nginx reverse proxy -> apache,

要想在程序中取得真实的IP,在执行nginxconfigure时,必须指定参数“--with-http_realip_module”,示例:

./configure --prefix=/data/nginx --with-http_realip_module --with-stream --with-pcre=/tmp/X/pcre-8.32 --with-openssl=/tmp/X/openssl-1.0.2a

 

参数说明:

--prefix= 指定安装目录,也就是make install后程序文件等的存放目录

--with-http_realip_module 使得程序可以通过环境变量HTTP_X_REAL_IP取得真实的客户端IP地址

--with-stream 表示启用TCP代理

--with-pcre= 指定依赖的pcre,注意为pcre源代码解压后的目录路径,而不是安装路径

--with-openssl= 指定依赖的openssl,注意为openssl源代码解压后的目录路径,而不是安装路径

 

另外,最简单的确认方法是使用nm命令查看nginx程序文件,看看是否有包含real相关的符号,对于版本nginx-1.9.4 ,可以发现存在“0809c54b t ngx_http_realip”。

2. 程序代码

测试程序代码(后续测试基于它):

// g++ -g -o hello.cgi hello.cpp

#include 

#include 

int main()

{

        printf("Content-Type: text/html; charset=utf-8\r\n\r\n");

        printf("

HTTP_X_FORWARDED_FOR: %s\n", getenv("HTTP_X_FORWARDED_FOR"));

        printf("

HTTP_X_REAL_IP: %s\n", getenv("HTTP_X_REAL_IP"));

        printf("

REMOTE_ADDR: %s\n", getenv("REMOTE_ADDR"));

        printf("

");

        return 0;

}

 

测试是在nginx自带配置文件nginx.conf上进行的修改:

proxy_set_header可以添加在nginx.confhttp段,也可以是server段,还可以是location段,一级一级间是继承和覆盖关系。

3. 相关配置

示例:

location / {

#    root   html;

#    index  index.html index.htm;

    proxy_pass http://20.61.28.11:80;

    proxy_redirect off;

    proxy_set_header   Host    $host; 

    proxy_set_header   X-Real-IP   $remote_addr;  # 这个是必须的

    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 

}

 

X-Forwarded-ForX-Real-IP的区别是,如果请求时已带了X-Forwarded-For,则nginx追加方式,这样可以通过它显示转发的轨迹。

当然请求时完全可以构造假的X-Forwarded-For,在配置文件打开了X-Real-IP及编译指定了--with-http_realip_module时,环境变量HTTP_X_REAL_IP总是为真实的客户端IP

 

如果是:

client -> nginx reverse proxy (A) -> nginx reverse proxy (B) -> apache

HTTP_X_REAL_IP又会是什么了?

4. 测试1

假设如下部署:

client(10.6.81.39) -> nginx(10.6.223.44:8080) -> nginx(10.6.208.101:8080) -> apache(10.6.208.101:80)

 

? A

假设nginx(10.6.223.44:8080)的配置均为(在nginx默认配置上的修改部分):

server {

    listen       8080;

    server_name  10.6.223.44;

    location / {

    #    root   html;

    #    index  index.html index.htm;

        proxy_pass http://10.6.208.101:8080;

        proxy_redirect off;

        proxy_set_header   Host    $host;

        proxy_set_header   X-Real-IP   $remote_addr;

        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

    }

 

假设nginx(10.6.208.101:8080)的配置均为(在nginx默认配置上的修改部分):

server {

    listen       8080;

    server_name  10.6.208.101;

    location / {

    #    root   html;

    #    index  index.html index.htm;

        proxy_pass http://10.6.208.101:80;

        proxy_redirect off;

        proxy_set_header   Host    $host;

        proxy_set_header   X-Real-IP   $remote_addr;

        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

    }

 

上述测试程序输出的结果为:

HTTP_X_FORWARDED_FOR: 10.6.81.39, 10.6.223.44

HTTP_X_REAL_IP: 10.6.223.44

REMOTE_ADDR: 10.6.81.39

 

? B

但如果clientHTTP请求头中加入:

X-FORWARDED-FOR:8.8.8.7

CLIENT-IP:8.8.8.8

X-REAL-IP:8.8.8.10

后输出结果变成:

HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39, 10.6.223.44

HTTP_X_REAL_IP: 10.6.223.44

REMOTE_ADDR: 8.8.8.7

 

? C

基于A如果只nginx(10.6.223.44:8080)配置注释掉“X-Forwarded-For”,输出结果变成:

HTTP_X_FORWARDED_FOR: 10.6.223.44

HTTP_X_REAL_IP: 10.6.223.44

REMOTE_ADDR: 10.6.223.44

 

? D

基于A如果只nginx(10.6.208.101:8080)配置注释掉“X-Forwarded-For”,输出结果变成:

HTTP_X_FORWARDED_FOR: 10.6.81.39

HTTP_X_REAL_IP: 10.6.223.44

REMOTE_ADDR: 10.6.81.39

5. 测试2

基于测试1的配置,

当访问路径变成:client(10.6.81.39) -> nginx(10.6.208.101:8080) -> apache(10.6.208.101:80)时,程序输出结果为:

HTTP_X_FORWARDED_FOR: 10.6.81.39

HTTP_X_REAL_IP: 10.6.81.39

REMOTE_ADDR: 10.6.81.39

 

但如果clientHTTP请求头中加入:

X-FORWARDED-FOR:8.8.8.7

CLIENT-IP:8.8.8.8

X-REAL-IP:8.8.8.10

后输出结果变成:

HTTP_X_FORWARDED_FOR: 8.8.8.7, 10.6.81.39

HTTP_X_REAL_IP: 10.6.81.39

REMOTE_ADDR: 8.8.8.7

 

从上可以看出,只配置正确使用了real-ip功能,除HTTP_X_REAL_IP外,其它内容可以被干扰,client可以篡改它们。

6. 结论

如果正确编译和配置了nginx反向代理,当只有一层nginx反向代理时,可以通过“HTTP_X_REAL_IP”取得client的真实IP

 

如果有二层nginx反向代理,则client的真实IP被包含在“HTTP_X_FORWARDED_FOR”中。

 

最不可信的是“REMOTE_ADDR”,它的内容完全可以被client指定!总之只要编译和配置正确,“HTTP_X_FORWARDED_FOR”总是包含了client的真实IP

 

相关文章
|
2月前
|
负载均衡 监控 应用服务中间件
配置Nginx反向代理时如何指定后端服务器的权重?
配置Nginx反向代理时如何指定后端服务器的权重?
160 61
|
2月前
|
缓存 负载均衡 安全
Nginx的反向代理具体是如何实现的?
Nginx的反向代理具体是如何实现的?
|
19天前
|
缓存 Java 应用服务中间件
nginx的正向代理和反向代理以及tomcat
Nginx的正向代理和反向代理功能在不同的场景中具有重要作用,正向代理主要用于客户端访问控制和匿名浏览,而反向代理则用于负载均衡和高可用性服务。Tomcat作为Java Web应用服务器,与Nginx结合使用,可以显著提升Web应用的性能和稳定性。通过合理配置Nginx和Tomcat,可以构建高效、稳定和可扩展的Web服务架构。
104 11
|
28天前
|
存储 应用服务中间件 nginx
nginx反向代理bucket目录配置
该配置实现通过Nginx代理访问阿里云OSS存储桶中的图片资源。当用户访问代理域名下的图片URL(如 `http://代理域名/123.png`)时,Nginx会将请求转发到指定的OSS存储桶地址,并重写路径为 `/prod/files/2024/12/12/123.png`。
71 5
|
2月前
|
缓存 负载均衡 算法
如何配置Nginx反向代理以实现负载均衡?
如何配置Nginx反向代理以实现负载均衡?
|
1月前
|
监控 应用服务中间件 定位技术
要统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现
要统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现
116 3
|
2月前
|
安全 应用服务中间件 网络安全
如何测试Nginx反向代理实现SSL加密访问的配置是否正确?
如何测试Nginx反向代理实现SSL加密访问的配置是否正确?
111 3
|
2月前
|
安全 应用服务中间件 网络安全
配置Nginx反向代理实现SSL加密访问的步骤是什么?
我们可以成功地配置 Nginx 反向代理实现 SSL 加密访问,为用户提供更安全、可靠的网络服务。同时,在实际应用中,还需要根据具体情况进行进一步的优化和调整,以满足不同的需求。SSL 加密是网络安全的重要保障,合理配置和维护是确保系统安全稳定运行的关键。
176 3
|
Web App开发 应用服务中间件 nginx
|
应用服务中间件 PHP Apache