fail2ban自定义规则拦截跨境扫描IP实操指南
为什么需要拦截跨境扫描IP
服务器频繁被国外IP扫描端口或爆破登录,轻则拉高CPU负载,重则被拿下权限。
fail2ban自带的基础规则只能拦截固定频率的重复失败行为,但无法区分国内外IP。
通过自定义规则,你可以在fail2ban中直接屏蔽特定国家或地区的IP段,从源头减少大量无效攻击。
本文以CentOS 7/Ubuntu 20.04为例,演示从零配置完整方案。
前提准备:确认fail2ban已安装并运行
先确认系统上是否存在fail2ban,执行:
fail2ban-client --version
如果没有输出,请安装:
- CentOS/RHEL:
sudo yum install epel-release && sudo yum install fail2ban -y - Ubuntu/Debian:
sudo apt update && sudo apt install fail2ban -y
安装后启动并设置开机自启:
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
查看状态确保running:
sudo fail2ban-client status
核心步骤:编写自定义规则拦截跨境扫描IP
1. 获取目标IP段(以中国IP为例)
如果你只想允许国内IP访问,可以用GeoIP数据库或从APNIC获取IP段。
这里推荐一个简单方法:使用ipip2location或下载中国IP列表。
但为了避免依赖外部服务,你也可以直接在中国互联网信息中心(CNNIC)获取IP分配数据。
本文用一个更直白的策略:利用Fail2ban的ignoreip和badip结合iptables的ipset模块。
不过对新手来说,更稳妥的是按国家代码屏蔽。
2. 使用fail2ban内置的maxminddb插件(推荐)
Fail2ban 1.0+版本支持GeoIP过滤,前提是安装GeoIP数据库。
sudo apt install geoip-database # Ubuntu
sudo yum install GeoIP GeoIP-update # CentOS
然后在/etc/fail2ban/jail.local中添加一个自定义jail:
[sshd-allow-china]
enabled = true
filter = sshd
logpath = /var/log/auth.log
action = iptables-allports[name=ssh, country=CN, chain=INPUT, protocol=all]
%(action_mwl)s
maxretry = 3
bantime = 86400
这个jail使用了filter=sshd,但action中加入了country=CN参数——实际上默认action不支持此参数。
我们需要创建一个自定义action。
3. 编写自定义action(基于ipset)
更可控的方式是使用fail2ban配合ipset和白名单。
下面给出一个经典的自定义规则:只允许中国IP访问,其余全部拦截(谨慎使用,适合仅面向国内用户的业务)。
创建文件/etc/fail2ban/action.d/iptables-allow-cn.conf:
[Definition]
actionban = ipset add fail2ban-
iptables -I 1 -m set --match-set fail2ban- src -j DROP
actionunban = ipset del fail2ban-
iptables -D -m set --match-set fail2ban- src -j DROP
[Init]
chain = INPUT
然后在jail.local中引用这个action,并用ignoreip指定允许的国内IP段。
4. 更为直接的方式:用maxminddb动作
从Fail2ban 1.0开始,自带了iptables-ipset-proto6-allports.conf并支持family参数。
但最实用的是使用社区提供的iptables-geoip动作。
下载iptables-geoip.conf到/etc/fail2ban/action.d/,然后在jail中指定:
[sshd-geo-block]
enabled = true
filter = sshd
logpath = /var/log/auth.log
action = iptables-geoip[countrycode=CN, port=ssh, protocol=tcp]
maxretry = 3
findtime = 600
bantime = 3600
这个动作会先查询IP的GeoIP数据,如果不是CN(中国),则ban。
注意:需要安装GeoIP数据库和lua库。
若不想引入外部数据库,还可以用IP段匹配规则:在/etc/fail2ban/filter.d/下新建grep-allowed-ip.conf,但维护IP段列表较麻烦。
避坑说明:防止误拦国内正常IP
- 测试环境先用soft模式:设置
bantime = 60,观察日志,确认没有误拦。 - 白名单优先:在
jail.local的[DEFAULT]中设置ignoreip = 127.0.0.1/8 你的公司出口IP,避免把自己关在外面。 - GeoIP数据库及时更新:每月运行
geoipupdate或使用付费版,否则IP归属可能过时。 - 不要对全部端口使用过滤:只针对SSH、Web等暴露端口,避免影响邮件等业务。
效果验证:检查名单和日志
执行以下命令查看日志:
sudo tail -f /var/log/fail2ban.log
当有非中国IP尝试登录时,你会看到类似:
2025-04-10 12:34:56,123 fail2ban.actions [1234]: NOTICE [sshd-geo-block] Ban 203.0.113.50 (geoip country: US)
同时验证iptables规则:
sudo iptables -L -n | grep fail2ban
你应该能看到相应的DROP规则。
高频问题解答
Q:Fail2ban能否直接根据IP段屏蔽某个国家?
A:标准版本不能,但可以通过自定义action配合iptables+ipset+maxminddb实现。
Q:我的业务只面向国内,能不能一键禁止所有国外IP?
A:可以,但强烈建议先测试,防止云厂商的监控IP被误拦。推荐的做法是使用“白名单+防火墙”而非黑名单。
Q:有没有更简单的脚本?
A:可以配合country.sh脚本,从ipip.net下载IP段并写入ipset,再让fail2ban引用。推荐先掌握基础方法。
总结
通过fail2ban自定义规则拦截跨境扫描IP,核心是利用GeoIP或IP段白名单,在fail2ban动作层区分国内与国外。
初次配置时建议从小范围实验开始,逐步扩展。
如果你正在处理此问题,建议先按本文步骤在测试环境完整跑通,再应用到生产服务器;
遇到异常时优先检查GeoIP数据库版本和ignoreip设置。