如何在Debian 11上使用Fail2Ban保护SSH

介绍

SSH是连接到云服务器的事实标准方法。它耐用且可扩展——随着新的加密标准的开发,它们可以用于生成新的SSH密钥,确保核心协议保持安全。然而,没有协议或软件堆栈是完全无懈可击的,SSH在互联网上被广泛部署意味着它代表了一个非常可预测的攻击面或攻击向量,通过它人可以尝试获取访问权限。

以这种方式暴露在网络上的任何服务都是潜在的攻击目标。如果您查看任何广受欢迎的服务器上运行的SSH服务的日志,通常会看到重复的系统登录尝试,这代表着用户和机器人的暴力攻击。尽管您可以对SSH服务进行一些优化,以减少这些攻击成功的机会接近零,比如禁用密码身份验证,转而使用SSH密钥,它们仍然可能构成轻微但持续的风险。

对于那些完全不能容忍此类责任的大规模生产部署,通常会在其SSH服务前部署类似WireGuard的VPN,以便在没有额外软件抽象或网关的情况下,无法直接连接到外部互联网的默认SSH端口22。这些VPN解决方案被广泛信任,但会增加复杂性,并可能破坏一些自动化或其他小型软件挂钩。

在承诺采用完整VPN设置之前或之后,您可以实施一种称为Fail2ban的工具。Fail2ban可以通过创建规则,自动更改防火墙配置以在一定数量的登录尝试失败后禁止特定IP,从而显着减轻暴力攻击。这将使您的服务器能够在无需您干预的情况下加固自身,抵御这些访问尝试。

在本指南中,您将了解如何在Debian 11服务器上安装和使用Fail2ban。

先决条件

要完成本指南,您需要:

  • 一个Debian 11服务器和一个具有sudo特权的非root用户。您可以在我们的使用Debian 11进行初始服务器设置指南中了解有关如何设置具有这些特权的用户的更多信息。

  • 可选地,您可以连接到第一个服务器的第二个服务器,然后使用它来测试被故意禁止。

步骤 1 — 安装 Fail2ban

Fail2ban 可在 Debian 软件存储库中找到。首先以非根用户身份运行以下命令来更新软件包列表并安装 Fail2ban:

  1. sudo apt update
  2. sudo apt install fail2ban

安装完毕后,Fail2ban 将自动设置一个后台服务。您可以使用 systemctl 命令检查其状态:

  1. systemctl status fail2ban.service
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled Active: active (running) since Tue 2022-06-28 16:23:14 UTC; 17s ago Docs: man:fail2ban(1) Process: 1942 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS Main PID: 1943 (fail2ban-server) Tasks: 5 (limit: 1132) Memory: 15.8M CPU: 280ms CGroup: /system.slice/fail2ban.service └─1943 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

您可以继续使用 Fail2ban 的默认设置,但首先您将查看一些其功能。

步骤 2 — 配置 Fail2ban

Fail2ban 服务将其配置文件保存在 /etc/fail2ban 目录中。那里有一个名为 jail.conf 的默认文件。进入该目录并使用 head -20 打印该文件的前 20 行:

  1. cd /etc/fail2ban
  2. head -20 jail.conf
Output
# # 警告:在 0.9.0 版本中进行了大量重构。 请审核并 # 自定义设置以适应您的设置。 # # 更改:在大多数情况下,您不应修改此 # 文件,而是在 jail.local 文件中提供定制内容, # 或在 jail.d/ 目录下提供单独的 .conf 文件,例如: # # 如何激活 Jails: # # 您不应修改此文件。 # # 它可能会在发行版更新中被覆盖或改进。 # # 在 jail.local 文件或 jail.d/customisation.local 文件中提供自定义内容。 # 例如,要更改所有 jails 的默认封禁时间并启用 # ssh-iptables jail,则以下(已取消注释)将出现在 .local 文件中。 # 详见 man 5 jail.conf 了解详情。 # # [DEFAULT]

正如您所见,此文件的前几行是注释掉的 – 它们以#字符开头,表示它们将被视为文档而不是设置。 此外,您还会看到,这些注释指示您不要直接修改此文件。 相反,您有两个选项:在jail.d/目录中创建多个 Fail2ban 的个别配置文件,或者创建并收集所有本地设置在jail.local文件中。 jail.conf文件将定期更新,因为 Fail2ban 本身也会更新,并将用作您尚未创建任何覆盖的默认设置的源。

在这个教程中,您将创建jail.local文件。您可以通过复制jail.conf来实现:

  1. sudo cp jail.conf jail.local

