如何使用 fail2ban 防御 SSH 服务器的暴力破解攻击

对于SSH服务的常见的攻击就是暴力破解攻击——远程攻击者通过不同的密码来无限次地进行登录尝试。当然SSH可以设置使用非密码验证验证方式来对抗这种攻击,例如公钥验证或者双重验证。将不同的验证方法的优劣处先放在一边,如果我们必须使用密码验证方式怎么办?你是如何保护你的 SSH 服务器免遭暴力破解攻击的呢?

未分类

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

在这篇指导教程中,我会演示如何安装并配置 fail2ban 来保护 SSH 服务器以避免来自远程IP地址的暴力攻击。

在linux上安装Fail2ban

为了在CentOS 或 RHEL上安装fail2ban,首先设置EPEL仓库,然后运行以下命令。

$ sudo yum install fail2ban

在Fedora上安装fail2ban,简单地运行以下命令:

$ sudo yum install fail2ban

在ubuntu,Debian 或 Linux Mint上安装fail2ban:

$ sudo apt-get install fail2ban

为SSH服务器配置Fail2ban

现在你已经准备好了通过配置 fail2ban 来加强你的SSH服务器。你需要编辑其配置文件 /etc/fail2ban/jail.conf。 在配置文件的“[DEFAULT]”区,你可以在此定义所有受监控的服务的默认参数,另外在特定服务的配置部分,你可以为每个服务(例如SSH,Apache等)设置特定的配置来覆盖默认的参数配置。

在针对服务的监狱区(在[DEFAULT]区后面的地方),你需要定义一个[ssh-iptables]区,这里用来定义SSH相关的监狱配置。真正的禁止IP地址的操作是通过iptables完成的。

下面是一个包含“ssh-iptables”监狱配置的/etc/fail2ban/jail.conf的文件样例。当然根据你的需要,你也可以指定其他的应用监狱。

$ sudo vi /etc/fail2ban/jail.local
[DEFAULT]
# 以空格分隔的列表,可以是 IP 地址、CIDR 前缀或者 DNS 主机名
# 用于指定哪些地址可以忽略 fail2ban 防御
ignoreip = 127.0.0.1 172.31.0.0/24 10.10.0.0/24 192.168.0.0/24

# 客户端主机被禁止的时长(秒)
bantime = 86400

# 客户端主机被禁止前允许失败的次数 
maxretry = 5

# 查找失败次数的时长(秒)
findtime = 600

mta = sendmail

[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=your@email.com, sender=fail2ban@email.com]
# Debian 系的发行版 
logpath = /var/log/auth.log
# Red Hat 系的发行版
logpath = /var/log/secure
# ssh 服务的最大尝试次数 
maxretry = 3

根据上述配置,fail2ban会自动禁止在最近10分钟内有超过3次访问尝试失败的任意IP地址。一旦被禁,这个IP地址将会在24小时内一直被禁止访问 SSH 服务。这个事件也会通过sendemail发送邮件通知。

一旦配置文件准备就绪,按照以下方式重启fail2ban服务。

在 Debian, Ubuntu 或 CentOS/RHEL 6:

$ sudo service fail2ban restart

在 Fedora 或 CentOS/RHEL 7:

$ sudo systemctl restart fail2ban

为了验证fail2ban成功运行,使用参数’ping’来运行fail2ban-client 命令。 如果fail2ban服务正常运行,你可以看到“pong(嘭)”作为响应。

$ sudo fail2ban-client ping
Server replied: pong

测试 fail2ban 保护SSH免遭暴力破解攻击

为了测试fail2ban是否能正常工作,尝试通过使用错误的密码来用SSH连接到服务器模拟一个暴力破解攻击。与此同时,监控 /var/log/fail2ban.log,该文件记录在fail2ban中发生的任何敏感事件。

$ sudo tail -f /var/log/fail2ban.log

未分类

