[英]How to automatically determine KnownNetworks for ASP.NET Core application running in Kubernetes with an in-cluster reverse proxy?
我在Kubernetes中的反向代理后面運行ASP.NET Core API,該代理發送X-Forwarded-For
, X-Forwarded-Proto
和X-Forwarded-Host
標頭。
我發現我需要使用UseForwardedHeaders()
來接受來自代理的值,因此我編寫了以下代碼:
var forwardedOptions = new ForwardedHeadersOptions()
{
ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All
};
forwardedOptions.KnownNetworks.Add(new IPNetwork(IPAddress.Parse(configuration["network:address"]), int.Parse(configuration["network:cidrMask"])));
app.UseForwardedHeaders(forwardedOptions);
我正在Kubernetes中運行我的API和反向代理,並且該API僅在集群中可見。 因此,我不必擔心群集網絡上有人欺騙標頭。 我想做的是自動檢測群集的內部子網並將其添加到KnownNetworks
列表中。 這可能嗎? 如果是這樣,怎么辦?
我創建了一種方法,用於為每個活動接口計算范圍的開始和CIDR子網掩碼:
private static IEnumerable<IPNetwork> GetNetworks(NetworkInterfaceType type)
{
foreach (var item in NetworkInterface.GetAllNetworkInterfaces()
.Where(n => n.NetworkInterfaceType == type && n.OperationalStatus == OperationalStatus.Up) // get all operational networks of a given type
.Select(n => n.GetIPProperties()) // get the IPs
.Where(n => n.GatewayAddresses.Any())) // where the IPs have a gateway defined
{
var ipInfo = item.UnicastAddresses.FirstOrDefault(i => i.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); // get the first cluster-facing IP address
if (ipInfo == null) { continue; }
// convert the mask to bits
var maskBytes = ipInfo.IPv4Mask.GetAddressBytes();
if (!BitConverter.IsLittleEndian)
{
Array.Reverse(maskBytes);
}
var maskBits = new BitArray(maskBytes);
// count the number of "true" bits to get the CIDR mask
var cidrMask = maskBits.Cast<bool>().Count(b => b);
// convert my application's ip address to bits
var ipBytes = ipInfo.Address.GetAddressBytes();
if (!BitConverter.IsLittleEndian)
{
Array.Reverse(maskBytes);
}
var ipBits = new BitArray(ipBytes);
// and the bits with the mask to get the start of the range
var maskedBits = ipBits.And(maskBits);
// Convert the masked IP back into an IP address
var maskedIpBytes = new byte[4];
maskedBits.CopyTo(maskedIpBytes, 0);
if (!BitConverter.IsLittleEndian)
{
Array.Reverse(maskedIpBytes);
}
var rangeStartIp = new IPAddress(maskedIpBytes);
// return the start IP and CIDR mask
yield return new IPNetwork(rangeStartIp, cidrMask);
}
}
例子:
然后,我將選項代碼更改為如下所示:
var forwardedOptions = new ForwardedHeadersOptions()
{
ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All
};
foreach (var network in GetNetworks(NetworkInterfaceType.Ethernet))
{
forwardedOptions.KnownNetworks.Add(network);
}
app.UseForwardedHeaders(forwardedOptions);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.