Fail2ban 是一个多功能的安全工具。 虽然它主要用于防止对 SSH 的暴力攻击,但它也可以用于保护其他服务。
有一些机器人会四处扫描互联网并向 Web 服务器发送数千个请求,以期找到漏洞。 这篇文章讨论了如何使用 Fail2ban 阻止此类机器人。
我们假设您正在使用 Apache 作为网络服务器。 但是,这些说明可以很容易地针对 nginx 或任何其他 Web 服务器进行调整。
但是,您应该记住,Fail2ban 不是 Web 应用程序防火墙 (WAF),并且无法抵御传入的恶意请求。 这是因为fail2ban 通过监控日志来采取行动; 因此,在 Fail2ban 采取行动之前,必须至少记录一次恶意尝试。
什么是坏机器人?
在这篇文章中,我们将专注于阻止执行以下操作之一的机器人:
当然,您也可以阻止其他类型的攻击。 但是,我们将在本文中仅限于上述三种情况。
安装 Fail2ban
Fail2ban 在大多数发行版的存储库中可用。
要在 Debian/Ubuntu 上安装它,请运行以下命令:
sudo apt-get update sudo apt-get install fail2ban
在 CentOS 上,您应该首先启用 EPEL 存储库; 然后,您应该启用并启动它。
sudo yum -y install epel-release sudo yum -y install fail2ban sudo systemctl enable fail2ban sudo systemctl start fail2ban
Fail2ban 基础知识
Fail2ban 工作机制的核心是一组监狱。 简而言之,jail 告诉Fail2ban 查看一组日志,并在每次日志更改时对其应用过滤器。 如果过滤器的匹配数等于jail 允许的最大匹配数,则执行jail 中指定的操作。
因此,您需要定义两件事:过滤器和监狱。 将监狱配置为查看 Apache的日志来检测恶意请求。
定义过滤器
过滤器只是与日志匹配的 Python 正则表达式的集合。 在这里,我们需要为我们上面描述的标准定义过滤器。
但首先,让我们看一下 Apache 日志:
66.249.79.189 - - [17/Jan/2017:14:10:41 +0000] "GET /robots.txt HTTP/1.1" 200 3494 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http: //www.google.com/bot.html)"
注意请求头 GET /robots.txt HTTP/1.1
用双引号括起来。 在自己设计此类规则时,您应该足够小心以确保只有请求标头匹配。 否则,您可能会阻止合法用户。
SQL 注入负载通常包含以下形式的字符串 union select(...)
或者 select concat (...)
. 因此,您可以尝试将此模式与以下正则表达式匹配:
(?i)^<HOST> -.*"[^"]+(?:union[^"]+select[^"]*|select[^"]+concat[^"]*)(?:%%2[8C]|[,(])
这 <HOST>
部分定义了 IP 地址在日志条目中的位置,以及 (?i)
声明正则表达式不区分大小写。
这 [^"]
在正则表达式中确保匹配的文本用双引号括起来。 这有助于确保正则表达式只匹配请求标头而不匹配其他任何东西。 这 (?:%%2[8C]|[,(])
指定 union select
或者 select concat
匹配后跟一个逗号(,
) 或括号 ((
),直接或在他们的 百分比编码形式.
扫描开放代理的机器人通常会发送以下形式的请求:
101.33.59.9 - - [17/Jan/2017:14:10:41 +0000] "GET https://google.com/ HTTP/1.1" 400 3494 "-" "Mozilla" 101.33.59.9 - - [17/Jan/2017:14:10:44 +0000] "CONNECT yahoo.com:80" 400 3499 "-" "Mozilla"
像下面这样的正则表达式可以很容易地匹配这些:
(?i)^<HOST> -.*"(?:(?:GET|POST|HEAD) https?:|CONNECT [a-z0-9.-]+:[0-9]+)
正则表达式 (?:(?:GET|POST|HEAD) https?:
匹配第一种类型的请求,而正则表达式 CONNECT [a-z0-9.-]+:[0-9]+
匹配第二种类型的请求。
扫描 Shellshock 的机器人通常会发出如下请求:
10.11.12.13 - - [17/Jan/2016:16:00:00 +0000] "GET /cgi-bin/printenv.cgi HTTP/1.0" 200 1 "-" "() { test;};echo "Content-type: text/plain"; echo; echo; /bin/rm -rf /var/www/"
像这样的正则表达式将匹配 Shellshock 的模式:
<HOST> -.*"()s*{[^;"]+[^}"]+}s*;
在这里,我们正在检查 () { <command>; }
模式,以及 s
考虑可能存在于恶意请求中的空格。
结合它们,我们现在可以编写我们的过滤器:
[Definition] failregex = <HOST> -.*"()s*{[^;"]+[^}"]+}s*; (?i)^<HOST> -.*"[^"]+(?:union[^"]+select[^"]*|select[^"]+concat[^"]*)(?:%%2[8C]|[,(]) (?i)^<HOST> -.*"(?:(?:GET|POST|HEAD) https?:|CONNECT [a-z0-9.-]+:[0-9]+) ignoreregex =
这 ignoreregex
允许您将条目列入白名单。 您可以添加忽略的正则表达式,就像对 failregex 所做的那样。
Save 上面的过滤器变成 /etc/fail2ban/filter.d/badbot.local
定义监狱
定义了过滤器后,现在是定义监狱的时候了。 在这里,如果 IP 地址在六分钟内发送三个此类请求,我们将阻止该 IP 地址六分钟。
将此添加到您的 /etc/fail2ban/jail.local
文件:
[badbot] enabled = true port = http,https filter = badbot logpath = /var/log/apache*/*access.log maxretry = 3 banaction = iptables-multiport findtime = 360 bantime = 360
配置jail 后,您应该重新启动fail2ban 以使这些更改生效。 根据您的发行版,需要以下命令之一来重新启动它:
sudo systemctl restart fail2ban sudo service fail2ban restart
fail2ban 现在将阻止恶意机器人尝试攻击您的 Web 服务器的所有尝试。 您还可以将这些规则扩展到您的另一台 Web 服务器,或您可能会看到的其他类型的攻击。