服务器暴露在公网后,最常见的噪音不是业务流量,而是各种自动化扫描、SSH 爆破、弱口令尝试和恶意请求。Fail2ban 的作用很直接:读取日志,匹配异常行为,在一段时间内自动封禁来源 IP

它不是银弹,但非常适合作为小型 VPS、博客服务器、个人网关的第一层自动防护。

本文以 Debian / Ubuntu 系服务器为例。CentOS、Rocky Linux、AlmaLinux 的思路一致,只是包管理器、日志路径和防火墙后端可能略有差异。

Fail2ban 的工作方式

Fail2ban 由三部分组成:

组件 作用 常见配置
filter 定义如何从日志里识别异常请求 /etc/fail2ban/filter.d/*.conf
jail 定义监控哪个服务、封多久、触发几次 /etc/fail2ban/jail.local
action 定义封禁动作,比如写入 iptables / nftables / ufw /etc/fail2ban/action.d/*.conf

简单说,就是:

1
日志出现多次失败记录 -> filter 命中 -> jail 计数超限 -> action 封禁 IP

安装 Fail2ban

Debian / Ubuntu:

1
2
3
sudo apt update
sudo apt install fail2ban
sudo systemctl enable --now fail2ban

确认服务状态:

1
sudo systemctl status fail2ban

不要直接改 /etc/fail2ban/jail.conf。这个文件通常是默认模板,升级时可能被覆盖。自己的配置建议写到:

1
/etc/fail2ban/jail.local

先保护 SSH

创建或编辑 /etc/fail2ban/jail.local

1
2
3
4
5
6
7
8
9
10
11
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s

这段配置的含义:

参数 含义
bantime = 1h 命中规则后封禁 1 小时
findtime = 10m 统计最近 10 分钟内的失败次数
maxretry = 5 10 分钟内失败 5 次就封禁
backend = systemd 从 systemd journal 读取日志

重启并查看状态:

1
2
3
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

如果看到 Jail list 里有 sshd,说明 SSH 防护已经启用。

配合 UFW 使用

如果你的服务器使用 UFW,可以让 Fail2ban 通过 UFW 执行封禁:

1
2
3
[DEFAULT]
banaction = ufw
banaction_allports = ufw

然后重启:

1
sudo systemctl restart fail2ban

查看 UFW 和 Fail2ban 状态:

1
2
sudo ufw status numbered
sudo fail2ban-client status sshd

如果你正在远程维护服务器,修改 SSH、防火墙和 Fail2ban 前,最好保持一个已登录的备用终端窗口。确认新配置有效后再退出,避免把自己锁在门外。

给 Nginx 加常见防护

如果博客或站点前面跑的是 Nginx,可以启用一些内置 jail。比如防止异常认证、恶意 bot 或过高频率探测:

1
2
3
4
5
6
7
8
9
10
11
12
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log

[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 10m
bantime = 6h

检查当前系统是否已有对应 filter:

1
ls /etc/fail2ban/filter.d/nginx*

如果没有相关 filter,可以先只启用 SSH,等确认 Nginx 日志格式后再补自定义规则。Fail2ban 的优势是稳,误封太激进反而会影响正常访问。

常用管理命令

场景 命令
查看所有 jail sudo fail2ban-client status
查看 SSH jail sudo fail2ban-client status sshd
手动封禁 IP sudo fail2ban-client set sshd banip 1.2.3.4
手动解封 IP sudo fail2ban-client set sshd unbanip 1.2.3.4
检查配置 sudo fail2ban-client -t
查看服务日志 sudo journalctl -u fail2ban -e

当你觉得配置不生效时,优先看这三处:

1
2
3
sudo fail2ban-client -t
sudo fail2ban-client status sshd
sudo journalctl -u fail2ban -e

推荐的安全组合

Fail2ban 最好和这些基础措施一起使用:

  1. SSH 禁止 root 直接登录。
  2. 使用 SSH key 登录,关闭密码登录。
  3. UFW 只开放必要端口,比如 2280443
  4. 服务后台、数据库、面板端口不要直接暴露公网。
  5. 定期更新系统和服务端软件。

SSH 配置一般在:

1
/etc/ssh/sshd_config

常见加固项:

1
2
3
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

改完 SSH 配置后先测试,再重启:

1
2
sudo sshd -t
sudo systemctl reload ssh

一个适合个人服务器的配置模板

下面这份配置偏保守,适合博客、小站、个人 VPS 起步使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
banaction = ufw

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s

[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log

如果你有固定公网 IP,可以把自己的 IP 加进 ignoreip,降低误封风险:

1
ignoreip = 127.0.0.1/8 ::1 你的固定IP

小结

Fail2ban 的价值不在于“绝对安全”,而在于把大量低成本攻击挡在日志层和防火墙层之外。对于个人服务器来说,它部署简单、资源占用低、效果直观,是非常值得长期启用的基础防护工具。

真正稳妥的服务器安全应该是分层的:最小开放端口、强认证、及时更新、日志监控、自动封禁。Fail2ban 正好补上了其中“自动封禁”这一环。