环境:腾讯云轻量服务器 / Rocky Linux 9.4 / 2C4G
日期:2026-09-11
背景:服务器 iptables 里有一串 REJECT 名单(云主机安全组件在拦截恶意 IP),查日志发现过去 24 小时有 397 次 SSH 密码爆破尝试——说明我的服务器一直在被人扫。是时候上 fail2ban 了。
一、fail2ban 是什么
一句话:盯着登录日志,谁试错 N 次就把谁关进小黑屋。
工作机制分两半:
- Filter(侦察兵):实时监控日志(SSH、nginx 等),用正则抓「登录失败」事件,按 IP 计数
- Action(执法队):某 IP 在
findtime 窗口内失败达到 maxretry 次 → 自动往 iptables 写一条 REJECT 规则,封禁 bantime 时长
整个过程全自动,不需要人盯着。
二、安装(Rocky 9 / dnf 系)
1
2
| dnf install -y fail2ban fail2ban-firewalld
fail2ban-client --version # 装到 v1.1.0
|
三、配置(/etc/fail2ban/jail.local)
不要改自带的 jail.conf(升级会被覆盖),新建 jail.local:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| [DEFAULT]
# 本机 IP 永不封禁(防误伤自己)
ignoreip = 127.0.0.1/8 ::1
bantime = 24h # 封多久
findtime = 10m # 多长的观察窗口
maxretry = 5 # 窗口内失败几次就封
backend = systemd # 关键!见下方踩坑
banaction = iptables-multiport
[sshd]
enabled = true
port = ssh
[nginx-http-auth]
enabled = true
[nginx-botsearch]
enabled = true
|
踩坑:Rocky 9 上必须 backend = systemd
传统教程都写监控 /var/log/secure,但 Rocky 9 / RHEL 9 的 SSH 日志默认进 systemd journal,/var/log/secure 是空的或不完整。不改 backend 的话 fail2ban 会显示「No file is currently monitored」——看似在跑,其实在梦游。
启动
1
2
| systemctl enable --now fail2ban
systemctl restart fail2ban
|
四、验证:别只看「启动成功」
服务 active ≠ 在干活。要验证三件事:
1. 日志源有没有盯上
1
| fail2ban-client status sshd
|
关键看输出里的 Journal matches:
1
| Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd + _COMM=sshd-session
|
有这行 = 侦察兵真的在盯 sshd 的 journal。如果显示 No file is currently monitored,就是上面的 backend 坑。
2. 封禁链路端到端实测(重要!)
光看 status 不够,手动封一个测试 IP 验证整条链路:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 203.0.113.99 是 TEST-NET-3 保留地址,随便用不会误伤真人
fail2ban-client set sshd banip 203.0.113.99
# 看 fail2ban 认账了
fail2ban-client status sshd
# Currently banned: 1 / Banned IP list: 203.0.113.99
# 关键:确认 iptables 里真的出现了拦截规则
iptables -L -n | grep -A2 f2b-sshd
# Chain f2b-sshd (1 references)
# REJECT 0 -- 203.0.113.99 0.0.0.0/0 reject-with icmp-port-unreachable
# 测完放出来
fail2ban-client set sshd unbanip 203.0.113.99
|
只有 iptables 里亲眼看到 REJECT 规则,才算部署完成。
3. status 输出字段怎么看
1
2
3
4
5
6
7
8
9
| Status for the jail: sshd
├─ Filter
│ ├─ Currently failed: 0 ← 当前观察窗内正在试错的 IP 数
│ ├─ Total failed: 0 ← 启动以来抓到的失败总数(不追溯启动前的)
│ └─ Journal matches: ... ← 盯的日志源
└─ Actions
├─ Currently banned: 0 ← 此刻小黑屋里关着几个
├─ Total banned: 1 ← 历史累计(含手动测试那个)
└─ Banned IP list: ... ← 当前名单
|
五、日常运维
1
2
3
4
| fail2ban-client status # 看有几个 jail 在跑
fail2ban-client status sshd # 看战果(封了几个、是谁)
fail2ban-client set sshd unbanip <IP> # 误封了手动放人
tail -f /var/log/fail2ban.log # 看实时动态
|
六、后续加固路线
fail2ban 只是第一道防线,后面还排着:
- SSH 密钥登录 + 关密码登录——做完这个,爆破直接归零(釜底抽薪)
- 安全组收敛——22 端口只对常用 IP 段开放
- dnf-automatic 自动安全更新
- 登录成功告警——有人登上服务器立刻通知我
七、总结
- 部署成本:10 分钟
- 维护成本:零(全自动)
- 收益:397 次/天的爆破尝试,从「全靠密码强度硬扛」变成「试错 5 次关 24 小时」
公网服务器第一课:你以为是安静的小站,扫描器眼里是嗷嗷待宰的肉鸡。fail2ban 该装就早点装。