Yuhang Zheng

使用fail2ban防范ssh爆破

N 人看过

前几天登录我的小树莓派服务器的时候,发现系统日志里面大量的sshd登录日志,如下:

image-20250303111709866

这一看就是有人在爆破我的服务器的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次“试错”的机会,虽然服务器还是存在风险,但是却大大的减少了系统被爆破的概率!毕竟这可比之前每分每秒无休无止的爆破差的不是一点半点了!