配置 Forwarded Headers Middleware
来自微软的说明:Configure ASP.NET Core to work with proxy servers and load balancers | Microsoft Learn。
通过该中间件,会更新:
-
HttpContext.Connection.RemoteIpAddress: 使用
X-Forwarded-For
请求头的值. 其它的配置会影响到中间件如何设置RemoteIpAddress
的值.消费掉的值会从
X-Forwarded-For
中删除, 原始的值被设置到X-Original-For
. 相同的处理模式也应用于其它请求头Host
和Proto
. -
HttpContext.Request.Scheme: 使用来自
X-Forwarded-Proto
请求头的值设置. -
HttpContext.Request.Host: 使用来自
X-Forwarded-Host
请求头的值.
该中间件不仅处理 Forwarded 请求头,还提供了额外的安全措施。
KnownNetworks 和 KnownProxies 表示有效的中间件地址,如果配置了 KnownNetworks 或者 KnownProxies,则该中间件仅仅处理列出在 KnownNetworks 和 KnownProxies 中的地址,而会忽略掉其它的地址。
ForwardLimit 则限制了处理的地址数量,这意味着不是所有列出在请求头中的地址都一定被处理。
默认配置
- 在应用和客户端之间仅一个代理存在
- 只有 loopback 地址作为已知代理地址和已知的网络范围
- forwarded 请求头的名称为 X-Forwarded-For 和 X-Forwarded-Proto
- 默认的 Forwardedheaders 的值为 ForwardedHeaders.None,意味着不处理,必须通过配置它来启用中间件。
See: Configure ASP.NET Core to work with proxy servers and load balancers | Microsoft Learn
配置示例
下面的示例中,最多检查 2 个元素,支持的代理服务器是 127.0.0.1 和 127.0.10.1,Forwarded For 的请求头名称使用的是自定义的 X-Forwarded-For-My-Custom-Header-Name。
builder.Services.Configure<ForwardedHeadersOptions>(options => {
options.ForwardLimit = 2;
options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
常用配置说明
KnownNetworks
用来表示有效的网段集合。
它是一个集合类型,其中的元素类型为 IPNetwork.
public System.Collections.Generic.IList
<Microsoft.AspNetCore.HttpOverrides.IPNetwork> KnownNetworks { get; }yb
这个 IPNetwork 表示一个网段。
这是它的构造函数,可以看到它通过一个前缀的长度来指定网段。
public IPNetwork(IPAddress prefix, int prefixLength)
:this(prefix, prefixLength, true)
{
}
例如,默认的配置代码如下:
public IList<IPNetwork> KnownNetworks { get; }
= new List<IPNetwork>() {
new IPNetwork(IPAddress.Loopback, 8)
};
表示只要是 127.x.x.x 的网段,8 指的是 8 位,即第一个字节。也就是 127 所在的部分。
KnownProxies
表示有效的代理集合,其中的元素类型为 IpAddress,即单个的网络地址。
例如,默认的配置代码如下:
public IList<IPAddress> KnownProxies { get; }
= new List<IPAddress>() {
IPAddress.IPv6Loopback
};
ForwardLimit
限制中间件处理的在 X-Forwarded- 中的地址数量,默认为 1 个。
默认的配置如下:
public int? ForwardLimit { get; set; } = 1;
通过设置为 null 可以禁用该限制,但是这必须在配置了 KnownProxies 和 KnownNetworks 之后。配置为非 null 的值是一种安全预防措施 (但不是保证),用来防止配置错误的代理,和来自网络上游的恶意请求。
处理的顺序是从右向左的相反顺序进行的,如果使用默认值 1,则仅仅处理请求头中最右边的值。