今天偶然看了下服务器上的日志,结果发现有人在暴力尝试SSH登录:
因为服务器是实验室内部使用,只有校园网才能连接,所以在服务器的安全上就没怎么在意。见此状况,立刻用iptables
禁掉了一些IP,比如说禁掉148.235.57.190:
1 | $ sudo iptables -I INPUT -s 148.235.57.190 -j DROP |
-I
表示插入规则,INPUT
是规则链,-s
指定来源IP,-j
指定要跳转的目标,DROP
表示丢弃数据包。
禁掉之后,过一会儿发现又来一些新的IP地址发起攻击了。考虑到对方可能有不少IP,我总不能像这样手动禁止IP吧。于是,就找到了fail2ban
。
fail2ban
fail2ban
通过监测指定的日志,对日志使用正则表达式匹配,当在一段时间内匹配到指定数量时,就采取相应的动作,一般是配置防火墙、邮件通知等。这个就叫jail。
安装
安装fail2ban
比较简单,直接安装即可。为了实现邮件通知功能,装个mailutils
,这个自带邮件服务器postfix
。
1 | $ sudo apt install fail2ban mailutils |
配置
fail2ban
的配置文件位于/etc/fail2ban,fail2ban.conf是对程序的一些设置,jail.conf是对规则的配置。不过,官方建议不要修改.conf文件,而是使用.local文件。也就是说,应该配置jail.local文件(没有的话新建一个),而不是去修改jail.conf文件。fail2ban
会先读取.conf,再读取.local,因此.local可以覆写与.conf中重复的项,而.local中没有的项就可以使用.conf提供的配置。也可以在jail.d目录下进行配置。
以下是我的/etc/fail2ban/jail.local配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [DEFAULT] # 允许本地环回和内网访问 ignoreip = 127.0.0.1/8 192.168.3.0/24 # 邮件告知谁 destemail = user1@localhost [sshd] enabled = true # 在10小时内重试5次,就禁止30天 maxretry = 5 bantime = 2592000 findtime = 36000 # 禁止并发送邮件 action = %(action_mwl)s |
ignoreip表示忽略哪些IP地址段,可以配置多个IP地址段,用空格隔开。192.168.3.0/24表示192.168.3.0~192.168.3.255这个IP地址段,/24是掩码的一种表示,意思是前24位是网段,也就是子网掩码为255.255.255.0。
destemail是发送邮件的收件人,多个收件人用,
分隔。
maxretry、bantime、findtime表示:在findtime秒内有maxretry次符合规则的日志产生就禁止来源bantime秒。不过,由于处理时延,实际开始处理时可能次数比maxretry多一点。(注意“bantime”别拼写错了)
至于action,默认的动作是iptables-multiport,也就是配置iptables。
jail.conf里预设了一些其它动作,比如禁止并发送邮件等,可以像示例那样使用。也可以使用/etc/fail2ban/action.d中的动作,需要传入相应的参数,可以参考jail.conf里的示例。
filter.d目录是对日志的过滤规则,默认有很多实用的规则。如果要自定义过滤规则,要注意:
- 可以配置多条正则表达式,每行一条,每匹配一条都会使得计数器+1
- 对于日志行,会先自动匹配日期时间,剩下的部分才执行配置的正则表达式匹配,且不要求全部匹配。如果自动匹配日期时间失败,则整行的匹配会失败。并且,自动匹配日期时间的行为无法配置。
命令行
当修改配置文件后,需要重新加载配置文件使其生效:
1 | $ sudo fail2ban-client reload |
重新加载配置文件后,也会重新扫描日志文件,重新执行jail。
查看配置了哪些jail:
1 2 3 4 | $ sudo fail2ban-client status Status |- Number of jail: 1 `- Jail list: sshd |
查看jail的详细信息,只需加上jail名即可,例如查看sshd:
1 2 3 4 5 6 7 8 9 10 | $ sudo fail2ban-client status sshd Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 2 |- Total banned: 2 `- Banned IP list: 186.201.214.162 46.101.103.207 |
为了检查过滤规则是否有效,可以使用fail2ban-regex
:
1 2 3 4 5 6 | # 检查日志行与正则表达式的匹配情况 $ fail2ban-regex '18-07-2008 12:13:01 [1.2.3.4] authentication failed' '\[<HOST>\] authentication failed' # 检查日志与过滤规则的匹配情况 $ fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf # 检查日志与正则表达式的匹配情况 $ fail2ban-regex /var/log/auth.log "Failed [-/\w]+ for .* from <HOST>" |
Results中,Failregex: x total表示有x条日志行匹配(可见发出了很多次攻击),Date template hits表示自动匹配日期时间时命中了哪些格式。
注意事项
当我们更改了时区后,然后日志的时间并没有修改过来,导致两者的时间不一致,这样fail2ban
的工作就失效了。
解决办法:重启日志服务,保证两者的时间一致:
$ sudo systemctl restart rsyslog |
sshd更改端口号后使用fail2ban
需要注意在填写配置的时候也需要更改端口号,否则起不到禁止作用。
如果使用jail.conf中预设的action,设置port即可,否则设置action,传入合适的port参数。
iptables
这里并不打算详细介绍iptables
,毕竟本文的主角是fail2ban
。
启动fail2ban服务后,会自动在iptables里加入f2b-xxx链(xxx是jail名):
1 2 3 4 5 6 7 | $ sudo iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination f2b-sshd tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 22 ... Chain f2b-sshd (1 references) target prot opt source destination |
如果fail2ban误杀了某个IP,可以手动将其移除。例如移除f2b-sshd链中的第1条规则(从1开始):
$ sudo iptables -D f2b-sshd 1 |
参考文献
文章作者: 文剑木然