如何使用集群内反向代理自动确定在 Kubernetes 中运行的 ASP.NET Core 应用程序的已知网络?

Joh*_*ica 3 c# kubernetes asp.net-core

我跑在Kubernetes背后的真实发送反向代理的ASP.NET核心API X-Forwarded-ForX-Forwarded-ProtoX-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);
Run Code Online (Sandbox Code Playgroud)

我在 Kubernetes 中运行我的 API 和反向代理,并且 API 仅在集群中可见。因此,我不担心集群网络上有人欺骗标头。我想做的是自动检测集群的内部子网并将其添加到KnownNetworks列表中。这可能吗?如果是这样,如何?

Joh*_*ica 7

我创建了一个方法来计算每个活动接口的范围和 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

  • 192.168.1.33 带掩码 255.255.255.252 返回 192.168.1.32/30
  • 10.50.28.77 与掩码 255.252.0.0 返回 10.50.0.0/14

然后我将我的选项代码更改为如下所示:

var forwardedOptions = new ForwardedHeadersOptions()
{
    ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All
};
foreach (var network in GetNetworks(NetworkInterfaceType.Ethernet))
{
    forwardedOptions.KnownNetworks.Add(network);
}
app.UseForwardedHeaders(forwardedOptions);
Run Code Online (Sandbox Code Playgroud)