如何配置Fail2Ban同时封禁IPv6及对应IPv4地址?
解决Fail2Ban同时封禁IPv4/IPv6双栈地址的配置方案
要实现同一客户端的IPv4和IPv6地址同时被封禁,核心思路是让Fail2Ban在触发封禁时,自动关联并封禁目标主机的所有关联IP地址。以下是两种可靠的配置方法:
方法一:自定义双栈封禁Action(基于iptables/ip6tables)
通过创建自定义Action配置,让Fail2Ban在封禁单个IP时,自动通过反向解析获取目标主机的所有关联IP,一并封禁。
1. 创建自定义Action文件
在/etc/fail2ban/action.d/目录下新建dualstack-ban.conf:
[Definition] # 初始化规则链 actionstart = iptables -N f2b-<name> iptables -A f2b-<name> -j RETURN ip6tables -N f2b-<name> ip6tables -A f2b-<name> -j RETURN # 清理规则链 actionstop = iptables -F f2b-<name> iptables -X f2b-<name> ip6tables -F f2b-<name> ip6tables -X f2b-<name> # 检查规则链是否存在 actioncheck = iptables -n -L | grep -q f2b-<name> ip6tables -n -L | grep -q f2b-<name> # 封禁逻辑:先封触发IP,再解析关联IP批量封禁 actionban = iptables -I f2b-<name> 1 -s <ip> -j DROP 2>/dev/null || ip6tables -I f2b-<name> 1 -s <ip> -j DROP 2>/dev/null # 通过反向解析获取主机名 HOST=$(getent hosts <ip> | awk '{print $2}') if [ -n "$HOST" ]; then # 获取该主机名下的所有IP地址 ALL_IPS=$(getent hosts "$HOST" | awk '{print $1}') for IP in $ALL_IPS; do iptables -I f2b-<name> 1 -s "$IP" -j DROP 2>/dev/null || ip6tables -I f2b-<name> 1 -s "$IP" -j DROP 2>/dev/null done fi # 解封逻辑:反向操作 actionunban = iptables -D f2b-<name> -s <ip> -j DROP 2>/dev/null || ip6tables -D f2b-<name> -s <ip> -j DROP 2>/dev/null HOST=$(getent hosts <ip> | awk '{print $2}') if [ -n "$HOST" ]; then ALL_IPS=$(getent hosts "$HOST" | awk '{print $1}') for IP in $ALL_IPS; do iptables -D f2b-<name> -s "$IP" -j DROP 2>/dev/null || ip6tables -D f2b-<name> -s "$IP" -j DROP 2>/dev/null done fi
2. 配置Jail使用自定义Action
编辑/etc/fail2ban/jail.local,在需要双栈封禁的Jail(比如sshd)中指定banaction:
[sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 banaction = dualstack-ban # 替换为自定义Action
方法二:基于IPSet的双栈集合封禁
如果你的系统支持IPSet,这种方法更高效,适合大规模封禁场景:
1. 创建自定义IPSet Action文件
新建/etc/fail2ban/action.d/dualstack-ipset.conf:
[Definition] # 初始化IPSet集合和防火墙规则 actionstart = ipset create f2b-<name> hash:ip family inet hashsize 1024 maxelem 65536 ipset create f2b-<name>6 hash:ip family inet6 hashsize 1024 maxelem 65536 iptables -I INPUT -m set --match-set f2b-<name> src -j DROP ip6tables -I INPUT -m set --match-set f2b-<name>6 src -j DROP # 清理集合和规则 actionstop = iptables -D INPUT -m set --match-set f2b-<name> src -j DROP ip6tables -D INPUT -m set --match-set f2b-<name>6 src -j DROP ipset destroy f2b-<name> ipset destroy f2b-<name>6 # 检查集合是否存在 actioncheck = ipset list f2b-<name> >/dev/null 2>&1 ipset list f2b-<name>6 >/dev/null 2>&1 # 封禁逻辑:添加IP到对应集合,并批量添加关联IP actionban = ipset add f2b-<name> <ip> 2>/dev/null || ipset add f2b-<name>6 <ip> 2>/dev/null HOST=$(getent hosts <ip> | awk '{print $2}') if [ -n "$HOST" ]; then ALL_IPS=$(getent hosts "$HOST" | awk '{print $1}') for IP in $ALL_IPS; do ipset add f2b-<name> "$IP" 2>/dev/null || ipset add f2b-<name>6 "$IP" 2>/dev/null done fi # 解封逻辑 actionunban = ipset del f2b-<name> <ip> 2>/dev/null || ipset del f2b-<name>6 <ip> 2>/dev/null HOST=$(getent hosts <ip> | awk '{print $2}') if [ -n "$HOST" ]; then ALL_IPS=$(getent hosts "$HOST" | awk '{print $1}') for IP in $ALL_IPS; do ipset del f2b-<name> "$IP" 2>/dev/null || ipset del f2b-<name>6 "$IP" 2>/dev/null done fi
2. 应用到Jail
同样在jail.local中指定banaction = dualstack-ipset即可。
注意事项
- 反向解析依赖目标IP的PTR记录,如果客户端没有配置正确的PTR,关联IP封禁会失效;
- 确保系统安装了
getent工具(多数Linux发行版默认自带); - 配置完成后执行
fail2ban-client reload生效,可通过模拟失败登录测试封禁效果; - 若使用firewalld而非iptables,需将Action中的iptables命令替换为
firewall-cmd相关指令。
内容的提问来源于stack exchange,提问作者user19561542
相关产品推荐
相关产品推荐

