通过 SSH 连接到服务器非常安全,但是 SSH 守护进程本身必须暴露给互联网才能正常工作。这很容易成功潜在攻击者的目标。以这种方式暴露给网络的任何服务都是攻击者的潜在目标。如果我们注意过这些服务的日志,就会经常看到重复的登录尝试,这就意味着该服务遭受了暴力破解攻击。WordPress 因为广泛使用也每天都遭受着这样的攻击。
Linux 系统中有一个叫 Fail2ban 的服务,可以通过分析应用程序日志识别暴力破解行为,然后自动修改 iptables 防火墙规则来屏蔽掉攻击者 的 IP 地址。这个过程是自动的,配置好Fail2ban 服务后,我们就不需要人工干预了。在这篇文章中,我将介绍如何在 CentOS 7 服务器上安装和使用Fail2ban。
在CentOS 7上安装Fail2ban
官方 CentOS 组件库中没有包含 Fail2ban 软件,它被打包在了EPEL项目中(EPEL代表额外的企业版 Linux 软件包),我们需要先启用 EPEl 仓库。
sudo yum install epel-release
现在,我们应该可以安装fail2ban包了
sudo yum install fail2ban
安装完成后,我们需要使用systemctl启用fail2ban服务:
sudo systemctl enable fail2ban
自定义 Fail2ban 设置
Fail2ban 的配置文件在/etc/fail2ban目录。在这里,我们可以找到一个名为 jail.conf 的Fail2ban 配置文件。此文件可能会被软件包升级覆盖,所以我们不应该直接编辑,我们可以编写一个名为新文件 jail.local 的自定义配置文件,该文件中定义的任何值将覆 jail.conf 中的设置。
jail.conf 包含了 [DEFAULT] 配置,随后是各个服务的配置。 jail.local 可以覆盖这些值中的任何值。另外,文件夹 /etc/fail2ban/jail.d/ 中的服务相关设置又可以覆盖这两个文件中的设置,这些文件的优先级如下:
/etc/fail2ban/jail.conf
/etc/fail2ban/jail.d/*.conf,按字母顺序排列
/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*.local,按字母顺序排列
任何文件可以包含一个 [DEFAULT] 配置,首先执行,也可以包含各个服务的配置。
首先,让我们编写一个非常简单的 jail.local。使用 vi 编辑器打开一个新文件:
sudo vi /etc/fail2ban/jail.local
粘贴以下内容:
[DEFAULT]
# Ban hosts for one hour:
bantime = 3600
# Override /etc/fail2ban/jail.d/00-firewalld.conf:
banaction = iptables-multiport
[sshd]
enabled = true
上面的配置覆盖了三种设置:为所有服务设置了一个新的屏蔽时间,设置使用 iptables 进行屏蔽操作,并启用了sshd 屏蔽,修改完成后,我们需要重启以便使 Fail2ban 生效:
sudo systemctl restart fail2ban
该命令完成后应该没有任何输出。
Fail2ban 其他可用设置
我们可能还需要调整 Fail2bam 的其他设置。打开 jail.conf,我们将讨论一些默认设置。如果需要改变这些值,一定要复制到 jail.local 配置文件里面调整,而不是直接在默认文件里面修改。
sudo vi /etc/fail2ban/jail.conf
Jail 的所有默认设置
首先是 [DEFAULT] 部分。
ignoreip = 127.0.0.1/8
该参数可以让 Fail2ban 忽略来自某些 IP 的流量。目前,它被配置为不禁止来自本机的任何流量。我们可以附加更多 IP(以空格分隔)来忽略其他地址。
bantime = 600
bantime 参数设置了某IP被屏蔽的时间,以秒为单位,默认为600秒,也就是10分钟。
findtime = 600
maxretry = 3
接下来要注意的两个参数是 findtime 和maxretry。这两个参数共同确定了某IP应该被屏蔽的条件。
maxretry 变量设置一个 IP 在 findtime 内,被屏蔽之前可以尝试的次数。默认情况下,Fail2ban 将禁止在10分钟内 3 次登录失败的 IP。
destemail = root@localhost
sendername = Fail2Ban
mta = sendmail
如果要配置电子邮件警报,我们可能需要重写 destemail,sendername 和 mta 设置。destemail 参数设置了接收禁止消息的电子邮件地址。sendername 为邮件“发件人”字段的值。mta 参数设置了使用什么邮件服务来发送邮件。
action = $(action_)s
此参数设置了当 Fail2ban 想要屏蔽 IP 时采取的操作。默认操作是配置防火墙以拒绝来自符合屏蔽条件的流量,直到屏蔽时间过去。
其他 Jail 设置
在 [DEFAULT] 之后,是各个服务的 jail 设置,通常包括一个 port 和需要监控的日志路径 logpath。例如,我们启用了 SSH 监控,jail.local 中会有如下设置:
[sshd]
port = ssh
logpath = %(sshd_log)s
这种情况下,ssh 是一个标准 SSH 端口的预定义变量,%(sshd_log)s 使用 fail2ban 标准配置处定义的值(方便 jail.conf 在不同操作系统中移植)。
在有些监控服务中,可能需要单独设置一个 filter,用来确定验证失败的规则,该 filter 值位于 /etc/fail2ban/filter.d 目录,此文件包含一个正则表达式,用于确定日志中的行是否符合屏蔽条件。后面将要介绍的 WordPress 监控设置就需要新建一个 filter 文件。
我们可以通过列出该目录中的文件来查看可用的过滤器:
ls /etc/fail2ban/filter.d
如果我们看到一个与正在使用的服务相关的文件,大多数情况下该过滤规则是可以直接使用的,例如,我们正在使用 Nginx,我们可以在我们的 /etc/fail2ban/jail.local 文件中设置 [nginx-http-auth]:
[DEFAULT]
# Ban hosts for one hour:
bantime = 3600
# Override /etc/fail2ban/jail.d/00-firewalld.conf:
banaction = iptables-multiport
[sshd]
enabled = true
[nginx-http-auth]
enabled = true
重新启动fail2ban服务:
sudo systemctl restart fail2ban
查看 Fail2ban 状态和防火墙设置
设置了 Fail2ban后,我们需要知道 Fail2ban 是否按预期工作的,通过启动 fail2ban-client 检查整体服务状态或个别监控服务的状态:
sudo fail2ban-client status
sudo fail2ban-client status jail_name
也可以列出为 iptables 当前生效的规则来查看通过 Fail2ban 屏蔽的 ip:
sudo iptables -L
使用 Fail2ban 防止 WordPress 暴力破解
如果我们的 WordPress 站点设置了访问日志,我们就可以让 Fail2ban 监控网站日志,来防止 WordPress 暴力破解,凡是不停发送 POST 的请求到 wp-login.php 的请求,一般情况下都是暴力破解的行为。根据这个特征,我们可以设置下面的 filter,命名为wordpress.conf,放在/etc/fail2ban/filter.d/文件夹中。
# WP brute force attacks filter
[Definition]
failregex =.*-.*-.*POST.*/wp-login$
ignoreregex =
然后在 jail.local 文件中,加入以下内容,其中的 logpath 就是网站的访问日志路径。
[wordpress]
enabled = true
filter = wordpress
logpath = /home/wwwlogs/*.log
maxretry = 3
port = http,https
Centos 7 使用了 firewalld 替代了 iptables,fail2ban 可能无法更新 iptables 规则,这种情况下,使用下面两条命令禁用 firewalld 防火墙,然后启用 iptables 就可以了。
systemctl stop firewalld
systemctl mask firewalld
通过上面的设置,服务器就可以防止大部分的暴力破解攻击了,在安全性上又提升了一个级别。即便如此,我们依然不能忘记安全的基本规则,不要设置过于简单的密码,谨慎保存自己的密码,防止泄露。安全不仅是一种状态,更是一种习惯,养成了注意网络安全的习惯,安全就会一直保持下去。