LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Nginx配置参数在用户访问的地址是http时,可以抓取到访问者的真实IP;但采用https时,没有抓到真实的访问者IP,要如何解决?

admin
2025年9月19日 10:8 本文热度 85

这个问题非常经典。您遇到的情况是典型的在HTTPS(SSL/TLS)终止代理场景下,后端服务器获取不到真实客户端IP的问题。

问题根源分析

您的配置在纯HTTP代理时工作正常,但切换到HTTPS时失效,根本原因通常不在于这两行配置本身,而在于整个数据流的路径发生了变化

  1. HTTP 流量
    客户端 (真实IP) -> Nginx (代理) -> 后端服务器

    • 在这种情况下,Nginx作为代理,使用proxy_set_header添加了X-Real-IPX-Forwarded-For头信息,后端服务器正确读取了这些头信息,得到了真实IP。

  2. HTTPS 流量 (SSL Termination)
    客户端 (真实IP) -> Nginx (代理 & SSL终端) -> 后端服务器 (HTTP)

    • 在这种情况下,Nginx扮演了SSL终止代理的角色。客户端与Nginx之间是加密的HTTPS连接,而Nginx与后端服务器之间通常是明文的HTTP连接。

    • 问题在于:如果Nginx与后端服务器之间的连接是新的HTTP请求,它可能没有完整地传递所有原始客户端的连接信息。虽然您配置了头部,但后端服务器接收到的连接对象(Socket)的来源IP变成了Nginx代理服务器的内网IP,而不是读取您设置的头信息。

解决方案

要确保HTTPS模式下也能正确获取真实IP,您需要执行以下两个关键步骤

步骤一:确保Nginx正确设置代理头(您已部分完成)

您的配置是正确的,但为了确保万无一失,通常还会设置HostX-Forwarded-Proto头,这对于一些后端应用(如WordPress等)正确识别原始请求的协议至关重要。

server {

    listen 443 ssl;

    server_name your_domain.com;


    # SSL证书配置

    ssl_certificate /path/to/your/fullchain.pem;

    ssl_certificate_key /path/to/your/privkey.pem;


    location / {

        # 核心配置:传递真实IP和协议信息

        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; # 这个很重要!告诉后端原始请求是https


        # 其他代理设置

        proxy_pass http://your_backend_server; # 指向您的后端服务器地址

        # 例如:proxy_pass http://localhost:8080;

        # 例如:proxy_pass http://backend_server_ip:8080;

    }

}

  • X-Forwarded-Proto $scheme:这行是关键补充。它告知后端服务器客户端最初使用的协议(http或https)。许多Web应用程序依赖这个值来生成正确的URL地址,避免陷入重定向循环或其他问题。

步骤二:配置后端服务器信任并使用这些头信息

这是最关键且最常被忽略的一步!仅仅在Nginx中发送头信息是不够的,你必须告诉后端服务器“请不要再去看直接连接的客户端的IP(这现在是Nginx的IP),而是去读取 X-Forwarded-For 或 X-Real-IP 头中的值”

后端服务器的配置取决于您运行的是什么软件:

1. 如果后端是另一个Nginx(例如用于处理PHP-FPM)

您需要修改后端的Nginx配置(通常是nginx.conf/etc/nginx/nginx.conf),在其 http 块中,设置 set_real_ip_from 和 real_ip_header 指令。

http {

    # 告诉Nginx,来自我们代理服务器(192.168.1.10)的请求是可信的

    # 将 192.168.1.10 替换为您的前端Nginx代理服务器的内网IP

    # 如果有多级代理,可以多次设置 set_real_ip_from

    set_real_ip_from 192.168.1.10;

    set_real_ip_from 127.0.0.1; # 如果代理和后端在同一台机器上


    # 告诉Nginx从哪个头信息中提取真实IP

    real_ip_header X-Forwarded-For; # 或者 X-Real-IP


    # 真实IP将被覆盖,$remote_addr 变量现在保存的是客户端的真实IP

    # 这样访问日志和应用程序获取到的就是真实IP了


    ... 其他配置 ...

}

