原文 K8s中ASP.NET Core应用获取不到客户端真实IP地址解决办法
应用部署在 kubernets 集群中,请求是通过阿里云负载均衡+ nginx ingress 转发的,客户端 IP 是通过 X-Forwarded-For 请求头转发的,ASP.NET Core 应用是这么获取客户端 IP 的。 在 Startup.ConfigureServices 中的代码: services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.KnownNetworks.Clear(); options.KnownProxies.Clear(); }); 获取客户端 IP 地址的代码: var ip = HttpContext.Connection.RemoteIpAddress.ToString(); 之前部署在 docker swarm 集群上能正常获取,现在部署到 kubernetes 集群上却获取不到,而部署在同一个 k8s 集群上的其他 .net core 能正常获取。 排查过程: 确定排查目标:X-Forwarded-For 的值是 "116.62.124.68, 192.168.107.192",ForwardedHeadersMiddleware 是如何解析得到 192.168.107.192 的? 从 github 上签出 asp.net core 源代码 的 release/3.1 分支 运行 build.cmd 命令安装 build 环境(在 windows 系统上操作) 在 git bash 中运行 ./activate.sh 切换 .net core sdk 版本 修改 ForwardedHeadersMiddlewareTests 中的测试用例 XForwardedForDefaultSettingsChangeRemoteIpAndPort 重现问题。 [Fact] public async Task XForwardedForDefaultSettingsChangeRemoteIpAndPort() { var builder = new WebHostBuilder() .Configure(app => { var options = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor }; app.UseForwardedHeaders(options); }); var server = new TestServer(builder); var context = await server.SendAsync(c => { c.Request.Headers["X-Forwarded-For"] = "116.62.124.68, 192.168.107.192"; }); Assert.Equal("116.62.124.68", context.Connection.RemoteIpAddress.ToString()); } 在测试驱动+埋点打印的帮助下阅读 ForwardedHeadersMiddleware 的实现源码。 ForwardedHeadersMiddleware 是按从右到左的倒序读取 X-Forwarded-For 中的多个 IP 地址的。 if (checkFor && i < forwardedFor.Length) { set.IpAndPortText = forwardedFor[forwardedFor.Length - i - 1]; } 所以从 "116.62.124.68, 192.168.107.192" 得到 "192.168.107.192" 说明只读了1次。 找到控制读取次数的代码,发现 ForwardLimit 可以影响读取次数。 if (_options.ForwardLimit.HasValue && entryCount > _options.ForwardLimit) { entryCount = _options.ForwardLimit.Value; } 于是找到解决方法,将 ForwardLimit 设置为 2 即可。 services.Configure<ForwardedHeadersOptions>(options => { options.ForwardLimit = 2; //... }); 先用tcpdump port 80 -A -s 0 -c 100(输出80端口接收的100个数据包,http数据包的ASCII部分会显示到stdout)确认一下进入到容器的HTTP请求是不是携带了X-Forwarded-For。
K8s中ASP.NET Core应用获取不到客户端真实IP地址解决办法
原文:https://www.cnblogs.com/lonelyxmas/p/13139842.html