Linux宝塔实战:一键屏蔽国外IP访问的高效脚本(附完整代码)

张开发
2026/4/11 10:48:09 15 分钟阅读

分享文章

Linux宝塔实战:一键屏蔽国外IP访问的高效脚本(附完整代码)
1. 为什么需要屏蔽国外IP访问最近几年不少站长朋友都遇到过这样的糟心事网站刚有点起色就被各种恶意爬虫和CC攻击盯上。更气人的是这些攻击流量大部分来自国外IP。我自己运营的几个网站也深受其害最严重的时候服务器直接被搞到宕机。为什么国外IP这么活跃主要有几个原因一是国外VPS价格便宜攻击者可以轻松购买大量资源二是跨境追查难度大违法成本低三是很多采集站为了规避国内备案要求专门把服务器架设在海外。实测发现屏蔽国外IP后能挡掉70%以上的恶意流量。传统做法是在域名解析层面设置境外线路指向127.0.0.1但实测根本没用别问我怎么知道的说多了都是泪。后来摸索出用iptablesipset的方案效果立竿见影。下面就把我在宝塔环境下的实战经验完整分享出来。2. 准备工作与环境检查2.1 确认服务器环境这套方案适用于CentOS 7/8推荐Ubuntu 16.04已安装宝塔面板任何版本服务器内存≥1GB处理大IP段时需要足够内存登录服务器后先检查关键组件# 检查iptables版本 iptables --version # 检查ipset是否安装 ipset --version如果提示命令不存在需要先安装# CentOS yum install -y iptables ipset # Ubuntu apt-get install -y iptables ipset2.2 获取国内IP段数据我们使用APNIC官方数据源通过这个命令获取最新国内IP段wget -q --timeout60 -O- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | awk -F\| /CN\|ipv4/ { printf(%s/%d\n, $4, 32-log($5)/log(2)) } /root/china_ssr.txt这个文件大概包含8000条记录大小约200KB。建议每周自动更新一次# 创建定时任务 (crontab -l 2/dev/null; echo 0 3 * * 1 /usr/bin/wget -q --timeout60 -O- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | awk -F\| /CN\|ipv4/ { printf(\%s/%d\\n\, \$4, 32-log(\$5)/log(2)) } /root/china_ssr.txt) | crontab -3. 核心脚本实现与解析3.1 完整脚本代码将以下内容保存为/root/allcn.sh#!/bin/bash mmode$1 CNIP/root/china_ssr.txt gen_iplist() { cat -EOF $(cat ${CNIP:/dev/null} 2/dev/null) EOF } flush_r() { iptables -F ALLCNRULE 2/dev/null iptables -D INPUT -p tcp -j ALLCNRULE 2/dev/null iptables -X ALLCNRULE 2/dev/null ipset -X allcn 2/dev/null } mstart() { ipset create allcn hash:net 2/dev/null ipset -! -R -EOF $(gen_iplist | sed -e s/^/add allcn /) EOF iptables -N ALLCNRULE iptables -I INPUT -p tcp -j ALLCNRULE iptables -A ALLCNRULE -s 127.0.0.0/8 -j RETURN iptables -A ALLCNRULE -s 169.254.0.0/16 -j RETURN iptables -A ALLCNRULE -s 224.0.0.0/4 -j RETURN iptables -A ALLCNRULE -s 255.255.255.255 -j RETURN # 在此添加你的办公网络IP避免被误封 # iptables -A ALLCNRULE -s 你的公网IP/24 -j RETURN iptables -A ALLCNRULE -m set --match-set allcn src -j RETURN iptables -A ALLCNRULE -p tcp -j DROP } if [ $mmode stop ] ;then flush_r exit 0 fi flush_r sleep 1 mstart给脚本添加执行权限chmod x /root/allcn.sh3.2 脚本原理解析这个脚本的核心机制是使用ipset创建名为allcn的哈希集合将国内IP段批量导入ipset通过iptables创建自定义规则链对非国内IP的TCP连接直接DROP几个关键点说明hash:net类型的ipset特别适合存储IP段保留了一些特殊IP段如本地回环规则链插入到INPUT链的最前面匹配效率极高实测对服务器性能影响1%4. 宝塔面板集成方案4.1 通过计划任务自动运行在宝塔面板添加计划任务进入计划任务界面任务类型选Shell脚本名称填屏蔽国外IP执行周期选每天脚本内容填/root/allcn.sh4.2 防火墙规则持久化为了防止重启失效需要保存规则# CentOS 7 yum install -y iptables-services systemctl enable iptables iptables-save /etc/sysconfig/iptables ipset save /etc/sysconfig/ipset # Ubuntu apt-get install -y iptables-persistent netfilter-persistent save4.3 白名单设置技巧如果需要允许某些国外IP访问可以这样操作# 先查询现有规则编号 iptables -L ALLCNRULE --line-numbers # 在DROP规则前插入放行规则假设要放行1.2.3.4 iptables -I ALLCNRULE 6 -s 1.2.3.4 -j RETURN5. 常见问题排查5.1 误封了国内IP怎么办这种情况通常是因为IP段数据没有及时更新本地网络使用了非常规IP段解决方案# 临时停止屏蔽 /root/allcn.sh stop # 更新IP段数据 wget -q --timeout60 -O- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | awk -F\| /CN\|ipv4/ { printf(%s/%d\n, $4, 32-log($5)/log(2)) } /root/china_ssr.txt # 重新启用 /root/allcn.sh5.2 服务器性能突然下降可能原因IPset内存占用过高规则冲突检查命令# 查看内存占用 ipset list | grep allcn -A5 # 查看规则匹配计数 iptables -L ALLCNRULE -v优化建议调整hash:net的hashsize参数减少不必要的规则链跳转5.3 如何验证规则生效测试方法用国内服务器curl测试使用在线代理网站测试查看实时日志tail -f /var/log/btmp | grep sshd6. 高级应用场景6.1 针对特定端口设置比如只屏蔽国外IP对80/443端口的访问iptables -A ALLCNRULE -p tcp --dport 80 -j DROP iptables -A ALLCNRULE -p tcp --dport 443 -j DROP6.2 结合Fail2Ban增强防护先安装Fail2Ban# CentOS yum install -y fail2ban # Ubuntu apt-get install -y fail2ban然后修改配置/etc/fail2ban/jail.local[sshd] enabled true filter sshd action iptables-allcn[nameSSH, portssh, protocoltcp] logpath /var/log/auth.log maxretry 36.3 负载均衡环境部署在多台服务器上同步规则# 主服务器导出规则 ipset save allcn allcn.ipset iptables-save allcn.iptables # 从服务器导入 scp allcn.* rootnode1:/root/ ssh rootnode1 ipset restore allcn.ipset iptables-restore allcn.iptables这套方案在我管理的十几台服务器上稳定运行超过两年成功抵御了数十次大规模CC攻击。有个电商客户在部署后服务器负载直接从8.0降到了1.5以下。最关键的是维护成本极低设置好后基本不用操心。

更多文章