Fail2ban SSH 防护配置:从日志匹配到封禁白名单验证

Fail2ban SSH 防护配置封面

这篇指南帮助你配置 Fail2ban(一种自动封禁恶意登录的工具)保护 SSH(安全远程登录协议)服务,从日志匹配规则到白名单验证,避免误封正常用户。Fail2ban 通过分析 SSH 登录日志自动封禁多次失败的 IP,但如果配置不当可能误封企业 NAT(网络地址转换)出口或自己的 IP,导致无法登录。

如果你的服务器面临 SSH 暴力破解,Fail2ban 是 容器安全加固之外的第二道防线。Hostease 这类 [VPS](https://cn.hostease.com/vps/)([虚拟专用服务器](https://cn.hostease.com/vps/))环境上的 SSH 暴露在公网,自动封禁恶意尝试是基础防护。本文重点不是 Fail2ban 安装,而是配置层面的避坑:白名单、过滤器和日志解析。如果你刚开始排查服务器安全问题,可以参考 VPS 入侵应急处理了解整体应急流程。

一、安装与初始配置

Fail2ban 在主流 Linux 发行版上都可以直接安装:

apt install fail2ban
systemctl enable fail2ban
systemctl start fail2ban

默认配置文件 /etc/fail2ban/jail.conf 会作为模板被覆盖,但实际生效的是 /etc/fail2ban/jail.local。修改配置前先复制 jail.conf 到 jail.local,再调整 jail.local,避免升级时丢失自定义配置。

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

默认 jail 已经启用了 SSH 服务,但参数比较激进。生产环境需要调整 findtime、maxretry、bantime 三个参数匹配实际场景。

Fail2ban 配置与封禁流程

二、调整封禁参数

SSH 登录失败检测的标准过滤器是 sshd。配置项含义:

  • findtime:检测窗口时间。默认 600 秒(10 分钟)。
  • maxretry:窗口内最大失败次数。默认 5 次。
  • bantime:封禁时长。默认 600 秒(10 分钟)。

对于公网暴露的服务器,建议把 bantime 设长一些(如 86400 秒 = 1 天),让被封禁的 IP 攻击者无法快速重试。但对于频繁误封场景(如 NAT 出口被多人共享),需要把 maxretry 提高到 10 或 20 次,避免单次误操作触发封禁。

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 86400

三、白名单配置

白名单是防止误封的关键配置。在 jail.local 中通过 ignoreip 设置始终信任的 IP,不会被封禁。

ignoreip = 127.0.0.1/8 192.168.0.0/16 你的家庭IP 你的公司IP

需要加入白名单的场景包括:自己的办公 IP(远程管理服务器)、公司 VPN(多个同事共用出口)、监控系统的检查 IP(防止监控被误封)、自动化脚本的执行 IP(如 Ansible 节点)。

配置白名单后必须验证。用故意输错密码的 SSH 登录测试,观察 fail2ban.log 看是否正确忽略白名单 IP。

tail -f /var/log/fail2ban.log
 # 从白名单 IP 多输错密码,确认没被封禁
fail2ban-client status sshd

如果白名单配置错误,对应 IP 在 maxretry 后仍会被封禁。常见错误包括 CIDR 格式错误(如漏写斜杠位数)、IP 写错(如 192.168.1.1 写成 192.168.1.10)。配置完成后用 fail2ban-client status sshd 查看当前被封禁 IP,确认白名单 IP 不在列表里。

四、日志解析规则

fail2ban 通过正则匹配日志识别失败登录。默认的 sshd filter 针对标准 syslog 格式,但有些 SSH 服务(如通过 Docker 转发或自定义日志格式)的日志格式可能不同,需要调整 filter。

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

这个命令会统计日志中匹配的失败登录次数和当前 filter 能否识别。如果日志格式不同,匹配数会是 0,需要修改 filter 的 failregex。修改前先备份默认配置,避免升级时丢失。

SSH 服务的日志位置在不同 Linux 发行版上不同:Debian/Ubuntu 用 /var/log/auth.log,CentOS/RHEL 用 /var/log/secure。配置 fail2ban 时要根据系统日志位置调整 logpath,否则会找不到日志导致永远不封禁。可以用 find /var/log -name "auth*" -o -name "secure*" 确认日志文件路径。容器化环境如果 SSH 服务在容器内运行,需要把宿主机的日志通过 volume 或日志收集系统转发到 fail2ban 能读取的位置。

对于多 IP 来源的日志(如经过跳板机或反向代理),日志里的源 IP 会被替换为跳板机或反向代理的 IP。fail2ban 默认按日志源 IP 封禁,会把所有经过跳板的真实客户端 IP 都封禁。解决方法是在 SSH 服务端配置 ReversePathFilter 或在 fail2ban filter 中通过日志中的原始字段提取真实 IP。如果你做了 Nginx 限流配置,反向代理层会转发真实 IP 到后端 SSH 日志,但 fail2ban 仍按日志里的字段读取,需要确认日志格式正确。

自定义 filter 时建议先在测试环境验证正则匹配。用 fail2ban-regex 配合实际日志样本测试,确认 failregex 能匹配上所有失败登录事件。匹配规则过严会漏封攻击者,过宽会误封正常登录。SSH 失败登录的特征关键词包括:Failed password、Invalid user、Connection closed by authenticating user。每个发行版的格式略有差异,最好把当前环境的日志样本提取出来作为测试输入。

如果你做了 WordPress 安全加固,fail2ban 也可以保护 WordPress 的 wp-login.php:通过自定义 filter 监控 nginx 或 Apache 访问日志,匹配 wp-login.php 的 POST 失败请求,把暴力破解者加入临时封禁。但要注意,HTTP 封禁的过滤规则和 SSH 不同,且失败率高时可能误封搜索引擎爬虫,建议设置较高的 maxretry。完整的 WordPress 安全防护还可以参考 Nginx 限流配置在反向代理层减少攻击请求,到达 fail2ban 之前就被拦截。

白名单与日志规则对比

五、监控与解封

Fail2ban 封禁是临时的,到期会自动解封。如果某个 IP 误封了且等不到自动解封,可以用 fail2ban-client 手动解封:

fail2ban-client set sshd unbanip 192.168.1.100

长期监控需要把 fail2ban 的状态接入监控平台。可以定期运行 fail2ban-client status sshd,统计被封禁 IP 数量、封禁规则触发次数、解封次数。如果某个 IP 反复被封禁,说明这是持续攻击源,可以加入永久黑名单。

总结

Fail2ban SSH 防护配置的核心是白名单和日志解析:白名单防止误封正常用户,日志解析确保能识别攻击尝试。配置完成后必须验证:故意输错密码看 fail2ban.log 是否正确忽略白名单 IP,用 fail2ban-regex 测试日志解析规则。生产环境建议 bantime 设长一些(如 24 小时),让攻击者无法快速重试。同时定期检查被封禁 IP 列表,识别持续攻击源。对于 Hostease 这类 VPS 环境,Fail2ban 是 SSH 防护的基础工具,配合强密码或密钥认证形成多层保护。

发表评论