首页 > Web开发 > 详细

K8s中ASP.NET Core应用获取不到客户端真实IP地址解决办法

时间:2020-06-16 11:35:31      阅读:113      评论:0      收藏:0      [点我收藏+]

原文 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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!