You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.net网站中封锁单个IP地址或国家IP段及实现方法

ASP.NET 封锁单个IP/国家IP段实现方案

下面分原生配置和自定义代码两种方案,适配不同版本的ASP.NET运行环境:

方案1:IIS原生配置(适合ASP.NET 4.x/部署在IIS上的.NET Core项目,无需修改代码)

仅适合简单的单个IP/IP段封锁,依赖IIS功能:

  • 先开启IIS的IP和域限制功能:打开服务器管理器→角色和功能→Web服务器(IIS)→安全性→勾选「IP和域限制」,安装完成后重启IIS。
  • 打开网站根目录的web.config文件,在<system.webServer>节点下添加如下配置:
<system.webServer>
  <security>
    <ipSecurity allowUnlisted="true">
      <!-- 封锁单个IPv4地址 -->
      <add ipAddress="192.168.1.100" allowed="false" />
      <!-- 封锁指定IPv4段,subnetMask为子网掩码 -->
      <add ipAddress="10.0.0.0" subnetMask="255.0.0.0" allowed="false" />
      <!-- 封锁单个IPv6地址 -->
      <add ipAddress="2001:db8::1" allowed="false" />
    </ipSecurity>
  </security>
</system.webServer>
  • 配置保存后立即生效,无需重启站点。

方案2:自定义中间件(适合ASP.NET Core/.NET 5+,跨平台,支持国家IP段批量封锁)

灵活性更高,不依赖IIS功能,适合需要批量封锁指定国家所有IP段的场景:

第一步:编写IP封锁中间件

using Microsoft.AspNetCore.Http;
using System.Net;
using System.Net.Sockets;

public class IpBlockMiddleware
{
    private readonly RequestDelegate _next;
    // 实际项目可改为从appsettings.json/数据库加载黑名单
    private static readonly HashSet<IPAddress> _blockedSingleIps = new HashSet<IPAddress>
    {
        IPAddress.Parse("192.168.1.100"),
        IPAddress.Parse("2001:db8::1")
    };
    // 国家IP段存CIDR格式,可提前导出对应国家的CIDR段批量存入
    private static readonly List<(IPAddress Network, int PrefixLength)> _blockedCidrRanges = new List<(IPAddress, int)>
    {
        // 示例:封锁10.0.0.0/8段
        (IPAddress.Parse("10.0.0.0"), 8)
    };

    public IpBlockMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var clientIp = context.Connection.RemoteIpAddress;
        // 适配IPv4映射的IPv6地址
        if (clientIp.IsIPv4MappedToIPv6)
        {
            clientIp = clientIp.MapToIPv4();
        }

        // 匹配单个IP黑名单
        if (_blockedSingleIps.Contains(clientIp))
        {
            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            await context.Response.WriteAsync("Access denied");
            return;
        }

        // 匹配CIDR IP段
        if (IsIpInCidrRanges(clientIp, _blockedCidrRanges))
        {
            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            await context.Response.WriteAsync("Access denied");
            return;
        }

        await _next(context);
    }

    private bool IsIpInCidrRanges(IPAddress ip, List<(IPAddress Network, int PrefixLength)> ranges)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            // IPv4转32位整数做掩码匹配
            var ipBytes = ip.GetAddressBytes();
            Array.Reverse(ipBytes);
            uint ipUint = BitConverter.ToUInt32(ipBytes, 0);

            foreach (var range in ranges)
            {
                if (range.Network.AddressFamily != AddressFamily.InterNetwork) continue;
                var mask = uint.MaxValue << (32 - range.PrefixLength);
                var networkBytes = range.Network.GetAddressBytes();
                Array.Reverse(networkBytes);
                uint networkUint = BitConverter.ToUInt32(networkBytes, 0);
                if ((ipUint & mask) == (networkUint & mask)) return true;
            }
        }
        // 需支持IPv6段匹配可自行扩展对应逻辑
        return false;
    }
}

第二步:注册中间件

在Program.cs(.NET 6+)或Startup.cs中,将中间件注册到请求管道的最前端,确保所有请求进来优先做IP校验:

// 必须放在UseRouting、UseAuthorization等其他中间件之前
app.UseMiddleware<IpBlockMiddleware>();

注意事项

  • 如果网站使用了CDN、反向代理,需要先配置转发头获取真实客户端IP:ASP.NET Core中需先注册UseForwardedHeaders中间件,并且配置信任的代理服务器IP,否则会误封CDN节点IP。
  • 国家IP段可以提前导出对应国家的所有CIDR格式段,批量存入配置或数据库,项目启动时加载到内存即可,无需每次请求查库。

内容的提问来源于stack exchange,提问作者DHY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:24:01