对于网站被恶意扫描、暴力破解、CC 攻击这一系列攻击,都有相似的特征,即高频率发请求导致主机资源使用率飙高。对于这些问题,我们可以借助一些工具来阻止类似行为以保护服务器的安全。

本篇文章就介绍如何使用Fail2Ban来阻止一些常见的暴力攻击。

简介

fail2ban 是 Linux 上的一个著名的开源入侵保护服务框架,它可以监控多个系统的日志文件(例如:/var/log/auth.log 或者 /var/log/secure)并根据检测到的任何可疑的行为自动触发不同的防御动作。事实上,fail2ban 在防御对SSH服务器的暴力密码破解上非常有用,同时它也可以通过监控web服务器的日志(如Nginx、Apache)从而实现异常IP自动封禁。

安装Fail2Ban

安装命令如下

#CentOS
sudo yum install fail2ban
#Debian&Ubuntu
sudo apt install fail2ban

调整配置文件

现在你已经准备好了通过配置 fail2ban 来保护你的服务器了,你需要通过编辑配置文件 /etc/fail2ban/jail.conf在里面添加监狱规则来实现。

在配置文件的“[DEFAULT]”区,你可以在此定义所有受监控的服务的默认参数,另外在特定服务的配置部分,你可以为每个服务(例如SSH,Apache等)设置特定的配置来覆盖默认的参数配置。

这三个是比较重要配置项,默认值如下

# 封禁时间
bantime  = 10m
# 在多长时间内
findtime  = 10m
# 最大失败次数
maxretry = 5

它的意思是:在10分钟内,如果失败超过5次,那么就将这个IP丢到小黑屋里10分钟。

理解了这三项参数就好办了,下面就让我们来进入实战操作吧

配置SSH登录保护

在配置区块中找到SSH servers字样的配置片段,然后默认配置就如下图所示,可以看到这个已经是配置好了,我们只需要在前面加一个enabled = true标记这个配置片段已经启用就行了。

image-20220710205210058

如果你需要为SSH服务器设定特别的封禁规则,那么你可以将上面的三个配置项写入到这个[sshd]区块中。

例如我需要规定:在1分钟内,将ssh登录失败次数超过3次的IP封禁24小时,那么sshd区块的配置文件应该如下所示

[sshd]
# 启用封禁规则
enabled = true
# 这里ssh就等价于你的ssh端口了,不用再特意把端口号写上去了
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

#自定义封禁规则
# 封禁时间
bantime  = 24h
# 在多长时间内
findtime  = 1m
# 最大失败次数
maxretry = 3
# 封禁动作,拉入IP黑名单,禁止该IP访问SSH端口
banaction = iptables-multiport

保存并退出后就可以启动fail2ban服务了,命令如下

sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo systemctl status fail2ban

看到提示running就OK了

image-20220710205943557

如果我们在启动后又修改了配置文件的话,可以使用重载命令来使配置文件生效:

#重启服务(推荐)
systemctl restart fail2ban
#重载配置
systemctl reload fail2ban

下面就赶紧来试一试这个有没有效果吧

image-20220710214811249

可以看到我在另一台机器上试了一两次密码就直接被拉黑了,提示Connection refused

接着我们可以来检查一下装了fail2ban的服务器的封禁列表,使用fail2ban-client status [监狱名称]来查看封禁列表

[root@server ~]# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	1
|  |- Total failed:	4
|  `- Journal matches:	_SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned:	1
   |- Total banned:	1
   `- Banned IP list:	82.116.189.56

可以看到已经将这台机器的IP拉黑了。

那么如何解封这个IP呢?

解封命令是fail2ban-client set [监狱名称] unbanip [封禁IP]

例如:

fail2ban-client set sshd unbanip 82.116.189.56

这行命令就可以解封在sshd监狱中的这个IP

配置Nginx保护

首先创建一个Nginx错误日志过滤器

vim /etc/fail2ban/filter.d/nginx-bansniffer.conf

在里面写入

#fail2Ban configuration file
#
# supports: ngx_http_limit_req_module module

[Definition]

failregex = limiting requests, excess:.* by zone.*client: <HOST>

# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

注意:上述过滤器需要配合Nginx配置模块使用,具体看这篇文章:

然后创建一个监狱模块

[http-get-dos]
enabled = true
port = http,https
filter = nginx-bansniffer
#logpath填写你的NginxServer的错误日志路径
logpath = /root/nginx/logs/www.hash070.top.error.log
#一般认为在120秒内触发120次Nginx过载保护的是一种比较罕见的行为
maxretry = 120
findtime = 120
#封个3600小时不过分吧(手动狗头,一般封个5分钟就差不多得了
bantime = 3600h
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]

注:这里的Nginx错误日志指的是Nginx Server块中error_log的输出文件,例如

error_log  /root/nginx/logs/www.hash070.top.error.log;

修改完后不要忘了重启Fail2Ban服务

systemctl restart fail2ban

效果:

image-20220710224047757

查看已封禁IP和解封方法

fail2ban-client status http-get-dos
fail2ban-client set http-get-dos unbanip 8.8.8.8

Q.E.D.