稷然如此

  • 首页
  • 文章分类
    • AI
    • Android
    • Java
    • Shell
    • Vue
    • C#
    • Python
    • 数据库
    • 组件
    • 其他
    • Game
  • 常用命令
    • Docker
    • Git
    • Linux
  • 操作系统
    • CentOS
    • Ubuntu
    • Windows
    • Kylin
  • 工具
    • IntelliJ IDEA
    • Visual Studio Code
稷然如此
不积跬步,无以至千里
  1. 首页
  2. 操作系统
  3. CentOS
  4. 正文

如何实现“仅限中国大陆访问”之 nginx + apnic 版

2025年11月28日 20点热度 0人点赞
用于:任何 Linux 系统 + 任何来源的 Nginx(官方源、宝塔、LNMP、手动编译等)。

1.获取中国大陆 IP 段

apnic 每天更新各国 IP 分配清单,地址永久免费开放:
http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest
# 下载到文件
wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest

# 直接输出到终端
curl -sSL https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest

2.创建自动转换脚本

vim /usr/local/bin/gen-cn-allow.sh
#!/bin/bash
# 从 APNIC 官方数据生成 Nginx allow 规则
# 小柳实验室  xlsys.cn
# 适用于任意 Linux 系统(CentOS/Ubuntu/Debian/Alma/Rocky 等)

OUTPUT_DIR="/etc/nginx/conf.d"
mkdir -p "$OUTPUT_DIR"

echo "正在下载 APNIC 最新数据..."
wget -qO- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | \
awk -F'|' '
  $2 == "CN" && $3 == "ipv4" {
    prefix = $4;
    len = 32 - log($5) / log(2);
    print "allow " prefix "/" len ";";
  }
  $2 == "CN" && $3 == "ipv6" {
    print "allow " $4 "/" $5 ";";
  }
' > /tmp/cn_allow.list

# 分离 IPv4 和 IPv6(避免混合导致 Nginx 报错)
grep -E 'allow [0-9]+\.' /tmp/cn_allow.list > "$OUTPUT_DIR/china-ipv4.conf"
grep -E 'allow [0-9a-fA-F:]+' /tmp/cn_allow.list > "$OUTPUT_DIR/china-ipv6.conf"

# 添加注释头
sed -i "1i# Auto-generated from APNIC — $(date)" "$OUTPUT_DIR/china-ipv4.conf"
sed -i "1i# Auto-generated from APNIC — $(date)" "$OUTPUT_DIR/china-ipv6.conf"

rm -f /tmp/cn_allow.list
echo "中国 IP 白名单已生成:"
echo "IPv4: $OUTPUT_DIR/china-ipv4.conf"
echo "IPv6: $OUTPUT_DIR/china-ipv6.conf"
赋权并运行:
chmod +x /usr/local/bin/gen-cn-allow.sh
sudo /usr/local/bin/gen-cn-allow.sh
设置每日自动更新(防止新 IP 段遗漏):
echo "0 3 * * * root /usr/local/bin/gen-cn-allow.sh >/dev/null 2>&1" | sudo tee /etc/cron.d/update-cn-ip

3.配置 Nginx 仅放行中国 IP

vim /opt/nginx/conf/nginx.conf 或 vim /opt/nginx/conf.d/xxx.conf
server {
    listen 80;
    listen [::]:80;
    server_name your-domain.com;

    # 引入中国 IP 白名单(顺序很重要!)
    include /etc/nginx/conf.d/china-ipv4.conf;
    include /etc/nginx/conf.d/china-ipv6.conf;

    # 可选:放行本地回环(避免自己被拦)
    allow 127.0.0.1;
    allow ::1;

    # 拒绝所有未匹配的请求
    deny all;

    location / {
        root /var/www/html;
        index index.html;
        # 你的其他配置...
    }
}
关键规则:Nginx 按顺序匹配 allow/deny,必须先写 alllow,再写 deny all !

4.重载生效并验证

# 检查语法
nginx -t

# 重载配置
nginx -s reload
# 或 systemctl reload nginx

5.其他注意事项

1. CDN 用户请特别注意!
如果你使用了 Cloudflare、阿里云 CDN、腾讯云 CDN 等:
用户真实 IP 被隐藏,Nginx 看到的是 CDN 节点 IP(多为境外);直接启用此规则会导致 所有用户被拦截!
解决方案:
在 CDN后台开启 “回源携带真实IP”(如 Cloudflare 的 CF-Connecting-IP);或改用 CDN 自带的地域封禁功能(更简单可靠)。
2. IPv6 支持按需启用
若服务器未启用IPv6,可删除listen [::]:80;和china-ipv6.conf引用。
3. 性能影响极小
中国大陆IP段约6000+条,Nginx 使用高效前缀匹配,实测无明显延迟。
其他方案对比(供参考)
方案优点缺点推荐场景
本文方案(APNIC + allow/deny)免费、开源、无需模块、全平台兼容需定期更新 IP 段自主运维、无 CDN、追求可控
CDN 地域封禁5 分钟上线、自动更新、抗 DDoS依赖第三方、高级功能收费已接入 CDN 的网站
iptables + ipset内核层拦截,性能极高配置复杂,Docker/NAT 环境需调试高并发、安全敏感业务
GeoIP2(MaxMind)支持国家/城市级判断需账号、需编译 Nginx需要精细地理分析的场景
如果需要高性能,还是推荐 iptables + ipset 参考文章:如何实现“仅限中国大陆访问”之 iptables + ipset + apnic 版
标签: 暂无
最后更新:2025年11月28日

Akim

犇 骉 Java、C#、Python、Go、Android、MiniProgram、Bootstrap、Vue2

点赞
< 上一篇
下一篇 >
文章目录
  • 1.获取中国大陆 IP 段
  • 2.创建自动转换脚本
  • 3.配置 Nginx 仅放行中国 IP
  • 4.重载生效并验证
  • 5.其他注意事项

Copyright © 2025 aianran.com All Rights Reserved.

免责申明 | 隐私政策 | 服务条款 | 关于我们

黔ICP备2023008200号-1

贵公网安备 52010202003594号