现在您可以开始进行配置更改。在nano或您喜欢的文本编辑器中打开文件:

  1. sudo nano jail.local

当您浏览文件时,本教程将审查一些您可能想要更新的选项。位于文件顶部附近[DEFAULT]部分下的设置将应用于Fail2ban支持的所有服务。文件中的其他位置,有[sshd]和其他服务的标头,其中包含将覆盖默认设置的特定于服务的设置。

/etc/fail2ban/jail.local
[DEFAULT]
. . .
bantime = 10m
. . .

bantime参数设置客户端在身份验证失败时被禁止的时间长度。这是以秒为单位的。默认情况下,设置为10分钟。

/etc/fail2ban/jail.local
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .

接下来的两个参数是findtimemaxretry。它们一起工作,建立客户端被视为非法用户应该被禁止的条件。

maxretry变量设置客户端在findtime定义的时间窗口内尝试身份验证的次数,在被禁止之前。使用默认设置,fail2ban服务将在10分钟窗口内无法成功登录5次的情况下禁止客户端。

/etc/fail2ban/jail.local
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .

如果您需要在Fail2ban采取行动时接收电子邮件警报,则应评估destemailsendernamemta设置。 destemail参数设置应接收禁止消息的电子邮件地址。 sendername设置电子邮件中“发件人”字段的值。 mta参数配置将用于发送邮件的邮件服务。 默认情况下,这是sendmail,但您可能希望使用Postfix或其他邮件解决方案。

/etc/fail2ban/jail.local
[DEFAULT]
. . .
action = $(action_)s
. . .

此参数配置了Fail2ban在要实施禁令时采取的操作。 值action_在此参数之前的文件中定义。 默认操作是更新您的防火墙配置,以拒绝来自违规主机的流量,直到禁令时间过去为止。

默认提供了其他action_脚本,您可以将$(action_)替换为上述内容:

/etc/fail2ban/jail.local
…
# 禁止并向destemail发送带有whois报告的电子邮件。
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# 禁止并向destemail发送带有whois报告和相关日志行
#至destemail。
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中的重要说明
#
# 禁止并向IP地址的滥用联系人发送xarf电子邮件,并包含相关日志行
#至destemail。
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# 在CloudFlare上禁止IP并向destemail发送带有whois报告和相关日志行的电子邮件
#至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行并附带其他设置来单独启用这些部分。

/etc/fail2ban/jail.local
[jail_to_enable]
. . .
enabled = true
. . .

默认情况下,SSH服务已启用,所有其他服务都已禁用。
.
此处设置的其他一些设置包括将用于决定日志中是否有失败认证的filter以及告诉fail2ban该特定服务的日志位置的logpath

filter值实际上是指向位于/etc/fail2ban/filter.d目录中的文件的引用,其.conf扩展名已移除。这些文件包含用于确定日志中是否存在认证失败尝试的正则表达式(一种常用的文本解析简写)。我们在本指南中不会深入介绍这些文件,因为它们相当复杂,预定义的设置能够很好地匹配适当的行。

但是,您可以通过查看该目录来了解可用的过滤器类型:

  1. 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参数:

/etc/fail2ban/jail.local
. . .
[nginx-http-auth]

enabled = true
. . .

当您完成编辑后,请保存并关闭文件。如果您已经进行了任何更改,可以使用systemctl重新启动Fail2ban服务:

  1. sudo systemctl restart fail2ban

在下一步中,您将演示Fail2ban的工作原理。

步骤3 — 测试禁止策略(可选)

从另一个服务器,即将来不需要登录到您的Fail2ban服务器的服务器上,您可以通过让第二个服务器被禁止来测试规则。登录到您的第二个服务器后,尝试通过SSH连接到Fail2ban服务器。您可以尝试使用一个不存在的名称进行连接:

  1. ssh blah@your_server

在密码提示符中输入随机字符。重复几次此操作。在某个时候,您收到的错误消息应从Permission denied更改为Connection refused。这表示您的第二个服务器已被Fail2ban服务器禁止。

在您的Fail2ban服务器上,您可以通过检查您的iptables输出来查看新规则。iptables是与服务器上的低级端口和防火墙规则交互的命令。如果您遵循DigitalOcean的初始服务器设置指南,则将使用ufw来管理更高级别的防火墙规则。运行iptables -S将显示ufw已经创建的所有防火墙规则:

  1. sudo iptables -S
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添加的规则:

  1. sudo iptables -S | grep f2b
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保护其他服务的信息,您可以阅读关于如何使用Fail2Ban保护Nginx服务器如何使用Fail2Ban保护Apache服务器

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-debian-11