.NET6 解决 Nginx 反向代理后获取客户端真实 IP(始终显示网关 IP)问题

假设现在你的服务器结构是这样:

  • 客户端真实公网 IP:36.112.25.88

  • Nginx 网关 IP:192.20.1.1

  • .NET 6 服务部署在本机 5000 端口

你在代码里这样获取 IP:

cs 复制代码
var ip = HttpContext.Connection.RemoteIpAddress?.ToString();

结果打印出来的永远是

192.20.1.1

而不是

36.112.25.88

一、为什么会出现这种现象?

因为在反向代理结构下:

  • .NET 接收到的请求是来自 Nginx

  • 网络层认为"请求发起者"就是 Nginx

  • 因此 RemoteIpAddress 返回的是网关 IP

换句话说:

反向代理改变了请求的直接来源。

这是一种正常行为,而不是程序错误。


二、真实 IP 在哪里?

Nginx 在转发请求时,会自动把客户端真实 IP 写入请求头:

cs 复制代码
X-Forwarded-For: 36.112.25.88
X-Real-IP: 36.112.25.88

但默认情况下:

ASP.NET Core 不会自动解析这些头。

原因是 HTTP 头可以伪造,框架出于安全考虑默认关闭信任机制。


三、正确解决方案

解决思路:

  1. Nginx 传递真实 IP

  2. .NET 6 显式启用 ForwardedHeaders


第一步:Nginx 反向代理配置

复制代码
cs 复制代码
server {
    listen 80;
    server_name api.test.com;

    location / {
        proxy_pass http://127.0.0.1:5000;

        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;
    }
}

关键配置:

cs 复制代码
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

第二步:.NET 6 启用 ForwardedHeaders

在 Program.cs 中配置:

cs 复制代码
using Microsoft.AspNetCore.HttpOverrides;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor |
        ForwardedHeaders.XForwardedProto;

    // 指定你的 Nginx 网关 IP
    options.KnownProxies.Add(IPAddress.Parse("192.20.1.1"));
});

var app = builder.Build();

// 必须放在最前面
app.UseForwardedHeaders();

app.MapControllers();

app.Run();

四、配置完成后的结果

请求仍然经过:

cs 复制代码
36.112.25.88 → 192.20.1.1 → .NET

但现在:

  • .NET 会信任来自 192.20.1.1 的转发信息

  • 自动解析 X-Forwarded-For

此时:

cs 复制代码
RemoteIpAddress

获取到的就是:

cs 复制代码
36.112.25.88

五、核心总结

在 Nginx 反向代理结构下:

  • 未配置时 → 获取到的是网关 IP

  • 正确配置后 → 获取到的是真实客户端 IP

本质原因是:

请求的直接来源变成了 Nginx,需要显式启用转发头解析机制。

相关推荐
szxinmai主板定制专家43 分钟前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
缓慢更新1 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
叼烟扛炮1 小时前
Linux 学习笔记(四十一):TCP 并发演进——从单进程到多线程服务器
linux·运维·服务器·网络·笔记·学习·tcp/ip
叼烟扛炮1 小时前
Linux 学习笔记(四十四):HTTP 协议解析与极简 Web 服务器实战
linux·服务器·学习
Decay__2 小时前
09_MySQL 闪回与时间点恢复 —— binlog 回放、mysqlbinlog、PITR 与误删恢复
运维·数据库·sql·mysql·架构
久曲健的测试窝2 小时前
2026软件测试工具选型指南:双模式如何化解UI脚本维护难题
运维·人工智能·科技·aigc
NailiConveyor3 小时前
柔性物流方案如何适配工厂升级?自动化输送流水线定制要点
大数据·运维·自动化·制造·业界资讯
Lsetea4 小时前
Certbot webroot申请SSL证书总是404:Nginx挑战目录与路径映射检查
运维·nginx·https·ssl证书·certbot
如若1234 小时前
Windows SSH + Headscale/Tailscale 组网及免密登录完整配置教程
运维·windows·ubuntu·ssh·内网穿透
开开心心就好4 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节