使用fail2ban防范ssh爆破
前几天登录我的小树莓派服务器的时候,发现系统日志里面大量的sshd登录日志,如下:
这一看就是有人在爆破我的服务器的sshd端口,虽然我更改了sshd的默认登录端口,结果还是被这群人给扫到了呀,幸亏自己设置了强密码,所以才让他们没办法轻易的爆破掉。(不过看来以后还是换成密钥登陆,关闭密码登录才是更保险的措施呢。)
这么被一直的爆破总是有风险的,那么有没有办法限制一下呢?类似于登录其他网站的时候输错几次密码直接不让输了,明天才能继续尝试一类的?
结果问了grok之后,才知道linux上早就有这种软件了,那就是fail2ban
下面简单记录一下这个软件的安装配置方法吧!
1. 安装 fail2ban
sudo apt update sudo apt install fail2ban
安装完成后,启动并启用服务:
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
2. 配置 fail2ban
fail2ban 默认已经支持 SSH 的防护,但是需要调整配置文件来满足我们的需求:同一 IP 登录失败 5 次后屏蔽,直到第二天。
创建自定义配置文件
编辑主配置文件前,建议创建一个本地配置文件以覆盖默认设置:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
然后编辑 jail.local:
sudo vim /etc/fail2ban/jail.local
配置 SSH 防护规则
找到[DEFAULT]部分,修改以下参数
findtime = 10m
maxretry = 5
- findtime = 10m:统计失败次数的时间窗口为 10 分钟。
- maxretry = 5:同一个 IP 在 findtime 时间内失败 5 次触发屏蔽。
找到 [sshd] 部分,或者添加以下内容:
[sshd]
enabled = true
action = %(action_)s
port = ssh
logpath = %(sshd_log)s # Debian/Ubuntu 系统日志路径
bantime = 24h # 屏蔽时间 1 天
backend = %(sshd_backend)s
- bantime = 86400:屏蔽时间为 24 小时(第二天自动解禁)。
3. 重启 fail2ban 服务
保存配置文件后,重启服务使配置生效:
sudo systemctl restart fail2ban
但是在查看服务状态的时候发现服务启动失败,
fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Fri 2025-02-28 14:55:06 CST; 13s ago
Duration: 406ms
Docs: man:fail2ban(1)
Process: 2247179 ExecStart=/usr/bin/fail2ban-server -xf start (code=exited, status=255/EXCEPTION)
Main PID: 2247179 (code=exited, status=255/EXCEPTION)
CPU: 385ms
Feb 28 14:55:06 raspberrypi systemd[1]: Started fail2ban.service - Fail2Ban Service.
Feb 28 14:55:06 raspberrypi fail2ban-server[2247179]: 2025-02-28 14:55:06,810 fail2ban.configreader [2247179]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Feb 28 14:55:06 raspberrypi fail2ban-server[2247179]: 2025-02-28 14:55:06,851 fail2ban [2247179]: ERROR Failed during configuration: Have not found any log file for sshd jail
Feb 28 14:55:06 raspberrypi fail2ban-server[2247179]: 2025-02-28 14:55:06,852 fail2ban [2247179]: ERROR Async configuration of server failed
Feb 28 14:55:06 raspberrypi systemd[1]: fail2ban.service: Main process exited, code=exited, status=255/EXCEPTION
Feb 28 14:55:06 raspberrypi systemd[1]: fail2ban.service: Failed with result 'exit-code'.
从报错信息上看,这表明 fail2ban 在配置 sshd jail 时找不到指定的日志文件。问题很可能出在 logpath 设置上,可能指定的日志文件路径不正确或不存在。
ERROR Failed during configuration: Have not found any log file for sshd jail
这是因为对于 Raspbian 系统,使用的是 systemd,SSH 日志被 journald 管理了,所以修改[sshd] 部分,增加一行:
sshd_backend = systemd
这样再次重启 fail2ban 服务就可以正常运行了。
4. 测试配置
你可以尝试用一个测试 IP 故意输错密码 5 次,观察是否被屏蔽:
检查被屏蔽的 IP:
sudo fail2ban-client status sshd
输出中会显示当前被屏蔽的 IP 列表。
手动解禁(如果需要测试):
sudo fail2ban-client unban <IP地址>
但是测试中发现,并没有屏蔽成功,虽然可以看到fail2ban的服务确实运行了,但是输错密码的IP还是没有被ban
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 22
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 65.20.189.35
后来发现原因是如果已经修改了 SSH 的端口号(例如从默认的 22 改为 2222),那么在 fail2ban 的配置文件中也需要相应地更新 [sshd] 部分的 port 参数。否则,fail2ban 会继续监控原来的默认端口(22),而无法正确保护修改后的 SSH 服务。
所以还需要修改[sshd] 部分的port为真实使用的端口号就可以了。
修改完成之后,发现系统日志里面的爆破信息果然就没有了!
这样修改之后,每个IP每天只有5次“试错”的机会,虽然服务器还是存在风险,但是却大大的减少了系统被爆破的概率!毕竟这可比之前每分每秒无休无止的爆破差的不是一点半点了!