介绍
SSH 是连接到云服务器的事实标准方法。它是持久的,并且它是可扩展的 —— 随着新的加密标准的开发,它们可以用来生成新的 SSH 密钥,确保核心协议仍然安全。然而,没有任何协议或软件堆栈是完全无懈可击的,SSH 在互联网上被广泛部署意味着它代表了一个非常可预测的攻击面或攻击向量,通过它人们可以尝试获取访问权限。
任何暴露在网络上的服务都可能是这种方式的潜在目标。如果您查看任何流量广泛的服务器上运行的 SSH 服务的日志,您通常会看到重复的、系统化的登录尝试,这代表了用户和机器人一样的暴力攻击。尽管您可以对 SSH 服务进行一些优化,将这些攻击成功的几率减少到接近零,例如禁用密码验证,改用 SSH 密钥,但它们仍然可能构成轻微但持续的风险。
对于那些完全不能接受此责任的大规模生产部署,通常会在他们的SSH服务前部署VPN,比如WireGuard,以便在没有额外软件抽象或网关的情况下,不可能直接连接到默认的SSH端口22。这些VPN解决方案被广泛信任,但会增加复杂性,并可能破坏一些自动化或其他小型软件钩子。
在承诺部署完整VPN设置之前或之后,您可以实施一个称为Fail2ban的工具。Fail2ban可以通过创建规则,在一定数量的登录尝试失败后自动更改您的防火墙配置以禁止特定IP地址,从而显著减轻暴力破解攻击。这将使您的服务器能够自动防御这些访问尝试,而无需您的干预。
在本指南中,您将了解如何在Ubuntu 22.04服务器上安装和使用Fail2ban。
先决条件
要完成本指南,您需要:
-
一个Ubuntu 22.04服务器和一个具有sudo特权的非root用户。您可以在我们的使用Ubuntu 22.04进行初始服务器设置指南中了解如何设置具有这些特权的用户。
-
可选:第二个服务器,您可以从中连接到第一个服务器,并将其用于测试人为禁止。
第1步 — 安装Fail2ban
Fail2ban可在Ubuntu的软件存储库中找到。首先以非root用户身份运行以下命令来更新您的软件包列表并安装Fail2ban:
安装完成后,Fail2ban将自动设置一个后台服务。但是,默认情况下它是禁用的,因为其一些默认设置可能会导致不良影响。您可以使用systemctl
命令来验证:
Output○ fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled
Active: inactive (dead)
Docs: man:fail2ban(1)
您可以立即启用Fail2ban,但首先您将查看其一些功能。
第2步 — 配置Fail2ban
fail2ban 服务将其配置文件存储在 /etc/fail2ban
目录中。有一个名为 jail.conf
的默认文件。转到该目录,并使用 head -20
命令打印该文件的前 20 行:
Output#
# 警告:在 0.9.0 版本中进行了大量重构。 请检查并
# 自定义设置以适合您的设置。
#
# 更改:在大多数情况下,您不应修改此
# 文件,而应在 jail.local 文件中提供定制,
# 或在 jail.d/ 目录下提供单独的 .conf 文件,例如:
#
# 如何激活监狱:
#
# 您不应修改此文件。
#
# 它可能会在发行版更新中被覆盖或改进。
#
# 在 jail.local 文件或 jail.d/customisation.local 中提供定制。
# 例如,要更改所有监狱的默认禁令时间并启用
# ssh-iptables 监狱,以下内容(取消注释)将出现在 .local 文件中。
# 有关详细信息,请参阅 man 5 jail.conf。
#
# [DEFAULT]
正如您所看到的,这个文件的前几行是被注释掉的 – 它们以 #
字符开始,表示它们应该被视为文档而不是设置。正如您还会看到的,这些注释指示您不要直接修改此文件。相反,您有两个选项:要么在 jail.d/
目录中创建多个文件以单独配置Fail2ban的配置文件,要么创建并收集所有本地设置在一个 jail.local
文件中。 jail.conf
文件将定期更新,因为Fail2ban本身会更新,并且将被用作您尚未创建任何覆盖的默认设置的源。
在本教程中,您将创建 jail.local
。您可以通过复制 jail.conf
来实现:
现在您可以开始进行配置更改。在 nano
或您喜欢的文本编辑器中打开文件:
当您浏览文件时,本教程将回顾一些您可能想要更新的选项。位于文件顶部附近 [DEFAULT]
部分下的设置将应用于Fail2ban支持的所有服务。在文件的其他位置,有 [sshd]
和其他服务的标题,其中包含将覆盖默认设置的特定于服务的设置。
[DEFAULT]
. . .
bantime = 10m
. . .
参数 bantime
设置了当客户端在身份验证时失败时被禁止的时间长度。这是以秒为单位计量的。默认情况下,此设置为10分钟。
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .
接下来的两个参数是findtime
和maxretry
。它们共同确定客户端被视为非法用户应该被禁止的条件。
maxretry
变量设置客户端在findtime
定义的时间窗口内尝试认证的次数,然后被禁止。使用默认设置,fail2ban服务将在10分钟窗口内无法成功登录5次的客户端。
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .
如果您需要在Fail2ban采取行动时接收电子邮件警报,则应评估destemail
、sendername
和mta
设置。 destemail
参数设置应接收禁止消息的电子邮件地址。sendername
设置电子邮件中“发件人”字段的值。mta
参数配置用于发送邮件的邮件服务。默认情况下是sendmail
,但您可能想使用Postfix或另一个邮件解决方案。
[DEFAULT]
. . .
action = $(action_)s
. . .
此参数配置Fail2ban在要实施封禁时采取的操作。值action_
在此参数之前的文件中定义。默认操作是更新您的防火墙配置以拒绝来自违规主机的流量,直到封禁时间过去。
默认提供了其他action_
脚本,您可以用上述$(action_)
替换。
…
# 禁止并发送带有 whois 报告的电子邮件到目标邮箱。
action_mw = %(action_)s
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
# 禁止并发送带有 whois 报告和相关日志行
# 到目标邮箱。
action_mwl = %(action_)s
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
# 请查看 action.d/xarf-login-attack 中的重要提示,了解何时使用此操作
#
# 禁止并发送 xarf 电子邮件到 IP 地址的滥用联系人,并包括相关日志行
# 到目标邮箱。
action_xarf = %(action_)s
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
# 在 CloudFlare 上禁止 IP 并发送带有 whois 报告和相关日志行的电子邮件
# 到目标邮箱。
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服务已启用,而其他所有服务均已禁用。
在这里设置的一些其他设置是filter
,用于确定日志中的一行是否表示了身份验证失败,并且logpath
告诉fail2ban该特定服务的日志位于何处。
filter
值实际上是对位于/etc/fail2ban/filter.d
目录中的文件的引用,其.conf
扩展名已移除。这些文件包含正则表达式(一种常见的文本解析简写),用于确定日志中的一行是否是失败的身份验证尝试。在本指南中,我们不会深入讨论这些文件,因为它们相当复杂,并且预定义的设置很好地匹配了适当的行。
但是,您可以通过查看该目录来查看可用的过滤器类型:
如果看到一个与您正在使用的服务相关的文件,您应该使用文本编辑器打开它。大多数文件都有相当详细的注释,您应该至少能够知道脚本是设计用来防范什么类型的条件的。大多数这些过滤器在我们可以在jail.local
文件中启用的jail.conf
文件中都有适当的(已禁用)部分。
例如,假设您正在使用Nginx提供网站服务,并意识到网站的受密码保护部分正受到大量的登录尝试。您可以告诉fail2ban使用nginx-http-auth.conf
文件来检查/var/log/nginx/error.log
文件中的此条件。
实际上,这已经在您的/etc/fail2ban/jail.conf
文件中的一个名为[nginx-http-auth]
的部分中设置好了。您只需要添加enabled
参数:
. . .
[nginx-http-auth]
enabled = true
. . .
编辑完成后,保存并关闭文件。此时,您可以启用Fail2ban服务,以便从现在开始自动运行。首先,运行systemctl enable
:
然后,首次手动启动它:systemctl start
:
您可以使用systemctl status
来验证它是否正在运行:
Output● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab>
Active: active (running) since Mon 2022-06-27 19:25:15 UTC; 3s 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 /usr/bin/fail2ban-server -xf start
Jun 27 19:25:15 fail2ban22 systemd[1]: Started Fail2Ban Service.
Jun 27 19:25:15 fail2ban22 fail2ban-server[39396]: Server ready
接下来的步骤中,您将演示Fail2ban的工作原理。
第3步 — 测试封禁策略(可选)
从另一个服务器,该服务器将来不需要登录到您的Fail2ban服务器,您可以通过使第二个服务器被封禁来测试规则。登录到您的第二个服务器后,尝试SSH连接到Fail2ban服务器。您可以尝试使用不存在的名称进行连接:
输入随机字符到密码提示中。重复这个动作几次。在某个时候,你收到的错误信息应该从权限被拒绝
变成连接被拒绝
。这表明你的第二台服务器已经被Fail2ban服务器禁止了。
在你的Fail2ban服务器上,你可以通过检查iptables
的输出来查看新规则。iptables
是一个用于与服务器上的低级端口和防火墙规则交互的命令。如果你遵循了DigitalOcean的初始服务器设置指南,你将使用ufw
来管理更高级别的防火墙规则。运行iptables -S
将显示ufw
已经创建的所有防火墙规则:
Output-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-N f2b-sshd
-N ufw-after-forward
-N ufw-after-input
-N ufw-after-logging-forward
-N ufw-after-logging-input
-N ufw-after-logging-output
-N ufw-after-output
-N ufw-before-forward
-N ufw-before-input
-N ufw-before-logging-forward
-N ufw-before-logging-input
-N ufw-before-logging-output
…
如果你将iptables -S
的输出通过管道传递给grep
,以在这些规则中搜索字符串f2b
,你就可以看到Fail2ban添加的规则:
Output-N f2b-sshd
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A f2b-sshd -s 134.209.165.184/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -j RETURN
包含REJECT --reject-with icmp-port-unreachable
的行将被Fail2ban添加,并应该反映出你第二台服务器的IP地址。
结论
你现在应该能够配置一些封禁策略来保护你的服务了。Fail2ban 是保护任何使用身份验证的服务的有用方式。如果你想了解更多关于 fail2ban 如何工作的信息,你可以查看我们的教程:fail2ban 规则和文件如何工作。
关于如何使用 fail2ban 来保护其他服务的信息,你可以阅读关于 如何在 Ubuntu 14.04 上使用 Fail2Ban 保护 Nginx 服务器 和 如何在 Ubuntu 14.04 上使用 Fail2Ban 保护 Apache 服务器。
Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-22-04