亚马逊AWS官方博客

保护 EC2 实例的开源工具 – Fail2Ban

前言

关于安全,有一句让我印象深刻的说法叫做 “You Can Never Be Too Careful” ,中文的意思就是“越小心越好”。在云计算的圈子里打磨的久了,对于这一点的认识就更强烈了。

或许我们都有过这样的经验,当我们创建一个 EC2 的实例,并在这个实例上运行 Apache、Nginx 作为 Web 服务器,并通过端口22且使用 SSH 连接到这台实例来进行配置和管理。时间一久,我们就能够在 Linux 的访问日志中看到许多尝试登录的记录。这些来自世界各个角落的访问可能产生于网络嗅探器、网络爬虫,甚至就是恶意的攻击行为。其中的一种攻击行为被称作 “Brute-force attack”(强力攻击),通常是指攻击者尝试所有可能的密码和口令,直到找到正确答案。或者,攻击者可以尝试猜测通常使用密钥派生函数根据密码创建的密钥,这也被称为穷举键搜索

也许我们会认为我的 Linux 主机使用了用户名/密码、EC2 密钥对甚至是安全组等安全措施来加以保护。但是考虑到历史上出现过的 OpenSSL “心脏出血漏洞”,即使现在看来安全的方案也未必万无一失。此外,很多资深的AWS用户还会告诉我,现有的许多服务已经提供了强力的安全保护,例如Amazon GuardDuty 就能够帮助检测和阻止针对EC2 的SSH 强力攻击。但是廉价且简单有效的方法我们永远都不会嫌多的,对吗?

查看登录日志的方法 –

Amazon Linux2 Ubuntu
$ sudo tail /var/log/secure
$ sudo tail /var/log/auth.log

Fail2Ban 是什么?

现在让我们一起来认识一下今天的主角 – Fail2Ban。简单说来,这是一个入侵防御软件的框架,可以保护计算机服务器免受暴力攻击。Fail2Ban 使用 Python 编程语言编写,能够运行在 POSIX 系统上(例如:Linux),并且具有与本地安装的数据包控制系统或防火墙的接口,例如iptables或TCP Wrapper 等。更进一步的解释,Fail2Ban 帮助我们自动化的监视暴力攻击和密码猜测者的攻击,对于在短时间内反复未能通过身份验证,则自动的禁止进行尝试。

Fail2Ban 的背景信息 –

原作者 Cyril Jaquier
主要开发者 Cyril Jaquier, Yaroslav Halchenko, Daniel Black, Steven Hiscocks, Arturo ‘Buanzo’ Busleiman等
第一次发布 2004年
稳定版本 0.11.1
代码库 https://github.com/fail2ban/fail2ban
许可证
GPLv2+
项目主页 https://www.fail2ban.org

Fail2Ban 工作原理

Fail2ban通过扫描日志文件(例如/ var / log / apache / error_log),发现并禁止显示出恶意迹象的IP地址(例如:过多的密码失败、寻找漏洞利用等)。通常,Fail2Ban使用更新防火墙规则的方法在指定的时间内拒绝特定的IP地址,在Linux 操作系统下,Fail2Ban 是通过向iptables 添加规则来强制实施对可疑IP地址的禁止。当然也可以配置任何其他任意操作(例如:发送电子邮件等)。

Fail2Ban具有开箱即用的特性,标准配置附带了Apache、Lighttpd、sshd、vsftpd、qmail、Postfix和Courier邮件服务器的过滤器。过滤器是由Python正则表达式定义的,熟悉正则表达式的开发人员可以方便地对其进行定制。一个过滤器和一个动作的组合被称为“jail”(监狱),是用来阻止恶意访问者对特定网络服务的访问。以及随软件分发的示例,可能会为创建访问日志文件的任何面向网络的过程创建一个“监狱”。考虑到现实的场景中,可能已为本机的防火墙配置了规则。Fail2Ban仅添加和删除其自己的规则-常规的iptables 的规则将保持不变。

技巧:查看 iptables 的现有规则 – sudo iptables -L

Fail2Ban能够减少不正确的/恶意的身份验证尝试的发生率,但是它不能消除弱身份验证带来的安全风险。 如果确实想保护AWS资源,则务必要结合安全的身份认证方法,例如多因子认证(MFA)等。

安装 Fai2Ban

通常情况下,我们使用的Linux 发行版已经提供了Fail2Ban 的安装包。这种情况下,安装就变得非常的简单 –

Amazon Linux 2 Ubuntu

$ sudo yum install -y  https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

$ sudo yam install fail2ban

$ sudo apt-get install fail2ban

注意:在各个不同的Linux 发行版中Fail2Ban 的版本或有不同。在Amazon Linux 2的EPEL 中的版本为v0.10.5,而Ubuntu 20.04 中的版本则为v0.11.1。

配置 Fai2Ban

Fail2Ban安装包中含有一个名为jail.conf的默认配置文件。 升级Fail2Ban时,该文件将被覆盖。因此,如果有定制化的配置,需要在升级前做好备份。