根据上述的日志文件,Fail2ban通过检测IP地址的多次失败登录尝试,禁止了一个IP地址192.168.1.8。

检查fail2ban状态并解禁被锁住的IP地址

由于fail2ban的“ssh-iptables”监狱使用iptables来阻塞问题IP地址,你可以通过以下方式来检测当前iptables来验证禁止规则。

$ sudo iptables --list -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-SSH (1 references)
target     prot opt source               destination
DROP       all  --  192.168.1.8          0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

如果你想要从fail2ban中解锁某个IP地址,你可以使用iptables命令:

$ sudo iptables -D fail2ban-SSH -s 192.168.1.8 -j DROP

当然你可以使用上述的iptables命令手动地检验和管理fail2ban的IP阻塞列表,但实际上有一个适当的方法就是使用fail2ban-client命令行工具。这个命令不仅允许你对”ssh-iptables”监狱进行管理,同时也是一个标准的命令行接口,可以管理其他类型的fail2ban监狱。

为了检验fail2ban状态(会显示出当前活动的监狱列表):

$ sudo fail2ban-client status

为了检验一个特定监狱的状态(例如ssh-iptables):

$ sudo fail2ban-client status ssh-iptables

上面的命令会显示出被禁止IP地址列表。

未分类

为了解锁特定的IP地址:

$ sudo fail2ban-client set ssh-iptables unbanip 192.168.1.8

未分类

注意,如果你停止了Fail2ban 服务,那么所有的IP地址都会被解锁。当你重启 Fail2ban,它会从/etc/log/secure(或 /var/log/auth.log)中找到异常的IP地址列表,如果这些异常地址的发生时间仍然在禁止时间内,那么Fail2ban会重新将这些IP地址禁止。

设置 Fail2ban 自动启动

一旦你成功地测试了fail2ban之后,最后一个步骤就是在你的服务器上让其在开机时自动启动。在基于Debian的发行版中,fail2ban已经默认让自动启动生效。在基于Red-Hat的发行版中,按照下面的方式让自动启动生效。

在 CentOS/RHEL 6中:

$ sudo chkconfig fail2ban on

在 Fedora 或 CentOS/RHEL 7:

$ sudo systemctl enable fail2ban

总结

在该教程中,我演示了如何安装并配置fail2ban来保护一个SSH服务器。当然fail2ban可以缓解暴力密码攻击,但是请注意,这并不能保护SSH服务器避免来自复杂的分布式暴力破解组织,这些攻击者通过使用成千上万个机器控制的IP地址来绕过fail2ban的防御机制。

CentOS 7安装fail2ban+Firewalld防止SSH爆破与CC攻击

说明:差不多很多博主都会遇到被CC攻击和SSH爆破的情况,这个时候就需要做下防御措施了,前几天发过一个防CC脚本,参考: https://www.moerats.com/archives/484/ ,不过对于CentOS 7来说,由于防火墙的因素,配置起来还是有点麻烦的,这里争对CentOS 7再分享个简单防CC攻击和SSH爆破的方法。

前言

fail2ban可以监视你的系统日志,然后匹配日志的错误信息执行相应的屏蔽动作。网上大部分教程都是关于fail2ban+iptables组合,考虑到CentOS 7已经自带Firewalld,所以这里我们也可以利用fail2ban+Firewalld来防CC攻击和SSH爆破。

本教程编辑文件使用vi命令,如果不会用的,可以使用比较简单的nano,可以参考: https://www.moerats.com/archives/485/ ,或者使用FTP工具,如WinSCP登录VPS操作。

准备工作

1、检查Firewalld是否启用

#如果您已经安装iptables建议先关闭
service iptables stop
#查看Firewalld状态
firewall-cmd --state
#启动firewalld
systemctl start firewalld
#设置开机启动
systemctl enable firewalld.service

启用Firewalld后会禁止所有端口连接,因此请务必放行常用的端口,以免被阻挡在外,以下是放行SSH端口(22)示例,供参考:

