繁体   English   中英

反向代理后面的 ASP.Net Core 不使用 `X-Forwareded-For`

[英]`X-Forwareded-For` is not used by ASP.Net Core behind reverse proxy

我试图在我的ASP.Net Core 2.1 MVC 控制器(在 .Net Docker 容器中运行)中获取请求的远程 IP 地址(即发送请求的客户端的 IP)。 考虑到我的 ASP.Net Core 应用程序位于 NGINX 反向代理之后(在 NGINX Docker 容器中运行)。

众所周知,当反向代理将请求重定向到我的 .Net Core 应用程序时,它会更改我请求的源 IP(TCP/IP 层),因此,我将 NGINX 配置为将带有原始 IP 的X-Forwareded-For添加到请求。 从 NGINX 容器重定向到 .Net 容器的请求在标头中有X-Forwareded-For

在此处输入图片说明

当然,我配置了 .Net Core 以了解这一点:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
    // Rewrite the header when being redirected (this is required because we are behind reverse proxy)
    var forwardedHeadersOptions = new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
        KnownProxies = { IPAddress.Parse("172.20.10.2"), IPAddress.Parse("172.20.10.3"), IPAddress.Parse("172.20.10.4") },
    };

    forwardedHeadersOptions.KnownNetworks.Add(
        new IPNetwork(IPAddress.Parse("172.0.0.0"), 8));
    forwardedHeadersOptions.KnownNetworks.Add(
        new IPNetwork(IPAddress.Parse("127.0.0.1"), 8));

    app.UseForwardedHeaders(forwardedHeadersOptions);
    ...

但是, HTTPContext.Connection.RemoteIPAddress仍然返回 172.20.10.3(NGINX 容器 IP,不是真正的远程 IP):

logger.LogDebug("Remote IP Address: " + Request.HttpContext.Connection.RemoteIpAddress.ToString());

远程 IP 地址:172.20.10.3

我在 .Net Core 中检查了我的标题,它有X-Forwareded-For和正确的原始远程 IP 地址:

logger.LogDebug("X-Forwareded-For Header Feature: " + HttpContext.Request.Headers["X-Forwarded-For"]);

X-Forwarded-For 标题功能:85.XX.4.121

有人知道我缺少什么吗? 为什么 RemoteIPAddress 仍然返回 NGINX docker 容器的 IP 而不是真正的远程 IP 地址?

更新

我的程序Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://*:5000")
            .UseStartup<Startup>()
            .Build();
}

我还尝试通过如下配置其服务来配置ForwarededHeadersOptions

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    //options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.0.0.0"), 8));
    options.RequireHeaderSymmetry = false;
    options.ForwardLimit = null;
    options.KnownProxies.Add(IPAddress.Parse("172.20.10.3"));
    //options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("127.0.0.1"), 8));
});

没有成功...

更新 2

好的,我想我走对了, RemoteIPAddress返回的 IP 地址是 ::ffff:172.20.10.20,而不是 172.20.10.20! 我不知道他们是不同的。 官方文档帮助我发现了这一点。

我从RemoteIPAddress获得的 IP 是表示为 IPv6 的 IPv4(是 ::ffff:172.20.10.20,而不是 172.20.10.20!)。 我只使用了 IP 的 IPv4 部分,因此在我的情况下, KnownProxies是错误的。 我也应该在 v6 表示部分输入完整的 IPv4 地址。

官方文档显示:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1

根据评论的要求更新:

所以在我的例子中,代码应该是这样的:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.RequireHeaderSymmetry = false;
    options.ForwardLimit = null;
    options.KnownProxies.Add(IPAddress.Parse("::ffff:172.20.10.20")); // <<-- Notice the full format of the IP address.
});

根据官方文档,如果您使用Apache 或 Nginx 集成,则应将以下代码添加到Startup.ConfigureServices方法中。

// using Microsoft.AspNetCore.HttpOverrides;

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
            ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });

然后最重要的是,在Configure方法中使用

app.UseForwardedHeaders();

进一步假设在 nginx conf 文件中,在一个位置内,使用

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-Host $server_name;

现在X-Forwarded-For的第一个条目将是真实的客户端 IP。

重要提示:如果您想保护应用程序并且不允许攻击者注入 X-Forwarded-For,请按照此Nginx 处理无效标头

请参阅转发 Linux 和非 IIS 反向代理的方案配置 Nginx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM