Nginx 如何代理转发传递真实 ip 地址?

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
访问控制,不限时长
简介: 【10月更文挑战第32天】

Nginx 是一个高性能的反向代理服务器,也是一个非常流行的负载均衡器和 HTTP 缓存。其轻量级的设计和高并发处理能力使得它广泛应用于各种 Web 服务中。在使用 Nginx 作为反向代理服务器时,一个常见的问题是如何在代理转发过程中传递客户端的真实 IP 地址。默认情况下,Nginx 会将客户端的 IP 地址替换为代理服务器的 IP 地址,这可能会在某些情况下引发问题,比如日志记录、访问控制和地理位置追踪等。

为什么需要传递真实 IP 地址

传递真实 IP 地址的需求主要有以下几个原因:

  1. 日志记录和分析:真实 IP 地址对于日志分析和用户行为追踪至关重要。如果使用代理服务器的 IP 地址,所有请求看起来都来自同一来源,这会导致分析结果不准确。

  2. 安全和访问控制:基于 IP 地址的访问控制策略需要识别真实的客户端 IP 地址。如果只看到代理服务器的 IP 地址,访问控制策略将无法正确应用。

  3. 地理位置追踪:很多服务依赖于客户端的地理位置信息,而这些信息通常是基于 IP 地址进行的。如果无法获取到真实的客户端 IP 地址,地理位置服务将无法正常工作。

使用 X-Forwarded-For 头传递真实 IP 地址

最常用的方法是通过 X-Forwarded-For HTTP 头传递客户端的真实 IP 地址。Nginx 可以在代理转发请求时添加这个头,以便后端服务器能够获取到真实的客户端 IP 地址。

在 Nginx 配置文件中,可以使用以下指令来设置 X-Forwarded-For 头:

http {
   
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    server {
   
        listen       80;
        server_name  localhost;

        location / {
   
            proxy_pass http://backend_server;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

在上述配置中:

  • proxy_pass:指定后端服务器的地址。
  • proxy_set_header:用于设置请求头。X-Real-IP 头传递客户端的真实 IP 地址,而 X-Forwarded-For 头包含客户端的真实 IP 地址以及代理服务器的 IP 地址。

后端服务器的配置

后端服务器需要正确解析 X-Forwarded-For 头以获取客户端的真实 IP 地址。例如,在 Apache 中,可以使用 mod_remoteip 模块:

<IfModule mod_remoteip.c>
    RemoteIPHeader X-Forwarded-For
    RemoteIPInternalProxy 10.0.0.0/8
</IfModule>

在以上配置中:

  • RemoteIPHeader:指定用于传递真实 IP 地址的请求头。
  • RemoteIPInternalProxy:指定可信任的代理服务器的 IP 地址范围。

使用 real_ip 模块

Nginx 提供了一个 ngx_http_realip_module 模块,用于处理 X-Forwarded-For 头并将其作为客户端的真实 IP 地址。

启用 real_ip 模块

首先,确保 Nginx 已经编译并启用了 ngx_http_realip_module 模块。可以通过以下命令检查:

nginx -V 2>&1 | grep -o with-http_realip_module

如果输出结果中包含 with-http_realip_module,则表示该模块已启用。

配置 real_ip 模块

在 Nginx 配置文件中,可以使用以下配置来启用 real_ip 模块:

http {
   
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.0.0.0/8;

    server {
   
        listen       80;
        server_name  localhost;

        location / {
   
            proxy_pass http://backend_server;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

在以上配置中:

  • real_ip_header:指定用于传递真实 IP 地址的请求头。
  • set_real_ip_from:指定可信任的代理服务器的 IP 地址范围。

假设有一个前端 Nginx 服务器和一个后端应用服务器,前端服务器的 IP 地址为 192.168.1.1,后端服务器的 IP 地址为 192.168.1.2

在前端 Nginx 服务器上,可以使用以下配置:

server {
   
    listen 80;
    server_name frontend.example.com;

    location / {
   
        proxy_pass http://192.168.1.2;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

在后端应用服务器上,可以使用以下配置:

server {
   
    listen 80;
    server_name backend.example.com;

    real_ip_header X-Forwarded-For;
    set_real_ip_from 192.168.1.1;

    location / {
   
        root /var/www/html;
        index index.html index.htm;
    }
}

配置完成后,可以通过以下步骤验证真实 IP 地址的传递是否正确:

  1. 发送请求:从客户端发送一个 HTTP 请求到前端 Nginx 服务器。
  2. 检查日志:在后端应用服务器的日志中检查请求的 IP 地址,确保显示的是客户端的真实 IP 地址而不是前端 Nginx 服务器的 IP 地址。

例如,可以使用 curl 命令发送请求:

curl -I http://frontend.example.com

然后,在后端应用服务器的日志中检查请求的 IP 地址:

tail -f /var/log/nginx/access.log

日志中应显示客户端的真实 IP 地址,而不是前端 Nginx 服务器的 IP 地址。

常见问题和解决方法

问题一:后端服务器仍然显示代理服务器的 IP 地址

解决方法:确保在后端服务器的 Nginx 配置中正确设置了 real_ip_headerset_real_ip_from 指令,并且前端服务器已正确设置 X-Forwarded-For 头。

问题二:多个代理服务器导致 X-Forwarded-For 头中包含多个 IP 地址

解决方法:在后端服务器的配置中,确保 real_ip_recursive 指令已启用,以处理包含多个 IP 地址的 X-Forwarded-For 头。

http {
   
    real_ip_header X-Forwarded-For;
    set_real_ip_from 192.168.1.1;
    real_ip_recursive on;
}

总结

在使用 Nginx 作为反向代理服务器时,传递客户端的真实 IP 地址对于日志记录、访问控制和地理位置追踪等应用至关重要。通过使用 X-Forwarded-For 头和 ngx_http_realip_module 模块,可以有效地实现这一需求。正确配置后端服务器以解析这些头信息,将确保能够正确获取到客户端的真实 IP 地址,从而提升系统的可靠性和准确性。

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
目录
相关文章
|
2月前
|
监控 应用服务中间件 测试技术
确保正则表达式在 Nginx 代理中的准确性和稳定性
【10月更文挑战第19天】总之,正则表达式在 Nginx 代理中具有重要作用,但要确保其准确性和稳定性需要付出一定的努力和关注。通过以上方法的综合运用,我们可以提高正则表达式配置的可靠性,为用户提供更好的服务体验。
|
4月前
|
负载均衡 网络协议 Unix
Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇
Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇
80 1
|
1月前
|
负载均衡 前端开发 JavaScript
Nginx 代理多服务
以上是 Nginx 代理多服务的几种常见方式,在实际应用中,可以根据具体的业务需求和系统架构选择合适的代理方式,并结合其他 Nginx 的功能和配置来优化和完善系统的性能和功能。
|
2月前
|
负载均衡 应用服务中间件 Linux
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
这篇博客文章详细介绍了Nginx的下载、安装、配置以及使用,包括正向代理、反向代理、负载均衡、动静分离等高级功能,并通过具体实例讲解了如何进行配置。
179 4
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
|
2月前
|
应用服务中间件 API nginx
使用正则表达式实现 Nginx 代理
【10月更文挑战第19天】在不断发展的互联网技术中,掌握正则表达式在 Nginx 代理中的应用是非常重要的。不断探索和实践,将有助于我们在实际工作中更好地运用这一技术,提升项目的质量和效率。
|
2月前
|
缓存 负载均衡 应用服务中间件
Nginx 实现一个端口代理多个前后端服务
【10月更文挑战第19天】Nginx 的强大功能不仅限于此,它还可以与其他技术和工具相结合,为我们的应用提供更强大的支持和保障。在不断发展的互联网时代,掌握 Nginx 的使用技巧将为我们的工作和生活带来更多的便利和效益。
|
2月前
|
存储 缓存 监控
|
2月前
|
存储 缓存 负载均衡
Nginx代理缓存机制
【10月更文挑战第2天】
101 4
|
2月前
|
应用服务中间件 网络安全 nginx
nginx如何代理ssl
nginx如何代理ssl
|
3月前
|
Ubuntu 应用服务中间件 数据库
Nginx配置:阻止非国内IP地址访问的设置方法
此外,出于用户隐私和法律合规性的考虑,应慎重考虑阻止特定国家或地区IP地址的决策。在某些情况下,这可能被视为歧视性或违反当地法律。
207 2