#放行22端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
#重载配置
firewall-cmd --reload
#查看已放行端口
firewall-cmd --zone=public --list-ports

2、安装fail2ban

fail2ban可以监控系统日志,并且根据一定规则匹配异常IP后使用Firewalld将其屏蔽,尤其是针对一些爆破/扫描等非常有效。

#CentOS内置源并未包含fail2ban,需要先安装epel源
yum -y install epel-release
#安装fial2ban
yum -y install fail2ban

安装成功后fail2ban配置文件位于/etc/fail2ban,其中jail.conf为主配置文件,相关的匹配规则位于filter.d目录,其它目录/文件一般很少用到,如果需要详细了解可自行搜索。

3、配置规则

新建jail.local来覆盖fail2ban的一些默认规则:

#新建配置
vi /etc/fail2ban/jail.local
#默认配置
[DEFAULT]
ignoreip = 127.0.0.1/8
bantime  = 86400
findtime = 600
maxretry = 5
#这里banaction必须用firewallcmd-ipset,这是fiewalll支持的关键,如果是用Iptables请不要这样填写
banaction = firewallcmd-ipset
action = %(action_mwl)s

参数说明:

ignoreip:IP白名单,白名单中的IP不会屏蔽,可填写多个以(,)分隔
bantime:屏蔽时间,单位为秒(s)
findtime:时间范围
maxretry:最大次数
banaction:屏蔽IP所使用的方法,上面使用firewalld屏蔽端口

防止SSH爆破

如果您还在使用默认SSH端口(22),可能每天都会被扫描,我们可以修改端口尽量避免被扫,参考: https://www.moerats.com/archives/394/ ,或者可以使用fail2ban将恶意IP屏蔽。

继续修改jail.local这个配置文件,在后面追加如下内容:

[sshd]
enabled = true
filter  = sshd
port    = 22
action = %(action_mwl)s
logpath = /var/log/secure

参数说明:

[sshd]:名称,可以随便填写
filter:规则名称,必须填写位于filter.d目录里面的规则,sshd是fail2ban内置规则
port:对应的端口
action:采取的行动
logpath:需要监视的日志路径

到这一步,我们jail.local的规则看起来可能像下面这样子:

[DEFAULT]
ignoreip = 127.0.0.1/8
bantime  = 86400
findtime = 600
maxretry = 5
banaction = firewallcmd-ipset
action = %(action_mwl)s

[sshd]
enabled = true
filter  = sshd
port    = 22
action = %(action_mwl)s
logpath = /var/log/secure

上面的配置意思是如果同一个IP,在10分钟内,如果连续超过5次错误,则使用Firewalld将他IP ban了。输入systemctl start fail2ban启动fail2ban来试试效果。

使用另一台服务器不断尝试连接SSH,并且不断的将密码输入错误,你会发现连续超过5次后直接连不上,说明IP被ban了,可以输入:fail2ban-client status sshd查看被ban的IP,如下截图。

未分类

防止CC攻击

这里仅以Nginx为例,使用fail2ban来监视nginx日志,匹配短时间内频繁请求的IP,并使用firewalld将其IP屏蔽,达到CC防护的作用。

#需要先新建一个nginx日志匹配规则
vi /etc/fail2ban/filter.d/nginx-cc.conf
#填写如下内容
[Definition]
failregex =  -.*- .*HTTP/1.* .* .*$
ignoreregex =

继续修改jail.local追加如下内容:

