Asp.net Core 经过nginx代理后获取不到真实ip和scheme的问题
背景
我最近在一个Asp.net core Web 程序在经过nginx代理后 ,总是获取不到用户真实i和scheme(HttpContext.Request.Scheme),挠头;
我们一般从请求头获取用户ip:(我就用的这种
context.Request.Headers["X-Forwarded-For"]
当然这个时候要去你nginx要配置了 X-Forwarded-For
我们也可以用Forwarded Headers Middleware方式:
Request.HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString();
当然按文档 ,在经过nginx代理后,我们是这样获取用户真实ip和scheme的:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//...
}
我虽然用的第一种从请求头中获取,但是Forwarded Headers Middleware 以上的这两步配置我都配置了。
后面看到dudu的,配置改为如下:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
//新增如下两行
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
//可以自定义这个头防止伪造X-Forwarded-For攻击,不过我觉得在第一层nginx那里配置 :proxy_set_header X-Forwarded-For $remote_addr; 比较方便,具体不展开了大家自己搜下
//options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
安装dudu说法:
如果负载均衡不是在本机通过 Loopback 地址转发请求的,一定要加上 options.KnownNetworks.Clear 与 options.KnownProxies.Clear 的
下面我获取下加了 options.KnownNetworks.Clear(); options.KnownProxies.Clear();与不加,获取的请求头的区别大家有兴趣可以复制下来对比下
获取请求头的代码
访问链接:https://test.mydomain.com/GetRequestHeader
[HttpGet]
public IActionResult GetRequestHeader()
{
var Scheme = _httpContextAccessor.HttpContext.Request.Scheme;
var RemoteIpAddress = _httpContextAccessor.HttpContext.Connection?.RemoteIpAddress;
var RemotePort = _httpContextAccessor.HttpContext.Connection?.RemotePort;
var Host = _httpContextAccessor.HttpContext.Request?.Host;
var realip = _httpContextAccessor.HttpContext.RealIp();
var header = _httpContextAccessor.HttpContext.Request.Headers.ToList();
return Success("success", new { Scheme, RemoteIpAddress = RemoteIpAddress.ToString(), RemotePort = RemotePort.Value, Host = Host.Value, realip, header });
}
加Clear()
{
"status": 1,
"msg": "success",
"data": {
"scheme": "https",
"remoteIpAddress": "172.16.1.174",
"remotePort": 0,
"host": {
"value": "test.mydomain.com",
"hasValue": true,
"host": "test.mydomain.com",
"port": null
},
"realip": "172.16.1.174",
"header": [
{
"Key": "Connection",
"Value": [
"keep-alive"
]
},
{
"Key": "Accept",
"Value": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
]
},
{
"Key": "Accept-Encoding",
"Value": [
"gzip, deflate, br"
]
},
{
"Key": "Accept-Language",
"Value": [
"zh-CN,zh;q=0.9"
]
},
{
"Key": "Host",
"Value": [
"test.mydomain.com"
]
},
{
"Key": "User-Agent",
"Value": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
]
},
{
"Key": "Upgrade-Insecure-Requests",
"Value": [
"1"
]
},
{
"Key": "X-Original-Proto",
"Value": [
"http"
]
},
{
"Key": "X-Forwarded-Host",
"Value": [
"test.mydomain.com"
]
},
{
"Key": "X-Forwarded-Port",
"Value": [
"443"
]
},
{
"Key": "X-Forwarded-Path",
"Value": [
"/rest/api/login/test"
]
},
{
"Key": "X-Real-IP",
"Value": [
"172.16.1.174"
]
},
{
"Key": "sec-ch-ua",
"Value": [
"\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"92\""
]
},
{
"Key": "sec-ch-ua-mobile",
"Value": [
"?0"
]
},
{
"Key": "sec-fetch-site",
"Value": [
"none"
]
},
{
"Key": "sec-fetch-mode",
"Value": [
"navigate"
]
},
{
"Key": "sec-fetch-user",
"Value": [
"?1"
]
},
{
"Key": "sec-fetch-dest",
"Value": [
"document"
]
},
{
"Key": "X-Original-For",
"Value": [
"[::ffff:172.16.3.119]:53404"
]
}
]
}
}
不加Clear()
{
"status": 1,
"msg": "success",
"data": {
"scheme": "https",
"remoteIpAddress": "::ffff:127.0.0.1",
"remotePort": 52804,
"host": {
"value": "test.mydomain.com",
"hasValue": true,
"host": "test.mydomain.com",
"port": null
},
"realip": "::ffff:127.0.0.1",
"header": [
{
"Key": "Cache-Control",
"Value": [
"max-age=0"
]
},
{
"Key": "Connection",
"Value": [
"close"
]
},
{
"Key": "Accept",
"Value": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
]
},
{
"Key": "Accept-Encoding",
"Value": [
"gzip, deflate, br"
]
},
{
"Key": "Accept-Language",
"Value": [
"zh-CN,zh;q=0.9"
]
},
{
"Key": "Cookie",
"Value": [
"_ga=GA1.2.1892895098.1524056233; _39wt_pk_cookie=d87f6237c18985a98db6aa79c0cdabb2-1015182643; _39wt_last_session_cookie=2b9b9210771666befc14a73de4951694-1544111121; _39wt_last_visit_time_cookie=1540012072376; __utma=202198739.1892895098.1524056233.1554648728.1563892800.3; __utrace=d145876b71944eb628f1c8b54da95a0e; money=0; picurl=https%253a%252f%252fpimg.39.net%252fupload%252fmy%252fc200844%252f20190313%252forg%252f7640674.jpg; pid=34820967; username=P52460069; DomainName=P52460069; nickname=%25e5%2593%2588%2A%2A%2A%2A%2A%2A; verify=3105499624; Hm_lvt_9840601cb51320c55bca4fa0f4949efe=1626704188; Hm_lvt_ab2e5965345c61109c5e97c34de8026a=1626704188"
]
},
{
"Key": "Host",
"Value": [
"test.mydomain.com"
]
},
{
"Key": "User-Agent",
"Value": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
]
},
{
"Key": "Upgrade-Insecure-Requests",
"Value": [
"1"
]
},
{
"Key": "sec-ch-ua",
"Value": [
"\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\""
]
},
{
"Key": "sec-ch-ua-mobile",
"Value": [
"?0"
]
},
{
"Key": "Sec-Fetch-Site",
"Value": [
"cross-site"
]
},
{
"Key": "Sec-Fetch-Mode",
"Value": [
"navigate"
]
},
{
"Key": "Sec-Fetch-User",
"Value": [
"?1"
]
},
{
"Key": "Sec-Fetch-Dest",
"Value": [
"document"
]
},
{
"Key": "X-Original-For",
"Value": [
"[::ffff:127.0.0.1]:52804"
]
},
{
"Key": "X-Original-Proto",
"Value": [
"http"
]
}
]
}
}
PS:注意本文请求都是经过nginx的情况下,且只有一层nginx;
引用
https://www.cnblogs.com/dudu/p/11088645.html
https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1
Asp.net Core 经过nginx代理后获取不到真实ip和scheme的问题的更多相关文章
- 深入nginx之《获取用户的真实IP》
获取用户的真实IP Nginx会将客户端的IP信息存放在$remote_addr变量里,但这并不意味着它就是客户端的IP,生产环境往往会充满各种代理,让IP的来龙去脉变得扑朔迷离. 目前互联网公司基本 ...
- ubuntu下发布asp.net core并用nginx代理之旅
asp.net core 1.0.1发布已有些日子了,怀着好奇的心情体验了把ubuntu下的asp.net core 系统运行环境:ubuntu 16.0.4 for developer 首先搭建.n ...
- nginx代理后,获取request的ip
应用程序部署上线,一般都会用nginx之类的来进行反向代理,而不是直接访问tomcat之类的容器. 这时候如果用平时的获取ip的代码,就只会获取到nginx所在服务器的ip, 就失去了本身的意义. 今 ...
- go 通过nginx代理后获取用户ip
go 如果使用自己的服务器,可以直接使用 net/http 来获取 func ip(w http.ResponseWriter, r *http.Request) { fmt.Println(r.Re ...
- Nginx 反向代理时获取用户的真实 IP
在平时我们开发后端程序的过程中,应该多多少少都会碰到记录客户端 IP 的场景,例如我之前写过的 APP 用户的一个审计功能,就需要获取用户的 IP 地址:还有广告系统里面,也是需要获取用户的 IP 地 ...
- ubuntu下发布asp.net core并用nginx代理之旅(续)
前面实现了ubuntu下的发布,然而实际项目一般为visual studio中发布文件系统,然后上传至生产环境中,(部分参考:上传文件到linux - ubuntu) 这节就发布到生产环境中的: 1. ...
- 获取用户的真实ip
常见的坑有两个: 一.获取的是内网的ip地址.在nginx作为反向代理层的架构中,转发请求到php,java等应用容器上.结果php获取的是nginx代理服务器的ip,表现为一个内网的地址.php获取 ...
- go 语言的库文件放在哪里?如何通过nginx代理后还能正确获取远程地址
/usr/local/Cellar/go/1.5.1/libexec/src/ 他的RemoteAddr 是从哪里获取? func (c *conn) RemoteAddr() Addr { if ! ...
- JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
- 使用nginx代理后以及配置https后,如何获取真实的ip地址
使用nginx代理后以及配置https后,如何获取真实的ip地址 Date:2018-8-27 14:15:51 使用nginx, apache等反向代理后,如果想获取请求的真实ip,要在nginx中 ...
随机推荐
- 本地已经有项目需要的所有依赖,但是maven总是会去网上下载
情况说明本地已经有项目需要的所有依赖,但是maven总是会去网上下载,因为网络不好等原因,一直下载失败,但是本地明明就已经有依赖了.maven的settings配置 maven已经配置成自己下载的,至 ...
- [ML] 数据预处理 - 特性归一化的目的
简而言之,归一化的目的就是使得预处理的数据被限定在一定的范围内(比如[0,1]或者[-1,1]), 从而消除奇异样本数据导致的不良影响. 是否归一化主要在于是否关心变量取值. Tool:ChatAI ...
- [FAQ] dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
通过 ls -al /usr/local/opt 可以看到 icu4c 链接的不是 libicui18n.64.dylib. 一般是 node 版本问题会出现该提示,通过观察版本大小,决定是升级还是使 ...
- 都2024年了,你还不知道git worktree么?
三年前 python 大佬吉多·范罗苏姆(为 Python 程序设计语言的最初设计者及主要架构师)才知道 git worktree ,我现在才知道,我觉得没啥丢人的. 应用场景 如果你正在 featu ...
- C#的基于.net framework的Dll模块编程(五) - 编程手把手系列文章
这次继续这个系列的介绍: 一.使用DLL类库的方法: 1) 静态类: 先引用该类库,然后声明命名空间,然后就能够进行使用了. 2) 动态类: 先引用该类库,然后声明命名空间,然后能够进行使用了. 3) ...
- 题解:CF1941G Rudolf and Subway
原题链接 简化题意 一个无向连通图中将边分成了不同颜色(保证同种颜色联通),问从 \(b\) 到 \(e\) 最短需要经过几种颜色 思路 考虑因为同种颜色联通,可直接在读入的时候开两个 vector ...
- C++ 类的继承(Inheritance)
一.继承(Inheritance) C++有一个很好的性质称为inheritance(继承),就是声明一个class(derived class),把另一个或多个class(base class)的所 ...
- IPv6 — 综合组网技术
目录 文章目录 目录 前文列表 IPv4v6 综合组网技术(转换机制) 双栈策略 隧道策略 前文列表 <IPv6 - 网际协议第 6 版> <IPv6 - 地址格式与寻址模式> ...
- 痞子衡嵌入式:从JLink V7.62开始优化了手动增加新MCU型号支持方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是JLink 7.62优化了手动增加新MCU型号支持方法. JLink 工具可以说是搞单片机开发的必备神器,JLink 包括一个硬件仿真器 ...
- C# Log4net 组件无法写日志 IsDebuged、IsInfoEnabled、IsErrorEnabled 全部为false
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)] 如果 ...