如何在Rocky Linux 9上使用Fail2Ban来保护SSH
介绍
SSH是连接到云服务器的事实标准方法。它是稳定的,而且具有扩展性 – 随着新的加密标准的发展,可以使用它们来生成新的SSH密钥,确保核心协议的安全性。然而,没有任何协议或软件栈是绝对安全的,SSH在互联网上被广泛部署意味着它代表着一种非常可预测的攻击面或攻击向量,黑客可以通过它来试图获取访问权限。
任何暴露在网络上的服务都可能成为潜在目标。如果你审查一下在任何繁忙服务器上运行的SSH服务的日志,你经常会看到重复的、系统化的登录尝试,这代表着用户和机器人进行的暴力攻击。尽管你可以对SSH服务进行一些优化,以减少这些攻击成功的可能性接近零,比如禁用密码认证来使用SSH密钥进行认证,它们仍然可能构成一种小型但持续存在的风险。
对于那些完全不能容忍此责任的大规模生产部署,通常会在其SSH服务前面部署一个VPN(如WireGuard),这样就不可能直接从外部互联网连接到默认的SSH端口22,除非使用额外的软件抽象或网关。这些VPN解决方案被广泛信赖,但会增加复杂性,并可能破坏一些自动化流程或其他小型软件钩子。
在承诺或决定使用完整的VPN设置之前,你可以实施一个叫做Fail2ban的工具。Fail2ban可以通过创建规则,在一定数量的登录失败尝试后自动更改防火墙配置,从而显著减少暴力破解攻击。这将使你的服务器能够在没有你的干预的情况下加强对这些访问尝试的防御。
在本指南中,您将了解如何在Rocky Linux 9服务器上安装和使用Fail2ban。
前提条件
为完成这个向导,您将需要:
- A Rocky Linux 9 server and a non-root user with sudo privileges. You can learn more about how to set up a user with these privileges in our Initial Server Setup with Rocky Linux 9 guide. You should also have firewalld running on the server, which is covered in our initial server setup guide.
- Optionally, a second server that you can connect to your first server from, which you will use to test getting deliberately banned.
第一步 – 安装 Fail2ban。
Fail2ban在Rocky的默认软件仓库中不可用。然而,它可在EPEL(企业级Linux增强软件包)仓库中找到,该仓库通常用于安装Red Hat和Rocky Linux的第三方软件包。如果您尚未将EPEL添加到系统软件源中,您可以使用dnf添加该仓库,就像安装其他任何软件包一样。
- sudo dnf install epel-release -y
当安装新软件时,dnf软件包管理器将会检查EPEL源,以及您默认的软件源。请继续安装Fail2ban。
- sudo dnf install fail2ban -y
安装完Fail2ban后,它将自动设置一个后台服务。然而,默认情况下它被禁用,因为一些默认设置可能会导致不期望的影响。您可以使用systemctl命令来验证这一点。
- systemctl status fail2ban.service
○ fail2ban.service – Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled Active: inactive (dead) Docs: man:fail2ban(1)
您可以立即启用Fail2ban,但首先您需要查看一些其功能。
第二步 – 配置Fail2ban
fail2ban服务将其配置文件保存在/etc/fail2ban目录中。其中有一个名为jail.conf的默认文件。转到该目录并使用head -20打印该文件的前20行。
- cd /etc/fail2ban
- head -20 jail.conf
# # WARNING: heavily refactored in 0.9.0 release. Please review and # customize settings for your setup. # # Changes: in most of the cases you should not modify this # file, but provide customizations in jail.local file, # or separate .conf files under jail.d/ directory, e.g.: # # HOW TO ACTIVATE JAILS: # # YOU SHOULD NOT MODIFY THIS FILE. # # It will probably be overwritten or improved in a distribution update. # # Provide customizations in a jail.local file or a jail.d/customisation.local. # For example to change the default bantime for all jails and to enable the # ssh-iptables jail the following (uncommented) would appear in the .local file. # See man 5 jail.conf for details. # # [DEFAULT]
正如您所见,该文件的前几行以#字符开头,表示这些行将被视为文档而非设置。同时您也会注意到,这些注释指示您不要直接修改该文件。相反,您有两个选择:要么在jail.d/目录中创建多个文件来为Fail2ban创建独立的配置文件,要么在jail.local文件中创建和收集所有本地设置。每当Fail2ban本身更新时,jail.conf文件也会定期更新,并作为默认设置的源头,如果您没有进行任何覆盖,则将使用该文件中的设置。
在本教程中,您将创建一个名为jail.local的文件。您可以通过复制jail.conf文件来实现。
- sudo cp jail.conf jail.local
现在你可以开始进行配置更改。在vi或你喜欢的文本编辑器中打开文件。
- sudo vi jail.local
当您浏览文件时,本教程将回顾一些您可能想要更新的选项。文件顶部附近的[DEFAULT]部分中的设置将应用于Fail2ban支持的所有服务。文件的其他部分还包含[sshd]和其他服务的标题,其中包含针对特定服务的设置,将覆盖默认设置。
[DEFAULT]
. . .
bantime = 10m
. . .
bantime参数用于设置客户端在未能正确进行身份验证时被禁止的时间长度,以秒为单位计算。默认情况下,设置为10分钟。
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .
下面的两个参数是findtime和maxretry。它们共同用于建立客户端被视为非法用户并应该被禁止的条件。
maxretry变量设置了客户端在findtime定义的时间窗口内进行身份验证的尝试次数上限,超过该次数则被封禁。默认设置下,fail2ban服务将会在10分钟的时间窗口内失败尝试登录5次的客户端进行封禁。
/etc/fail2ban/jail.local 可以被改写为以下一种中文表达方式:
1. 请修改/etc/fail2ban/jail.local文件。
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .
如果您需要在Fail2ban采取行动时接收电子邮件警报,您应该评估destemail、sendername和mta设置。destemail参数设置应接收封禁消息的电子邮件地址。sendername设置电子邮件中“发件人”字段的值。mta参数配置将用于发送邮件的邮件服务。默认情况下,此设置为sendmail,但您可能希望使用Postfix或其他邮件解决方案。
[DEFAULT]
. . .
action = %(action_)s
. . .
当Fail2ban想要实施禁止时,此参数配置Fail2ban所采取的操作。该参数在离此参数之前的文件中定义值action_。默认操作是更新防火墙配置,以拒绝来自违规主机的流量,直到禁止时间过期。
默认提供了其他的动作脚本,你可以将$(action_)替换为上述脚本。
…
# ban & send an e-mail with whois report to the destemail.
action_mw = %(action_)s
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(action_)s
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
#
# ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
# to the destemail.
action_xarf = %(action_)s
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
# to the destemail.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…
例如,action_mw执行操作并发送电子邮件,action_mwl执行操作、发送电子邮件并包括日志记录,而action_cf_mwl除了执行所有上述操作外,还向与您的账户关联的Cloudflare API发送更新以封禁施加者。
个人监狱设置
接下来是配置文件中与单个服务有关的部分。这些部分由节标题指定,例如[sshd]。
需要通过在标题下添加enabled = true行并设置其他设置,分别启用这些部分中的每一个。
[jail_to_enable]
. . .
enabled = true
. . .
在这个教程中,你将启用SSH监狱。它应该位于各个监狱设置的顶部。除此之外,默认参数将会起作用,但是你需要在[sshd]标头下添加一行配置,即enabled = true。
/etc/fail2ban/jail.local
#
# JAILS
#
#
# SSH servers
#
[sshd]
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode = normal
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
在此设置中,还有一些其他的设置,如筛选器的设置,该筛选器用于确定日志中的行是否表示了身份验证失败,并且为Fail2Ban提供了指示特定服务的日志文件所在位置的日志路径。
过滤器的值实际上是对位于/etc/fail2ban/filter.d目录中的文件的引用,其中的.conf扩展名被删除了。这些文件包含正则表达式(一种常见的文本解析简写),用于确定日志中的行是否是身份验证失败的尝试。在本指南中,我们不会深入讨论这些文件,因为它们相当复杂,并且预定义的设置可以很好地匹配适当的行。
然而,你可以通过查看该目录来了解有哪些种类的过滤器可供选择。
- ls /etc/fail2ban/filter.d
如果你看到一个看起来与你正在使用的服务有关的文件,你应该使用文本编辑器打开它。大多数文件都有相当详细的注释,你至少应该能够判断出该脚本旨在防范哪种类型的条件。这些过滤器大多在jail.conf文件中有对应的(已禁用)部分,如果需要的话我们可以在jail.local文件中启用这些部分。
例如,想象一下,你正在使用Nginx提供网站服务时,意识到你的网站中有一个受密码保护的部分正遭受登陆尝试的攻击。你可以告诉fail2ban使用nginx-http-auth.conf文件来检查/var/log/nginx/error.log文件中的这种情况。
这实际上已经在您的/etc/fail2ban/jail.conf文件中的一个名为[nginx-http-auth]的部分设置好了。您只需要添加enabled参数即可。
. . .
[nginx-http-auth]
enabled = true
. . .
当您完成编辑后,请保存并关闭文件。如果您使用的是vi,使用:x来保存并退出。此时,您可以启用Fail2ban服务,以便从现在开始自动运行。首先,运行systemctl enable命令。
- sudo systemctl enable fail2ban
然后,使用systemctl start手动启动它的第一次。
- sudo systemctl start fail2ban
您可以使用systemctl status命令来验证它是否运行。
- sudo systemctl status fail2ban
● fail2ban.service – Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled Active: active (running) since Wed 2022-09-14 20:48:40 UTC; 2s ago Docs: man:fail2ban(1) Main PID: 39396 (fail2ban-server) Tasks: 5 (limit: 1119) Memory: 12.9M CPU: 278ms CGroup: /system.slice/fail2ban.service └─39396 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start Sep 14 20:48:40 rocky9-tester systemd[1]: Starting Fail2Ban Service… Sep 14 20:48:40 rocky9-tester systemd[1]: Started Fail2Ban Service. Sep 14 20:48:41 rocky9-tester fail2ban-server[39396]: Server ready
在接下来的步骤中,您将展示Fail2ban的实际操作。
第三步-测试禁止政策(可选)
从另一个服务器上,一个将来不需要登录到您的Fail2ban服务器的服务器上,您可以通过将该第二个服务器禁止来测试规则。在登录到您的第二个服务器后,尝试通过SSH连接到Fail2ban服务器。您可以尝试使用一个不存在的名称进行连接。
- ssh blah@your_server
在密码提示中输入随机字符。重复几次此操作。在某个时刻,您收到的错误信息应该从”权限被拒绝”变为”连接被拒绝”。这表明您的第二个服务器已被Fail2ban服务器禁止。
在您的Fail2ban服务器上,可以通过检查fail2ban-client的输出来查看新的规则。fail2ban-client是Fail2ban提供的额外命令,用于检查其运行配置。
- sudo fail2ban-client status
Status |- Number of jail: 1 `- Jail list: sshd
如果您运行fail2ban-client status sshd命令,您可以查看被禁止通过SSH访问的IP地址列表。
- sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 2 | |- Total failed: 7 | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 134.209.165.184
禁止访问IP列表应该反映出你的第二个服务器的IP地址。
结论是
现在你应该能够为你的服务配置一些封禁政策了。Fail2ban是一种保护使用身份验证的任何类型服务的有用方式。如果你想了解更多关于fail2ban的工作原理,可以查看我们关于fail2ban规则和文件工作方式的教程。
有关如何使用fail2ban保护其他服务的信息,您可以阅读《如何使用Fail2Ban保护Nginx服务器》。