[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
action = %(action_mwl)s
maxretry = 20
findtime = 60
bantime = 3600
logpath = /usr/local/nginx/logs/access.log

上面的配置意思是如果在60s内,同一IP达到20次请求,则将其IP ban 1小时,上面只是为了测试,请根据自己的实际情况修改。logpath为nginx日志路径。

防止Wordpress爆破

如果您经常分析日志会发现有大量机器人在扫描wordpress登录页面wp-login.php,虽然对方可能没成功,但是为了避免万一还是将他IP干掉为好。

#需要先新建一个nginx日志匹配规则
vi /etc/fail2ban/filter.d/wordpress.conf
#填写如下内容
[Definition]
failregex = ^ -.* /wp-login.php.* HTTP/1.."
ignoreregex =

继续修改jail.local追加如下内容:

[wordpress]
enabled = true
port = http,https
filter = wordpress
action = %(action_mwl)s
maxretry = 20
findtime = 60
bantime = 3600
logpath = /usr/local/nginx/logs/access.log

当然,别忘记输入systemctl restart fail2ban重启fail2ban使其生效。

常用命令

#启动
systemctl start fail2ban
#停止
systemctl stop fail2ban
#开机启动
systemctl enable fail2ban
#查看被ban IP,其中sshd为名称,比如上面的[wordpress]
fail2ban-client status sshd
#删除被ban IP
fail2ban-client set sshd delignoreip 192.168.111.111
#查看日志
tail /var/log/fail2ban.log

总结

fail2ban已经内置很多匹配规则,位于filter.d目录下,包含了常见的SSH/FTP/Nginx/Apache等日志匹配,如果都还无法满足您的需求,您也可以自行新建规则来匹配异常IP。使用fail2ban+Firewalld来阻止恶意IP是行之有效的办法,可极大提高服务器安全。

提示:搬瓦工年付$18可换CN2机房的套餐已补货,7机房随意切换,支持支付宝,优惠码:BWH1ZBPVK,购买: https://bwh1.net/cart.php?a=confproduct&i=0

Fail2ban防止WordPress受到xmlrpc.php CC攻击

WordPress本身是一个非常强大的CMS(内容管理系统),功能强大。但是也正是因为其强大的特性,使其很容易被利用,造成服务器的不稳定甚至崩溃。最容易遭受攻击的就是xmlrpc.php这个文件,攻击者只要每秒发送1个post请求到此文件,不出1分钟,一台512M内存Debian7系统的VPS就会崩溃,php进程和Mysql占用内存过高而导致无法访问。在尝试了网上流传的多个防攻击手段之后,fail2ban是效果最好的一个,下面就简单记录一下过程,供大家参考。

分析日志

在服务器出现异常的时候,首先去分析Nginx日志, /var/log/nginx/access.log ,从代码中可以发现如下可以IP不断发送Post请求到xmlrpc.php,每个IP的发送频率大概在2秒钟一次,严格来说频率并不高但足以让php和mysql进程崩溃。

185.188.204.16 - - [15/Jul/2017:23:51:07 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.6 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.8 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.14 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.16 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.7 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.12 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.11 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.15 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.11 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"

安装fail2ban和iptables

安装fail2ban和iptables,这样能使用ipotables对攻击进行防御,想对于其它js和php的防御方式自动化更高,更为高效。

apt-get install fail2ban iptables

设置fail2ban jail.local

使用jail.local设定

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
vi /etc/fail2ban/jail.local
[xmlrpc]
enabled = true
filter = xmlrpc
action = iptables[name=xmlrpc, port=http, protocol=tcp]
logpath = /var/log/nginx/access.log
bantime = 43600
maxretry = 2

设置fail2ban 自定义filter

vi /etc/fail2ban/filter.d/xmlrpc.conf
[Definition]
failregex = ^<HOST> .*POST .*xmlrpc.php.*
ignoreregex =

设置fail2ban jail.local

设置好之后重启fail2ban服务既可生效

service fail2ban restart

查看fail2ban日志查看防御情况

tail -f /var/log/fail2ban.log
2017-07-15 23:51:38,265 fail2ban.jail   : INFO   Creating new jail 'ssh'
2017-07-15 23:51:38,266 fail2ban.jail   : INFO   Jail 'ssh' uses Gamin
2017-07-15 23:51:38,287 fail2ban.filter : INFO   Set maxRetry = 6
2017-07-15 23:51:38,288 fail2ban.filter : INFO   Set findtime = 600
2017-07-15 23:51:38,288 fail2ban.actions: INFO   Set banTime = 600
2017-07-15 23:51:38,320 fail2ban.jail   : INFO   Creating new jail 'xmlrpc'
2017-07-15 23:51:38,320 fail2ban.jail   : INFO   Jail 'xmlrpc' uses Gamin
2017-07-15 23:51:38,321 fail2ban.filter : INFO   Added logfile = /var/log/nginx/access.log
2017-07-15 23:51:38,322 fail2ban.filter : INFO   Set maxRetry = 2
2017-07-15 23:51:38,323 fail2ban.filter : INFO   Set findtime = 600
2017-07-15 23:51:38,323 fail2ban.actions: INFO   Set banTime = 43600
2017-07-15 23:51:38,328 fail2ban.jail   : INFO   Jail 'ssh' started
2017-07-15 23:51:38,329 fail2ban.jail   : INFO   Jail 'xmlrpc' started
# 以上日志显示自定义的xmlrpc filter已经生效
2017-07-15 23:51:45,350 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.8
2017-07-15 23:51:45,361 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.9
2017-07-15 23:51:45,368 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.6
2017-07-15 23:51:45,376 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.7
2017-07-15 23:51:45,382 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.16
2017-07-15 23:51:45,387 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.14
2017-07-15 23:51:45,392 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.15
2017-07-15 23:51:45,400 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.12
2017-07-15 23:51:45,415 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.10
2017-07-15 23:51:45,426 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.11
# 以上日志则显示成功防御对xmlrpc进行攻击的IP等情况

参考链接:https://rbgeek.wordpress.com/2014/09/11/block-wordpress-xmlprc-php-ddos-attacks-using-fail2ban/

WordPress插件:https://wordpress.org/plugins/wp-fail2ban/

Related posts:

  1. WordPress 启用HTTPS设置
  2. Wp Super Cache + Nginx规则
  3. Akismet:强大的反垃圾评论插件
  4. 浅谈博客的友情链接与链接
  5. WordPress移除静态资源版本号

WARNING: Unable to find a corresponding IP address for xxx

在之前开始使用fail2ban防止vsftpd或ssh暴力破解之后,有一定的效果,但在查看fail2ban.log日志时,发现一个问题:

  1. fail2ban.filter : WARNING Unable to find a corresponding IP address for ns.rs996.com

我们再查看secure日志:

  1. vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=devops.webres.wang rhost=ns.rs996.com

fail2ban是根据rhost取得客户端的ip,并使用iptables禁止它,但我们发现ns.rs996.com无法解析出ip地址,那它的ip去哪了呢?
经过分析得出结论:vsftpd默认对客户端ip进行反向解析,如果查询有结果,则把ip解析出来的域名记录secure日志中的rhost中,但是此反向解析出来的域名,本身又没有作A记录的解析,所以fail2ban再进行此域名的解析时,当然就无法获取到IP地址,也就无法禁止此客户端的暴力破解行为。
解决方法:
在vsftpd.conf中添加下面的代码禁止反向解析:

  1. reverse_lookup_enable=NO

之后重启vsftpd即可。生效之后不仅解决了这个问题,也使得登录vsftpd不再停顿几秒了。
但是/var/log/secure里记录ftp登录失败有一个缺点,就是用相同的用户名,不同的密码登录多次,只是记录首次失败的信息,而之后的就只显示:last message repeated x times这样的信息,无法满足登录失败三次的条件,所以就不能阻止此暴力破解,下面是解决这个问题的方法:
1、打开vsftpd.conf,添加如下代码:

  1. dual_log_enable=YES
  2. use_localtime=YES

2、打开/etc/fail2ban/jail.local,修改以下内容:

  1. [vsftpd-iptables]
  2. logpath = /var/log/vsftpd.log