背景:某个项目在部署的时候采取的是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。
参考资料:
- Microsoft Docs: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?tabs=aspnetcore2x
- Github aspnet/BasicMiddleware issues#190: https://github.com/aspnet/BasicMiddleware/issues/190
Copyright © 2018, Mjollnir. 除非另有声明,本网站采用知识共享“署名-非商业性使用-相同方式共享 3.0 中国大陆”许可协议授权。
您好。我有一个网站,能够通过主机的IPv4和IPv6地址访问到容器里的应用。如果通过IPv4访问,X-Forwarded-For就能正确显示用户的IP地址,但如果通过IPv6地址访问的话,X-Forwarded-For的值是172.19.0.1这样的值而不是用户的真实地址,这个问题怎么解决呢?
我的容器是直接port bind到主机的端口上的,它就能用IPv6访问了。
你使用的是什么反代服务器?