Fail2ban 防暴力破解配置完全指南 | SSH 安全防护教程
如果你使用的是默认端口(22)和传统的密码登录方式来连接你的 VPS,过不了几天你去查看系统日志,一定会发现大量的“失败登录尝试”。这是因为互联网上随时有无数的扫描脚本和僵尸网络在无差别地尝试爆破所有服务器的 SSH 密码。
这不仅占用系统资源,万一密码设得比较简单,服务器直接就沦陷成了“肉鸡”。
为了解决这个问题,除了 改用 SSH 密钥登录 之外,安装一款能自动识别“多次密码输入错误”并将其 IP 封禁的防火墙工具是非常有必要的。Fail2ban 就是其中的黄金标准。
什么是 Fail2ban?
Fail2ban 是一款强大的防御软件。它的工作原理很简单: 后台默默扫描系统日志(如 /var/log/auth.log),如果它发现某个 IP 地址在短时间内连续多次尝试密码失败,它就会自动去修改防火墙(iptables/ufw/firewalld 等)规则,把这个来源 IP 给拉黑(封禁)一段时间。
一次配置,终身免疫。
Fail2ban vs 其他安全工具对比
| 特性 | Fail2ban | DenyHosts | iptables 手动规则 | 云服务商 WAF |
|---|---|---|---|---|
| 自动化程度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐⭐⭐ |
| 灵活性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 支持协议 | 多种(SSH, Web, Mail等) | 仅 SSH | 所有 | 取决于服务 |
| 配置难度 | 中等 | 简单 | 困难 | 简单 |
| 资源占用 | 低 | 极低 | 无 | 无 |
| 免费开源 | ✅ | ✅ | ✅ | ❌ |
步骤一:安装 Fail2ban
Fail2ban 在包括 Debian 和 Ubuntu 在内的绝大部分 Linux 发行版的官方软件源里都能直接找到。
Debian/Ubuntu 安装
- 首先更新一下软件包列表:bash
apt update - 执行安装命令:bash
apt install fail2ban -y
CentOS/RHEL 安装
# 启用 EPEL 仓库
yum install epel-release -y
# 安装 Fail2ban
yum install fail2ban -y验证安装
# 检查版本
fail2ban-client --version
# 检查服务状态
systemctl status fail2ban安装完成后,Fail2ban 这个服务会自动启动并在后台默默运行。
步骤二:新建 Fail2ban 自定义配置(核心动作)
Fail2ban 所有的默认“封禁规则”和“监狱(Jail)”配置都存放在 /etc/fail2ban/jail.conf 这个文件里。 但是,官方强烈建议:不要去修改原始的 jail.conf 文件! 因为一旦未来软件升级,你的修改就有丢失的可能。
正确的做法是:新建一个 jail.local 文件,把属于我们自己的改动写在里面。 它的优先级比原始文件高。
基础配置
使用你最爱的编辑器打开(新建)这个文件:
bashnano /etc/fail2ban/jail.local将以下最基础、最实用的防护规则配置项 复制并粘贴 进去:
ini[DEFAULT] # 这是默认设置 # 忽略你自己的本地 IP 不受封禁(相当于白名单),如果你有固定 IP,也可以加在这里,用空格隔开。 ignoreip = 127.0.0.1/8 ::1 # 封禁时间:被拉黑后,多长秒数放出来。这里填 86400 (秒) 相当于封禁一天。 bantime = 86400 # 找茬时间窗口:在这个时间跨度内计算失败次数。这里设为 600 秒(十分钟)。 findtime = 600 # 最大容忍次数:10 分钟内,一旦失败次数大于等于 3 次,立刻封禁。 maxretry = 3 [sshd] # 开启针对 SSH 的监控监狱 enabled = true # 如果你改过 SSH 服务用的端口,请在这里写上你的新端口,如果是默认的 22,可以不写。 port = ssh粘贴完了以后,按下快捷键
Ctrl + X,再按一下字母Y,然后敲击键盘回车键保存退出。
高级配置示例
保护 Web 服务(Nginx/Apache):
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 86400保护 WordPress:
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 3
bantime = 3600保护 Postfix/Dovecot(邮件服务):
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps
filter = dovecot
logpath = /var/log/mail.log配置参数详解
| 参数 | 说明 | 推荐值 | 单位 |
|---|---|---|---|
bantime | 封禁时长 | 86400(1天)或 3600(1小时) | 秒 |
findtime | 检测时间窗口 | 600(10分钟) | 秒 |
maxretry | 最大失败次数 | 3-5 次 | 次数 |
ignoreip | 白名单 IP | 127.0.0.1/8 和你的固定 IP | CIDR |
backend | 日志监控后端 | auto(自动选择) | - |
usedns | DNS 查询 | warn(警告但不阻止) | - |
封禁时间策略建议:
- 首次违规:1 小时(3600 秒)
- 重复违规:1 天(86400 秒)
- 恶意攻击:1 周(604800 秒)或永久
步骤三:重启服务生效与日常查看
修改完了属于咱们自己的安全配置文件之后,我们需要告诉 Fail2ban 这位门卫大爷重新看一遍工作手册:
bashsystemctl restart fail2ban为了保证无论重启服务器多少次它都在默默工作,随手允许它开机自启动:
bashsystemctl enable fail2ban
怎么查看它有没有在工作?抓到了几个坏人?
咱们可以通过它的客户端命令去查看目前有哪些因为爆破 SSH 被关进“小黑屋”的倒霉蛋。
fail2ban-client status sshd终端将会友好地输出一份短小的报告:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0 # 当前正在数错密码的次数(因为还没超过3次)
| |- Total failed: 21 # 从服务开始到现在,这帮人一共输错了多少次密码
`- Actions
|- Currently banned: 3 # 此刻正待在小黑屋里被封号的倒霉 IP 数量(被 ban 了!)
|- Total banned: 5 # 历史总共拉黑过的倒霉蛋
`- Banned IP list: 192.168.1.100 203.0.113.45 198.51.100.22 # 这里会列出被你封禁的详细 IP 地址查看所有监狱状态
# 列出所有启用的监狱
fail2ban-client status
# 输出示例:
# Status
# |- Number of jail: 3
# `- Jail list: sshd, nginx-http-auth, wordpressFail2ban 日志管理
查看 Fail2ban 日志
# 实时查看日志
tail -f /var/log/fail2ban.log
# 查看最近的封禁记录
grep "Ban" /var/log/fail2ban.log | tail -20
# 查看解封记录
grep "Unban" /var/log/fail2ban.log | tail -20日志轮转配置
Fail2ban 自带日志轮转配置,通常位于 /etc/logrotate.d/fail2ban:
cat /etc/logrotate.d/fail2ban典型配置:
/var/log/fail2ban.log {
weekly
rotate 4
compress
delaycompress
missingok
postrotate
fail2ban-client flushlogs >/dev/null || true
endscript
}常用管理命令
封禁/解封 IP
# 手动封禁 IP
fail2ban-client set sshd banip 192.168.1.100
# 手动解封 IP
fail2ban-client set sshd unbanip 192.168.1.100
# 解封所有 IP
fail2ban-client set sshd unbanip --all查看封禁列表
# 查看特定监狱的封禁 IP
fail2ban-client get sshd actionunbannedips
# 查看 iptables 规则
iptables -L f2b-sshd -n -v重载配置
# 重载所有监狱配置
fail2ban-client reload
# 重载特定监狱
fail2ban-client reload sshd停止/启动服务
# 停止 Fail2ban
systemctl stop fail2ban
# 启动 Fail2ban
systemctl start fail2ban
# 重启 Fail2ban
systemctl restart fail2ban
# 查看状态
systemctl status fail2ban自定义过滤器(Filter)
如果内置过滤器不满足需求,可以创建自定义过滤器。
创建自定义过滤器
示例:保护自定义应用
- 创建过滤器文件:
nano /etc/fail2ban/filter.d/myapp.conf- 添加过滤规则:
[Definition]
# 匹配失败登录的正则表达式
failregex = ^.*Failed login from <HOST>.*$
^.*Authentication failure.*from <HOST>.*$
# 忽略的行(可选)
ignoreregex =- 在
jail.local中引用:
[myapp]
enabled = true
port = 8080
filter = myapp
logpath = /var/log/myapp/access.log
maxretry = 3
bantime = 3600- 重载配置:
fail2ban-client reload测试过滤器
# 测试过滤器是否能正确匹配日志
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# 输出会显示匹配的行数和示例常见问题排查
Q1: Fail2ban 没有封禁任何 IP?
排查步骤:
- 检查服务状态
systemctl status fail2ban- 查看日志是否有错误
tail -50 /var/log/fail2ban.log- 确认监狱已启用
fail2ban-client status sshd- 检查日志路径是否正确
# 查看 SSH 日志
tail -20 /var/log/auth.log
# 确认有失败登录记录
grep "Failed password" /var/log/auth.log- 测试过滤器
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.confQ2: 误封了自己的 IP 怎么办?
解决方案:
# 方法 1:从 VNC 控制台登录解封
fail2ban-client set sshd unbanip 你的IP
# 方法 2:临时停止 Fail2ban
systemctl stop fail2ban
# 方法 3:将自己的 IP 加入白名单
nano /etc/fail2ban/jail.local
# 在 ignoreip 中添加你的 IP
ignoreip = 127.0.0.1/8 ::1 你的IP/32
# 重载配置
fail2ban-client reload预防措施:
- 始终将自己的固定 IP 加入
ignoreip白名单 - 先测试配置,确认无误后再启用严格规则
- 保留 VNC 控制台访问权限作为应急通道
Q3: 封禁时间太短/太长如何调整?
动态调整(无需重启):
# 修改 SSH 监狱的封禁时间为 1 周
fail2ban-client set sshd bantime 604800
# 修改最大重试次数为 5
fail2ban-client set sshd maxretry 5
# 修改检测时间窗口为 20 分钟
fail2ban-client set sshd findtime 1200永久修改: 编辑 /etc/fail2ban/jail.local,修改对应参数后重载。
Q4: 如何查看哪些 IP 正在尝试爆破?
# 实时查看失败登录尝试
tail -f /var/log/auth.log | grep "Failed password"
# 统计最常见的攻击 IP
grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | \
sort | uniq -c | sort -rn | head -20
# 查看今天的攻击情况
grep "$(date +%b %e)" /var/log/auth.log | grep "Failed password"Q5: Fail2ban 占用资源过高?
优化建议:
- 减少日志扫描频率
# 在 jail.local 的 [DEFAULT] 部分添加
backend = systemd # 使用 systemd journal 而非轮询文件- 简化过滤器正则
- 避免过于复杂的正则表达式
- 使用
fail2ban-regex测试效率
- 限制监狱数量
- 只启用真正需要的监狱
- 禁用不必要的监控
- 检查日志文件大小
# 清理旧日志
journalctl --vacuum-time=7d
# 轮转大日志文件
logrotate -f /etc/logrotate.confFail2ban 与其他安全工具配合
1. Fail2ban + SSH 密钥登录
最佳实践组合:
# 1. 启用 SSH 密钥登录
# 2. 禁用密码登录
# 3. 修改 SSH 端口
# 4. 启用 Fail2ban 作为最后一道防线2. Fail2ban + UFW 防火墙
# UFW 负责基础端口管理
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
# Fail2ban 负责动态封禁恶意 IP
# 两者互补,提供多层防护3. Fail2ban + Cloudflare
如果使用 Cloudflare CDN,需要特殊配置:
# 在 jail.local 中添加
[DEFAULT]
# 信任 Cloudflare IP 段
ignoreip = 127.0.0.1/8 ::1 173.245.48.0/20 103.21.244.0/22 ...
# 使用 Cloudflare API 封禁 IP(需额外配置 action)
action = cloudflare监控与告警
设置邮件告警
# 在 jail.local 的 [DEFAULT] 部分添加
destemail = admin@example.com
sender = fail2ban@your-server.com
mta = sendmail
action = %(action_mwl)s # 封禁时发送邮件并附带日志使用 Telegram 机器人告警
创建自定义 action:
nano /etc/fail2ban/action.d/telegram.conf[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST https://api.telegram.org/bot<TOKEN>/sendMessage \
-d chat_id=<CHAT_ID> \
-d text="🚨 Fail2ban: IP <ip> 已被封禁\n监狱: <name>\n原因: <failures> 次失败"
actionunban = curl -s -X POST https://api.telegram.org/bot<TOKEN>/sendMessage \
-d chat_id=<CHAT_ID> \
-d text="✅ Fail2ban: IP <ip> 已解封\n监狱: <name>"最佳实践总结
安全配置清单
✅ 基础安全
✅ Fail2ban 配置
✅ 监控与维护
推荐配置方案
个人博客/小型网站:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true企业级服务器:
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 3
ignoreip = 127.0.0.1/8 ::1 公司IP/32
[sshd]
enabled = true
[nginx-http-auth]
enabled = true
[wordpress]
enabled = true有了 Fail2ban 坐镇你的服务器,你可以在面对日志里乱飞的牛鬼蛇神时,喝杯茶会心一笑了。☕✨
- 🔥🔥🔥2026年便宜好用的翻墙VPN机场推荐评测(长期更新 欢迎推荐)
- 稳定好用的流媒体合租平台推荐(长期更新 欢迎推荐)
- AI 使用教程汇总|ChatGPT、Gemini 新手入门与国内使用指南
- 国外接码平台 Hero SMS 评测(稳定 · 低价 · 高成功率)
免责声明
本文仅供技术交流和学习参考,请遵守当地法律法规,合理合法使用网络服务。