当前位置:首页 > 技术文章 > 正文内容

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

arlanguage5个月前 (12-17)技术文章44

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_header 和 set_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 地址,从而提升系统的可靠性和准确性。

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/266.html

分享给朋友:

“Nginx 如何代理转发传递真实 ip 地址?” 的相关文章

彻底搞懂 Nginx 的五大应用场景 彻底搞懂 nginx 的五大应用场景是什么

— 1 —HPPTNginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。1、首先在文档根目录Docroot(/usr/local/var/www)下创建html目录,然后在html中放一个test...

logstash+ES+kibana搭建日志收集分析系统

日志监控和分析在保障业务稳定运行时,起到了很重要的作用,不过一般情况下日志都分散在各个生产服务器,且开发人员无法登陆生产服务器,这时候就需要一个集中式的日志收集装置,对日志中的关键字进行监控,触发异常时进行报警,并且开发人员能够查看相关日志。logstash+elasticsearch+kibana...

php培训都学什么?有哪些课程?

PHP入门虽然比较容易简单,但是对于零基础学员来讲,想要学到精髓,并不是一件容易的事情,越到后面学起来越累,因此,最快最便捷的方法就是参加培训,不仅可以快速掌握入门,还能够学到精髓之处,那么PHP培训都有哪些课程?下面我们以六星教育的php培训课程为例来为大家讲解:第一阶段:动态网站开发的三个方面1...

容器中Nginx高并发参数调优实战 nginx并发量过高怎么处理

在容器化的微服务架构中,Nginx作为反向代理和负载均衡器,常常需要承担高并发访问的压力。当并发连接数超过Nginx可处理的上限时,就会出现新连接被丢弃的情况。本文将详细介绍如何发现和定位这个问题,并通过调整内核参数和Nginx配置来解决。一、问题现象某Web服务在高并发场景下,偶尔会出现部分请求无...

深入Docker容器之日志篇

操作系统流重定向在linux系统中,运行一个命令,通常会是以下的方式:在linux 和 Unix系统中,在运行程序时,通常会有三种io流: stdin, stdout,stderr 。 stdin 是从外部设备或是键盘获取输入,而 stdout 是标准输出,stderr 是标准错误输出。而不管是标准...

SeaTunnel 实践 | SeaTunnel 帮你快速玩转 Spark 数据处理

Databricks 开源的 Apache Spark 对于分布式数据处理来说是一个伟大的进步。我们在使用 Spark 时发现了很多可圈可点之处,我们在此与大家分享一下我们在简化 Spark 使用和编程以及加快 Spark 在生产环境落地上做的一些努力。01一个 Spark Streaming 读取...