记录Docker部署asp.net core应用时使用反向代理的坑。

背景:某个项目在部署的时候采取的是Docker容器+Docker Nginx反向代理的方式部署。

应用的访问流程既为:客户->Nginx反向代理->应用。

应用有一个审计功能,会记录客户端IP地址。但在使用反向代理之后,默认情况会获取到反向代理服务器的IP地址,这就需要X-Forwarded-For头信息。

微软在Microsoft.AspNetCore.HttpOverrides包中提供一个ForwardedHeadersMiddleware中间件专门处理X-Forwarded-For代理头信息,修改HttpContext.Connection.RemoteIpAddress。

在微软的文档Host ASP.NET Core on Linux with Nginx中有提到用法,但非常不详细。

app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

然后这个代码只在本机测试,或者反向服务器是本机的情况下有效。

在翻看ForwardedHeadersMiddleware中间件代码时注意到,268行CheckKnownAddress方法会检查访问的IP是否在ForwardedHeadersOptions.KnownProxies或者ForwardedHeadersOptions.KnownNetworks之中。

ForwardedHeadersOptions代码中KnownProxies和KnownNetworks默认只有Loopback地址。

KnownProxies可以填反向代理的IP地址,KnownNetworks可以填反向代理IP网段,在访问的地址不在KnownProxies或者KnownNetworks网段中的时候X-Forwarded-For不会生效。

修改代码,添加Docker bridge网络的网段:

app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.All,
                KnownNetworks = { new IPNetwork(IPAddress.Parse("172.17.0.0"), 16) },
            });

测试,审计功能正常,能正常获取IP。

参考资料:

Copyright © 2018, Mjollnir. 除非另有声明,本网站采用知识共享“署名-非商业性使用-相同方式共享 3.0 中国大陆”许可协议授权。

2 条评论

  1. 您好。我有一个网站,能够通过主机的IPv4和IPv6地址访问到容器里的应用。如果通过IPv4访问,X-Forwarded-For就能正确显示用户的IP地址,但如果通过IPv6地址访问的话,X-Forwarded-For的值是172.19.0.1这样的值而不是用户的真实地址,这个问题怎么解决呢?
    我的容器是直接port bind到主机的端口上的,它就能用IPv6访问了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据