使用fail2ban防范SSH暴力破解攻击

随着云计算的普及,很多人都会在各大云服务商购买云服务器,只要有互联网就可以登录云服务器。但云服务器直接暴露到互联网上,始终存在被黑客攻击入侵的风险,虽然有安全组功能可以做访问限制,但是对于Linux服务器的SSH远程登录端口(默认22),很多时候客户端的公网出口IP是动态变化的,无法进行安全组规则的收敛。为了降低被暴力破解的风险,本文以CentOS7为例,介绍如何使用fail2ban防范SSH暴力破解攻击。

什么是fail2ban


fail2ban是一款利用Python开发的工具,通过扫描/var/log/auth.log等日志文件并自动封禁进行过多次失败登录尝试的IP地址,它通过更新系统防火墙来实现这一点。fail2ban可以读取许多标准日志文件,例如SSH和Apache的日志文件,并且可以根据需要配置读取任何你指定的日志文件。

安装并配置fail2ban


源码安装(推荐)

下载fail2ban

https://github.com/fail2ban/fail2ban/releases下载fail2ban的源码包Source code(tar.gz)

安装fail2ban

解压并安装fail2ban

1
2
3
tar zxf fail2ban-1.0.2.tar.gz
cd fail2ban-1.0.2
python setup.py install

将fail2ban服务添加到Systemd管理

1
2
cp -a build/fail2ban.service /usr/lib/systemd/system/
systemctl daemon-reload

启动fail2ban,设置开机自启动

1
2
3
systemctl start fail2ban
systemctl enable fail2ban
systemctl status fail2ban

配置fail2ban

根据fail2ban官网wiki建议,在配置fail2ban的时候应该避免直接更改由fail2ban安装创建的.conf文件(例如fail2ban.confjail.conf),相反,应该创建扩展名为.local的新文件(例如jail.local)来进行自定义配置。.local文件将覆盖.conf文件相同部分的参数

创建/etc/fail2ban/jail.local文件

1
touch /etc/fail2ban/jail.local

编辑/etc/fail2ban/jail.local文件,添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
[DEFAULT]
ignoreip = 127.0.0.1/8
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/secure
bantime = 1mon
findtime = 5m
maxretry = 3
action = hostsdeny

参数说明
ignoreip:配置忽略检测的IP(段),如有多个用空格隔开
enabled:配置是否启用此section的的扫描监控
port:配置服务端口,如果SSH使用非默认端口22,要修改为实际使用端口
filter:配置使用的匹配规则文件(位于/etc/fail2ban/filter.d目录中)
logpath:配置要扫描的日志文件路径
bantime:配置IP封禁的持续时间(秒或时间缩写格式:years/months/weeks/days/hours/minutes/seconds)
findtime:配置从当前时间的多久之前开始计算失败次数(秒或时间缩写格式:years/months/weeks/days/hours/minutes/seconds)
maxretry:配置在findtime时间内发生多少次失败登录然后将IP封禁。
action:配置封禁IP的手段(位于/etc/fail2ban/action.d目录中),可通过iptablesfirewalld或者TCP Wrapper等,此处设置为hostsdeny代表使用TCP Wrapper

重启fail2ban使配置生效

1
2
systemctl restart fail2ban
systemctl status fail2ban

Yum安装

说明
我使用Yum安装的fail2ban不支持通过TCP Wrapper的方式进行拦截,只能通过iptables或者firewalld,一直没找到解决方法,如果有人知道原因的欢迎评论区指导下Koen呀~

确认firewalld服务已启动

1
2
3
4
5
# 查看是否启动
systemctl status firewalld
# 若未启动执行以下命令启动
systemctl start firewalld
systemctl enable firewalld

安装fail2ban

安装EPEL repository

1
yum install epel-release -y

安装并启动fail2ban,设置开机自启动

1
2
3
4
yum install fail2ban -y
systemctl start fail2ban
systemctl enable fail2ban
systemctl status fail2ban

配置fail2ban

根据fail2ban官网wiki建议,在配置fail2ban的时候应该避免直接更改由fail2ban安装创建的.conf文件(例如fail2ban.confjail.conf),相反,应该创建扩展名为.local的新文件(例如jail.local)来进行自定义配置。.local文件将覆盖.conf文件相同部分的参数

创建/etc/fail2ban/jail.local文件

1
touch /etc/fail2ban/jail.local

编辑/etc/fail2ban/jail.local文件,添加如下内容:

1
2
3
4
5
6
7
8
9
10
[DEFAULT]
ignoreip = 127.0.0.1/8
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/secure
bantime = 1mon
findtime = 5m
maxretry = 3

参数说明
ignoreip:配置忽略检测的IP(段),如有多个用空格隔开
enabled:配置是否启用此section的的扫描监控
port:配置服务端口,如果SSH使用非默认端口22,要修改为实际使用端口
filter:配置使用的匹配规则文件(位于/etc/fail2ban/filter.d目录中)
logpath:配置要扫描的日志文件路径
bantime:配置IP封禁的持续时间(秒或时间缩写格式:years/months/weeks/days/hours/minutes/seconds)
findtime:配置从当前时间的多久之前开始计算失败次数(秒或时间缩写格式:years/months/weeks/days/hours/minutes/seconds)
maxretry:配置在findtime时间内发生多少次失败登录然后将IP封禁。

重启fail2ban使配置生效

1
2
systemctl restart fail2ban
systemctl status fail2ban

验证


通过SSH登录,然后故意输错三次密码,然后查看fail2ban日志

1
2
3
4
5
# tail -f /var/log/fail2ban.log
2023-10-13 17:05:02,370 fail2ban.filter [29824]: INFO [sshd] Found 36.250.4.182 - 2023-10-13 17:05:02
2023-10-13 17:05:04,739 fail2ban.filter [29824]: INFO [sshd] Found 36.250.4.182 - 2023-10-13 17:05:04
2023-10-13 17:05:08,415 fail2ban.filter [29824]: INFO [sshd] Found 36.250.4.182 - 2023-10-13 17:05:08
2023-10-13 17:05:08,415 fail2ban.actions [29824]: NOTICE [sshd] Ban 36.250.4.182

日志显示36.250.4.182存在三次失败登录,该IP已被封禁,具体可以通过执行fail2ban-client status sshd查看Banned IP list确认

1
2
3
4
5
6
7
8
9
10
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 6
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 5
|- Total banned: 5
`- Banned IP list: 178.128.191.224 36.250.4.182 173.212.197.129 143.110.189.9 45.79.248.160

说明
如果fail2ban是配置通过firewalld防火墙策略实施封禁,可查看防火墙策略再次确认是否生效

1
2
3
4
# firewall-cmd --list-all
......
rich rules:
rule family="ipv4" source address="36.250.4.182" port port="10022" protocol="tcp" reject type="icmp-port-unreachable"

如果fail2ban是配置通过TCP Wrapper实施封禁,可查看/etc/hosts.deny文件再次确认是否生效

解封IP


如果发现有IP被fail2ban误封了,或者确认登录IP是安全的,可以通过以下命令进行手动解封

1
2
3
4
5
# 解封所有IP
fail2ban-client unban --all
# 解封指定IP
# fail2ban-client unban <IP> ... <IP>
fail2ban-client unban 36.250.4.182