【发布时间】:2021-11-04 05:29:48
【问题描述】:
我试图在我的 ASP.Net Core 2.1 MVC 中获取请求的远程 IP 地址(即发送请求的客户端的 IP)控制器(在 .Net Docker 容器中运行)。考虑到我的 ASP.Net Core 应用程序位于 NGINX 反向代理之后(在 NGINX Docker 容器中运行)。
众所周知,当反向代理将请求重定向到我的 .Net Core 应用程序时,它会更改我的请求的源 IP(TCP/IP 层),因此,我配置 NGINX 以添加 X-Forwarded-For 与原始 IP到请求。从 NGINX 容器重定向到 .Net 容器的请求在标头中有X-Forwarded-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-Forwarded-For 和正确的原始远程 IP 地址:
logger.LogDebug("X-Forwarded-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!我不知道它们是不同的。 official documentation 帮助我发现了这一点。
【问题讨论】:
-
当它到达您的应用程序时,您是否有多个
X-Forwarded-For标头? iirc 默认情况下,默认找到时将使用 firstX-Forwarded-For。另外请确保,您可以将ForwardLimit设置为null以取消限制,但前提是设置了KnowProxies和KnownNetworks(如您的情况):docs.microsoft.com/en-us/dotnet/api/…。默认情况下,ForwardLimit设置为 1,因此它只会处理 FIRST 条目,如果您有多个代理,这可能会成为问题... -
...每个代理设置自己的标头
-
@Tseng,我已经尝试将
ForwardLimit设置为null,但不幸的是没有成功,我只有一个反向代理,我的标题中只有一个X-Forwarded-For(如图所示)。我不知道那可能是什么......完全奇怪...... -
还要注意,Programm.cs 中的
UseIISIntegration调用,在默认平台中也 注册了UseForwardedHeaders(或曾经使用过的)中间件。尝试不要在 ConfigureServices 中使用UseForwardedHeader和services.Configure<ForwardedHeadersOptions>(options => ...),这样您就不会意外拥有两个中间件,并且可以确保您的配置用于正确的中间件,因为它是通过 DI 解决的,请参阅 github.com/aspnet/IISIntegration/blob/2.1.2/src/… -
@Tseng,我也试过了,但没有成功...我对问题添加了一个小更新
标签: c# asp.net-core .net-core