配置完成后,重启后端的Nginx服务。

2. 如果后端是Apache

启用mod_remoteip模块。修改Apache配置文件(例如httpd.conf/etc/apache2/apache2.conf)。

LoadModule remoteip_module modules/mod_remoteip.so


# 指定可信的代理服务器IP(即前端Nginx的IP)

RemoteIPTrustedProxy 192.168.1.10

RemoteIPTrustedProxy 127.0.0.1


# 告诉Apache用 X-Forwarded-For 头中的值替换直接连接IP

RemoteIPHeader X-Forwarded-For

配置完成后,重启Apache服务。

3. 如果后端是应用程序本身(如Node.js, Python Flask/Django, Java Spring等)

应用程序代码不能直接信任remote_addr,而必须从HTTP头中读取客户端IP。

  • Node.js (Express):

const clientIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  • Python (Flask):

from flask import request

client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)

重要安全提示:在应用程序中处理这些头时,必须确保只信任来自已知可信代理(您的Nginx服务器)的请求,否则用户可能伪造X-Forwarded-For头来欺骗系统。许多Web框架有内置的机制来处理可信代理(例如Flask的 ProxyFix中间件)。

4. 如果后端是IIS的asp程序

代码如下:

'函数:验证IP格式,是返回1,否则返回0

Function CheckIpResult(paR_strIp)

CheckIpResult=0

if paR_strIp &"CS"="CS" then Exit Function

tmpIPArray=Split(paR_strIp, ".")

if Not isArray(tmpIPArray) then Exit Function

if ubound(tmpIPArray)-3<>0 then Exit Function

For tmpLoop=0 To ubound(tmpIPArray)

If tmpIPArray(tmpLoop) &"CS"="CS" Then Exit Function

If Not isNumeric(tmpIPArray(tmpLoop)) Then Exit Function

If Cint(tmpIPArray(tmpLoop))>255 Or Cint(tmpIPArray(tmpLoop))<0 Then Exit Function

Next

CheckIpResult=1

End Function


Function getIP()

strIPOrig=Request.ServerVariables("HTTP_X_FORWARDED_FOR")

If strIPOrig="" OR InStr(strIPOrig,"unknown")>0 Then

strIPAddr=Request.ServerVariables("REMOTE_ADDR")

ElseIf InStr(strIPOrig,",") > 0 Then

strIPAddr=Mid(strIPOrig,1,InStr(strIPOrig,",")-1)

ElseIf InStr(strIPOrig,";") > 0 Then

strIPAddr=Mid(strIPOrig,1,InStr(strIPOrig,";")-1)

Else

strIPAddr=strIPOrig

End If

getIP=Trim(Mid(strIPAddr,1,30))

if getIP &"CS"="::1CS" then getIP="127.0.0.1"       'localhost's ip

if getIP &"CS"<>"127.0.0.1CS" then

if CheckIpResult(getIP)=0 then

response.write ("<p align=""center""color:#FFFFFF;"">当前账号IP(“"& getIP &"”)疑似非法攻击,已被系统拦截,如需继续访问,请联系管理员。</p>")

Response.end

end if

end if

End Function

login_ip=getIP()

总结

  1. 确认Nginx代理配置:确保包含了X-Forwarded-Proto $scheme并正确proxy_pass

  2. 配置后端服务:这是解决HTTPS下问题的关键。根据您的后端类型(Nginx、Apache或应用代码),进行相应的配置,让其信任并使用前端Nginx发来的X-Forwarded-ForX-Real-IP头信息。

完成这两步后,无论是HTTP还是HTTPS流量,您的后端服务都应该能正确获取到客户端的真实IP地址了。


该文章在 2025/9/19 10:27:25 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved