【问题标题】:IP Security in Asp.Net CoreAsp.Net Core 中的 IP 安全性
【发布时间】:2016-11-04 16:08:00
【问题描述】:

我正在尝试通过 IP 地址限制站点。在以前的 MVC 版本中,我会在 web.config 中添加如下内容:

<security>
  <ipSecurity allowUnlisted="false" denyAction="NotFound">
    <add allowed="true" ipAddress="XX.XX.XX.XX" subnetMask="255.255.255.0"/>
  </ipSecurity>
</security>

但是将其添加到 AspNetCore 项目会导致应用程序在启动时失败并出现错误

无法启动进程 Web 服务器请求失败,状态码为 500,内部服务器错误

显然我破坏了配置,因为它不再在这里处理。该错误会生成一个 HttpFailure 日志,如下所示:

现在最好的处理方法是什么,内置的或其他的

【问题讨论】:

  • 您能弄清楚内部服务器错误是什么并将其添加到您的帖子中吗?
  • ipSecurity 是 IIS 特定的,而 ASP.NET Core 是关于通过 Kestrel 服务器跨平台服务 Web 请求的。可能有更好的方法,但通过中间件管道可以检索stackoverflow.com/questions/28664686/… 中描述的 IP 地址并返回 NotFound 结果。
  • @rboe 啊,是的,这是有道理的。那么您认为这是手动添加它的情况吗?在想可能是这种情况
  • @mason 已编辑,谢谢
  • @rboe:在 ASP.NET Core 中检索 IP 并不是那么容易/一致,因为您期望的默认变量会为您提供反向代理的 IP,而不是用户IP 并取决于它有多少跃点,这并不容易确定。在面向 Internet 的服务器(Linux 上的 IIS 或 nginx)上执行此操作更有意义

标签: c# asp.net-core asp.net-core-mvc


【解决方案1】:

Damian Bod 制作了一个blog post 演示如何实施中间件来处理 IP 白名单。

他给出了全局中间件或动作过滤器的例子。

无论哪种方式,您都需要将允许的 IP 地址添加到您的 appsettings.json,并对照它们检查客户端 IP 地址。

客户端 IP 地址可通过HttpContext 获得(例如context.Connection.RemoteIpAddress)。

如果你想将IP地址范围列入白名单,那么你可以使用Nuget包IPAddressRange,它支持“192.168.0.0/24”和“192.168.0.0/255.255.255.0”等多种格式,包括CIDR表达式和 IPv6。

这是一个如何在过滤器中执行此操作的示例:

appsettings.json

{
  "IPAddressWhitelistConfiguration": {
    "AuthorizedIPAddresses": [
      "::1", // IPv6 localhost
      "127.0.0.1", // IPv4 localhost
      "192.168.0.0/16", // Local network
      "10.0.0.0/16", // Local network
    ]
  }
}

IPWhiteListConfiguration.cs

namespace My.Web.Configuration
{
    using System.Collections.Generic;

    public class IPWhitelistConfiguration : IIPWhitelistConfiguration
    {
        public IEnumerable<string> AuthorizedIPAddresses { get; set; }
    }
}

IIPWhiteListConfiguration.cs

namespace My.Web.Configuration
{
    using System.Collections.Generic;

    public interface IIPWhitelistConfiguration
    {
        IEnumerable<string> AuthorizedIPAddresses { get; }
    }
}

Startup.cs

public class Startup
{
    // ...
    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        services.Configure<IPWhitelistConfiguration>(
           this.Configuration.GetSection("IPAddressWhitelistConfiguration"));
        services.AddSingleton<IIPWhitelistConfiguration>(
            resolver => resolver.GetRequiredService<IOptions<IPWhitelistConfiguration>>().Value);
        // ...
    }
 }

ClientIPAddressFilterAttribute.cs

namespace My.Web.Filters
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using NetTools;
    using My.Web.Configuration;

    public class ClientIPAddressFilterAttribute : ActionFilterAttribute
    {
        private readonly IEnumerable<IPAddressRange> authorizedRanges;

        public ClientIPAddressFilterAttribute(IIPWhitelistConfiguration configuration)
        {
            this.authorizedRanges = configuration.AuthorizedIPAddresses
                .Select(item => IPAddressRange.Parse(item));
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var clientIPAddress = context.HttpContext.Connection.RemoteIpAddress;
            if (!this.authorizedRanges.Any(range => range.Contains(clientIPAddress)))
            {
                context.Result = new UnauthorizedResult();
            }
        }
    }

【讨论】:

  • 很好的答案,但我认为博客文章链接是错误的。
  • @CalC 谢谢。现已修复!
  • 我想知道 IPWhiteListConfiguration.cs 中使用的接口 IIPWhitelistConfiguration 是什么样子的。它是否继承了 IConfiguration?
  • @Verzada 只是一个接口,只暴露了AuthorizedIPAddresses 属性的getter。这对示例并不重要,只是为了将客户端代码与IPWhitelistConfiguration 的实现分离。为了完整起见,我已将其添加到答案中,并展示如何解决它。
  • @Ergwun 我刚刚进入 .NET Core,因此当我查看如何在该特定框架中进行依赖注入的示例时,我很欣赏任何可以使事情变得清晰的东西。所以感谢您花时间添加信息:)
【解决方案2】:

我需要类似的东西,除了“安全列出”单个 IP 地址对我来说不够好,因为我必须通过 CIDR 表示法(对于 Cloudflare)启用整个 IP 地址范围。我昨天blogged about it,但总之你可以安装Firewall NuGet package,然后像这样配置IP过滤器设置:

namespace BasicApp
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            var allowedIPs =
                new List<IPAddress>
                    {
                        IPAddress.Parse("10.20.30.40"),
                        IPAddress.Parse("1.2.3.4"),
                        IPAddress.Parse("5.6.7.8")
                    };

            var allowedCIDRs =
                new List<CIDRNotation>
                    {
                        CIDRNotation.Parse("110.40.88.12/28"),
                        CIDRNotation.Parse("88.77.99.11/8")
                    };

            app.UseFirewall(
                FirewallRulesEngine
                    .DenyAllAccess()
                    .ExceptFromIPAddressRanges(allowedCIDRs)
                    .ExceptFromIPAddresses(allowedIPs));

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-07-30
    • 2018-03-20
    • 1970-01-01
    • 2018-01-16
    • 2022-11-14
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多