Nginx 不原生支持 ASN 封禁,需借助外部方案:① GeoIP2+ASN 数据库(最推荐);② 动态生成 IP 段黑名单并 include;③ 系统层 iptables/nftables 拦截。

Nginx 本身不原生支持按 ASN(自治系统号)屏蔽流量,因为它工作在 OSI 第七层(应用层),而 ASN 是网络层(BGP 路由层面)的属性,需依赖外部数据源和预处理才能实现。但你可以通过组合方案,在 Nginx 生态中间接、高效地实现 ASN 级别封禁。以下是切实可行的三种主流方式,按推荐度排序:
✅ 方式一:用 GeoIP2 + ASN 数据库(最实用、生产推荐)
这是目前最成熟、可维护性强、支持实时更新的方案。
原理:
利用ngx_http_geoip2_module模块读取 MaxMind 的GeoLite2 ASN数据库(如GeoLite2-ASN.mmdb),将$geoip2_data_asn变量注入请求上下文,再配合if或map做条件拦截。-
操作步骤:
安装
ngx_http_geoip2_module(需重新编译 Nginx 或使用预编译包,如 Ubuntu 的nginx-extras或官方动态模块);下载并部署 MaxMind 的 GeoLite2 ASN 数据库(注意:免费版需每月更新,商用需许可);
-
在
http{}块中配置:http { geoip2 /usr/share/GeoIP2/GeoLite2-ASN.mmdb { $geoip2_asn autonomous_system_number; $geoip2_asn_org autonomous_system_organization; } # 将需封禁的 ASN 号映射为 1(例如封禁 AS12345 和 AS67890) map $geoip2_asn $block_by_asn { default 0; 12345 1; 67890 1; # 可继续添加更多 ASN } server { location / { if ($block_by_asn) { return 403 "Blocked by ASN"; } # 其他配置... } } } 测试配置:
nginx -t→ 重载:nginx -s reload
⚠️ 注意:
if在location中可用,但在server根层级慎用;更安全的做法是用map+deny(见下文补充)。
-
优势:精准、可批量、支持组织名匹配(如
~* "Cloudflare")、易于自动化更新 ASN 列表。
✅ 方式二:前置 IP→ASN 映射 + 动态 blockip.conf(适合无编译权限场景)
适用于无法安装 GeoIP2 模块,但能定时生成黑名单文件的环境(如云服务器、Docker 容器)。
-
流程:
- 写脚本(Python/Shell)定期调用 ASN 查询 API(如 IPGeolocation.io、bgp.tools 或本地
whois -h whois.radb.net -- "-i origin AS12345")获取某 ASN 下所有 IPv4/IPv6 地址段; - 将结果转为 Nginx
deny规则,写入/etc/nginx/conf.d/asn-blocks.conf:deny 203.0.113.0/24; deny 2001:db8::/32;
- 在主配置中
include /etc/nginx/conf.d/asn-blocks.conf; - 用
cron每日执行脚本 +nginx -s reload
- 写脚本(Python/Shell)定期调用 ASN 查询 API(如 IPGeolocation.io、bgp.tools 或本地
-
示例 Shell 片段(简化):
# 获取 AS12345 的 CIDR 列表(需适配实际 API) curl -s "https://api.bgpview.io/asn/12345/prefixes" | jq -r '.data.ipv4_prefixes[].prefix' > /tmp/asn12345.txt sed 's/^/deny /; s/$/;/' /tmp/asn12345.txt > /etc/nginx/conf.d/asn-12345.conf nginx -s reload
✅ 优点:无需修改 Nginx 编译选项,兼容所有版本;
❌ 缺点:IP 段可能滞后(BGP 数据非实时)、文件过大时 reload 略慢、IPv6 支持需额外处理。
⚠️ 方式三:用 iptables/nftables 配合 ASN(非 Nginx 层,但更底层高效)
若目标是彻底拒绝连接(而非返回 403),且你有 root 权限,可在系统层直接丢包:
- 使用工具如
bgpstream或iprange解析 ASN → CIDR; - 生成规则导入
nftables:nft add rule inet filter input ip saddr { 203.0.113.0/24, 198.51.100.0/24 } drop - 或用
iptables(旧系统):iptables -I INPUT -s 203.0.113.0/24 -j DROP
✅ 优势:零 Nginx 开销、连接级拦截、抗扫描能力强;
❌ 不适用:容器环境(无 netfilter 权限)、CDN 后端、需返回友好提示的场景。
补充提醒
-
不要用
if ($remote_addr ~ ...)匹配 ASN:ASN 不在原始请求头里,该变量只是客户端 IP 字符串,无法解析归属; -
避免滥用
deny大量 CIDR:Nginx 的deny/allow是线性匹配,超 1000 条规则会明显拖慢性能;建议优先用geoip2 + map或系统层拦截; -
测试关键点:确认
$geoip2_asn是否为空(未命中数据库时为-或空字符串),避免误判; -
合规注意:封禁整个 ASN 可能误伤合法用户(如某 CDN 或云厂商全量 IP),建议先观察
access.log中该 ASN 的 UA、路径、频率,再决策。
不复杂但容易忽略。


















