如何为systemd管理的容器内sshd自定义fail2ban过滤器
我来帮你搞定这个日志前缀导致的Fail2ban过滤失效问题!核心原因就是Docker把SSHD的日志包裹了一层,默认的SSHD过滤器抓不到被dockerd[xxx]:前缀套住的日志内容,咱们一步步来调整:
1. 复制默认过滤器到自定义目录(避免升级覆盖)
首先别直接改系统默认的sshd.conf,复制一份到自定义过滤器目录,防止系统更新时被覆盖:
cp /etc/fail2ban/filter.d/sshd.conf /etc/fail2ban/filter.d/sshd-docker.conf
2. 修改自定义过滤器的正则规则
打开刚复制的sshd-docker.conf,咱们要调整正则,让它能识别带dockerd前缀的SSHD日志。你的日志格式是这样的:
Feb 13 21:51:25 my.example.com dockerd[427]: Feb 13 18:51:25 sshd[555]: Invalid user ts3bot from 180.166.17.122 port 43474
方案一:给所有failregex加dockerd前缀匹配
找到文件里所有以failregex =开头的行,在原有规则前加上^.*dockerd\[\d+\]: ,比如原来的:
failregex = ^%(__prefix_line)sInvalid user .* from <HOST>
改成:
failregex = ^.*dockerd\[\d+\]: %(__prefix_line)sInvalid user .* from <HOST>
对所有类似的failregex行(比如Failed password、User not allowed等规则)都做同样修改,这样就能匹配到被dockerd包裹的SSHD日志了。
方案二:修改_daemon变量(更简洁)
找到文件里的_daemon = sshd行,改成:
_daemon = dockerd.*sshd
这个变量会被用到默认的前缀匹配里,相当于告诉Fail2ban:要匹配的守护进程是先出现dockerd再出现sshd的日志行,这样也能完美适配你的日志格式。
3. 配置对应的Fail2ban Jail
打开/etc/fail2ban/jail.local(如果没有就新建),添加一个针对Docker化SSHD的jail配置:
[sshd-docker] enabled = true filter = sshd-docker # 用咱们刚做的自定义过滤器 logpath = /var/log/syslog # 如果用systemd journal,这里可以留空或者设置为/var/log/journal/*/*.journal backend = systemd # 如果你用的是systemd日志,加上这个更靠谱 maxretry = 3 # 失败3次就封禁 bantime = 86400 # 封禁24小时,按需调整
4. 测试过滤器是否生效
用fail2ban-regex工具验证规则是否能匹配你的日志:
fail2ban-regex /var/log/syslog /etc/fail2ban/filter.d/sshd-docker.conf
看输出里的Matches部分,如果能看到你之前的Invalid user日志被匹配到,就说明规则没问题。
5. 重启Fail2ban服务
最后重启服务让配置生效:
systemctl restart fail2ban
额外注意点
- 永远别改默认的
sshd.conf,系统更新时会被覆盖,自定义过滤器才是稳妥的做法。 - 如果容器内的时间和主机时间不一致,不用担心,Fail2ban主要识别日志里的IP和事件内容,时间戳差异不影响匹配。
- 要是还有其他类型的SSHD攻击日志(比如暴力破解密码),确保对应的failregex行也做了适配。
内容的提问来源于stack exchange,提问作者funky-future

