只要服务器暴露了 SSH 端口,日志里就会看到大量来自世界各地的登录尝试。攻击者用字典和泄露的密码库批量试密码。Fail2ban 的作用就是读这些日志,发现某个 IP 失败次数太多就自动加入防火墙黑名单,省事又有效。
Fail2ban 配置速查
| 参数 | 含义 | 建议值 |
|---|---|---|
| maxretry | 最大尝试次数 | 3-5 |
| findtime | 统计窗口 | 600 秒 |
| bantime | 封禁时长 | 3600 秒 |
| backend | 日志后端 | systemd |
| ignoreip | 白名单 | 127.0.0.1/8 |
安装与启动
Debian/Ubuntu:
sudo apt update
sudo apt install fail2ban
sudo systemctl enable fail2ban --now
CentOS/RHEL:
sudo dnf install epel-release
sudo dnf install fail2ban
sudo systemctl enable fail2ban --now
基础配置
Fail2ban 的主配置文件是 /etc/fail2ban/jail.conf,但不要直接改它——升级时会被覆盖。新建 /etc/fail2ban/jail.local 覆盖需要的部分:
[DEFAULT]
# 封禁前允许的失败次数
maxretry = 3
# 检测窗口(秒)
findtime = 600
# 封禁时间(秒),这里 1 小时
bantime = 3600
# 忽略本地和可信 IP
ignoreip = 127.0.0.1/8 ::1 你的IP
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
如果你的 SSH 改了端口,把 port = ssh 改成实际端口号。
查看运行状态
# 查看被禁 IP
sudo fail2ban-client status sshd
# 手动解封某个 IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
# 查看当前活动的 jail
sudo fail2ban-client status
防护 Nginx 登录爆破
Fail2ban 不只是防 SSH。如果你的 Nginx 后面有 WordPress 或 Odoo,可以监控 Nginx access log,封禁高频访问登录页的 IP:
# /etc/fail2ban/jail.local
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/access.log
maxretry = 30
findtime = 60
bantime = 3600
对应的 filter 文件 /etc/fail2ban/filter.d/nginx-limit-req.conf:
[Definition]
failregex = ^ .* "(GET|POST) .*HTTP.*" 429
ignoreregex =
自定义邮件通知
Fail2ban 可以发邮件通知你有人被封禁。需要在 [DEFAULT] 里配置:
destemail = your@email.com
sender = fail2ban@yourserver.com
mta = sendmail
action = %(action_mwl)s
生产环境建议只通知不自己处理,避免误封重要 IP 导致失联。
注意事项
- 不要把
bantime设得太长,误封了自己会很麻烦 - 务必把自己的管理 IP 加入
ignoreip - 定期 review 日志,调整
maxretry阈值 - Fail2ban 对分布式攻击效果有限,需要配合 CDN 或上游防护
更多服务器安全教程,请访问 fenij.com。
常见问题
问:Fail2ban 会不会误封正常用户?
答:会。如果用户输错几次密码,或者某个公司内网多个员工共用出口 IP,都可能触发。设置合理的 maxretry、保留白名单,并保留手动解封的能力。
问:Fail2ban 能防 DDoS 吗?
答:不能防大流量 DDoS,只能处理应用层的小规模暴力破解。大流量攻击需要 CDN 或上游清洗。
问:改了 SSH 端口后 Fail2ban 不生效?
答:检查 jail 里的 port 是否和实际端口一致,同时检查 logpath 指向的日志文件是否存在。有些系统用 /var/log/secure 而不是 /var/log/auth.log。