另一种推荐的方法是将jail.conf文件复制到一个名为jail.local的文件中。 我们将定制的的配置更改存入jail.local中。这个文件在升级过程中将保持不变。 Fail2Ban启动时会自动读取这jail.conf与jail.local这两个配置文件。

操作方法:sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

现在,我们使用编辑器中打开文件jail.local。我使用的是vim。

操作方法:sudo vim /etc/fail2ban/jail.local

我们重点关注一下 [DEFAULT]和[sshd]这两个部分,其中[Default] 位于第41行。

  • ignoreip”- 永远不会被禁止的IP地址白名单。他们拥有永久的“摆脱监狱”卡。本地主机的IP地址  (0.0.1)是在列表中默认情况下,其IPv6相当于(::1)。如果确认永远不应禁止的其它IP地址,请将它们添加到此列表中,并在每个IP地址之间留一个空格
  • bantime”- 禁止IP地址的持续时间(“ m”代表分钟)。如果键入的值不带“ m”或“ h”(代表小时),则将其视为秒。值 -1将永久禁止IP地址。要非常小心,不要将自己的计算机给关了起来,这是非常有可能发生的低级错误。
  • findtime” – 尝试失败的连接次数过多会导致IP地址被禁止的时间。
  • maxretry”- “尝试失败次数过多”的数值。

解释一下这几个设置项的具体作用,如果来自同一IP地址的maxretry连接在该findtime时间段内尝试了失败的连接,则在的持续时间内将其禁止bantime。唯一的例外是ignoreip列表中的IP地址。

Fail2Ban将满足条件的IP地址放入“jail”(监狱)一段时间。Fai2Blan支持许多不同的“监狱”,每个“监狱”代表适用于单个连接类型的具体设置。可以对各种连接类型进行不同的设置。或者,可以使得Fail2Ban仅监视一组选定的连接类型。

[DEFAULT]部分的名称正如英文单词的含义,这个部分是缺省的设置。现在,让我们再去看一下SSH”监狱”的设置。

配置Jail(监狱)

Jails可让我们将连接类型移入和移出Fail2Ban的监视。如果默认设置不匹配要应用于监狱,您可以设置特定值bantime,findtime和maxretry。

向下滚动到第241行,我们看到[sshd] 的部分。

我们要在这个部分设置SSH连接监狱的值。要将这个监狱包括在监视和禁止中,我们要加入以下几行:

enabled = truemaxretry = 3

好了,sshd 的部分就配置好了。

启用 Fail2Ban

到目前为止,我们已经安装Fail2Ban并进行了配置。现在,我们必须使它能够作为自动启动服务运行。然后,我们需要对其进行测试以确保其可以正常工作。要使得系统开机后自动运行Fail2Ban服务,我们使用systemctl命令:

sudo systemctl enable fail2ban

我们还要来启动服务:

sudo systemctl start fail2ban

我们也可以使用来检查服务的状态systemctl:

sudo systemctl status fail2ban.service 我看到了这样的结果,表明Fail2Ban 已经正常的运行起来。

现在一切看起来都很顺利,让我们看看是否  Fail2Ban 自身检查的情况:

sudo fail2ban-client status

这反映了我们刚刚进行的设置。我们启用了一个名为[sshd]的“监狱”。如果在这条命令中包含“监狱”的名称,我们还可以获得更多的信息:

sudo fail2ban-client status sshd

输出的内容列出了失败的数量和被禁止的IP地址。当然,目前所有统计信息均为零。

如果希望验证置的结果进行验证,我们可以找到另一台计算机上,用这台机器将向测试的EC2实例发出SSH连接请求,并故意输入密码。

还记得maxretry设置项吗?那里设置的值将在三次连接尝试失败后触发,而不是三次密码尝试失败。因此,我们必须键入3次错误的密码才能使连接尝试一次失败。然后,我们将尝试进行另一次连接,并再三次错误输入密码。第三个连接请求的第一次错误密码尝试应触发Fail2Ban的规则。

当Fail2Ban 触发了规则,我门将会收到“Port 22:Connection refused”的提示。我们设置的规则生效了!

结语

我不认为Fail2Ban是解决安全问题的“银子弹”。但是你不能否认Fail2Ban是一个简单有效的恶意嗅探/暴力攻击的有效的方法。它只需很少的配置,几乎不会给我们的EC2实例带来任何操作开销。更重要的是,它没有任何成本,除了安装配置所付出的几分钟时间。还犹豫什么呢?

 

本篇作者

费良宏

费良宏,AWS Principal Developer Advocate。在过去的20多年一直从事软件架构、程序开发以及技术推广等领域的工作。他经常在各类技术会议上发表演讲进行分享,他还是多个技术社区的热心参与者。他擅长Web领域应用、移动应用以及机器学习等的开发,也从事过多个大型软件项目的设计、开发与项目管理。目前他专注与云计算以及互联网等技术领域,致力于帮助中国的 开发者构建基于云计算的新一代的互联网应用。