fail2ban 拯救你的线上服务

近把 overture 搬上了阿里云。我用了一台学生机小水管来充当我全部设备的 DNS(当然本地也有相应的缓存来提速本地网络)。今天起床以后,发现一个简单的 baidu 要超过 10s 才能加载成功,并且部分网页元素 404. 经过一段时间的排错,找到了导致网络不稳定的罪魁祸首:DNS 被人打了。

Under attack

从日志里可以看到,有一个 IP 一直在请求 pizzaseo.com。于是果断 ban 掉。刚刚爽了不到半天,家里的网络又开始卡顿了。SSH 上去以后,发现换了一个 IP 大量请求 pizzaseo.com。和攻击者躲猫猫了一段时间,感觉生命被浪费了,于是 google 搜了搜,果然有人出现了和我类似的情况。评论区里也有一位大佬遇到了同样的情况。

继续 google“如何防御 DDOS”,大佬们异口同声推荐 fail2ban。遂试用之。

fail2ban 原理

简单的解释下 fail2ban 的原理。它是通过分析日志文件,对于频繁访问的 IP 使用 iptables 自动屏蔽。考虑到这次的 DDOS 并没有打满我的本地带宽,只是担心 overture 日志增长速度过快把我的 20G 小盘塞满,fail2ban 可以完美满足我的需求。

fail2ban 配置

正则表达式

通过官方文档,发现我的 DNS 服务器没有被官方支持,需要手写正则表达式来过滤日志。fail2ban 的正则并不需要完美匹配,它的匹配是分成两部分来做的。对于日志里的一行数据,fail2ban 首先使用自己的过滤器把时间戳过滤出来。然后再通过自定义的正则来过滤日志正文。举个例子:

time="2020-05-12 22:02:08" 1.2.4.8

对于上述日志,直接使用 <HOST> 来过滤可得:

1
fail2ban-regex '"2020-05-12 22:02:08" 1.2.4.8' '<HOST>'

fail2ban-regex

可以看到,已经可以匹配到了,并不需要在正则里写时间戳相关的内容。

针对一条真正的日志:

time="2020-05-12 22:02:08" level=debug msg="Question from 117.27.239.28: ;pizzaseo.com.\tIN\t RRSIG"

我们可以构建相关正则表达式如下:

1
fail2ban-regex -v /var/log/overture/access.log 'level=debug msg="Question from <HOST>.*pizzaseo'

fail2ban-regex

fail2ban 配置文件

我们自定义 regex 的过滤方式要写两部分配置文件。首先看过滤规则:

# cat /etc/fail2ban/filter.d/overture.conf
[Definition]
failregex = level=debug msg="Question from <HOST>.*pizzaseo
ignoreregex =

这一部分把我们上文写的正则填进去就好了。然后是 jail:

# cat /etc/fail2ban/jail.d/overture.conf
[overture]
enabled = true
logpath = /var/log/overture/access.log
bantime = 10800
maxretry = 2
findtime = 3
protocol = udp
ignoreip = x.x.x.x

这一部分可以配置 ignoreip 白名单,可以把自己常用的 IP。

最后 service fail2ban restart 重启 fail2ban 就好了。

战果

为了编写本文,我短暂的停止了 fail2ban,再次重启的时候 overture 日志刷屏,fail2ban 瞬间封掉了几个 IP:

fail2ban-success

不想自己折腾的同学可以直接用我的 DNS:dns.mhtt1123.cn。

写在最后

有人问为什么不直接把所有 geoip 不在大陆境内的全 ban 掉。这里我有一个考虑,万一在极端网络条件下,有同学挂着全局梯子使用我的 DNS 会被误 ban。另外我也考虑了使用阿里云的安全组功能,但实际上并不起到过滤作用。本文的最后贴上我的安全组配置,大佬们可以帮忙看下:

阿里云安全组配置

updatedupdated2020-05-292020-05-29
加载评论