如何在 Rocky Linux 9 上使用 Fail2Ban 保护 Nginx 服务器
介绍
设置 Web 服务器时,通常会有您希望限制访问的站点部分。 Web 应用程序通常提供自己的身份验证和授权方法,但如果这些方法不充分或不可用,Web 服务器本身可用于限制访问。然而,Web 服务器身份验证也代表了一个非常可预测的攻击面 或攻击向量,人们可以通过它尝试获得访问权限。
任何暴露于网络的服务都是这种方式的潜在目标。如果您查看任何被广泛访问的 Web 服务器的日志,您会经常看到重复的、系统的登录尝试,这些尝试代表了用户和类似机器人的暴力攻击。
完全不能接受这种责任的大规模生产部署通常会在任何私有端点前实施 WireGuard 等 VPN,因此如果没有额外的软件抽象或网关,就不可能从外部互联网直接连接到这些 URL。这些 VPN 解决方案受到广泛信任,但会增加复杂性,并可能破坏某些自动化或其他小软件挂钩。
在进行完整的 VPN 设置之前或之外,您可以实施一个名为 Fail2ban 的工具。 Fail2ban 可以通过创建规则来显着减轻暴力攻击,这些规则会在登录尝试失败一定次数后自动更改防火墙配置以禁止特定 IP。这将允许您的服务器在没有您干预的情况下针对这些访问尝试加强自身。
在本指南中,您将了解如何在 Rocky Linux 9 服务器上安装 fail2ban
并将其配置为监控 Nginx 日志以查找入侵企图。
先决条件
- 使用具有
sudo
权限的非根用户访问 Rocky Linux 9 服务器环境以执行管理任务。要了解如何创建此类用户,请遵循 Rocky Linux 9 初始服务器设置指南。 - 按照本指南中有关如何在 Rocky Linux 9 上安装 Nginx 的第 1 步和第 2 步,在您的系统上安装 Nginx。
- 按照如何在 Rocky Linux 9 上使用 Nginx 设置密码身份验证,安装并配置了密码身份验证。
第 1 步 — 安装和配置 Fail2ban
Fail2ban 在 Rocky 的默认软件存储库中不可用。但是,它在 EPEL 或 Enhanced Packages for Enterprise 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
Output○ fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled
Active: inactive (dead)
Docs: man:fail2ban(1)
您可以立即启用 Fail2ban,但首先,您将查看它的一些功能。
fail2ban 服务将其配置文件保存在 /etc/fail2ban
目录中。有一个名为 jail.conf
的默认文件。转到该目录并使用 head -20
打印该文件的前 20 行:
- cd /etc/fail2ban
- head -20 jail.conf
Output#
# 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中创建并收集所有本地设置代码>文件。 jail.conf
文件将随着 Fail2ban 本身的更新而定期更新,并将用作您尚未创建任何覆盖的默认设置的来源。
在本教程中,您将创建 jail.local
。您可以通过复制 jail.conf
来做到这一点:
- sudo cp jail.conf jail.local
现在您可以开始进行配置更改。 Rocky Linux 9 自带的默认文本编辑器是 vi
。 vi
是一个非常强大的文本编辑器,但对于缺乏使用经验的用户来说可能有点迟钝。你可能想要安装一个对用户更友好的编辑器,比如 nano
来编辑你的 Rocky Linux 9 服务器上的配置文件:
- sudo dnf install nano -y
现在你可以使用 nano
来编辑你的 Nginx 配置文件:
- sudo nano jail.local
更改默认值
您将从评估文件中设置的默认值开始。这些将在文件中的 [DEFAULT]
部分下找到。这些项目设置了一般策略,并且可以在每个应用程序的基础上被覆盖。如果您使用的是 nano
,则可以通过按 Ctrl+W
在文件中搜索,输入搜索字符串,然后按 enter。
首先要查看的项目之一是不受 fail2ban
策略约束的客户端列表。这是由 ignoreip
指令设置的。有时将您自己的 IP 地址或网络添加到例外列表中以避免将您自己锁定在外是个好主意。与 SSH 相比,这对于 Web 服务器登录来说不是一个问题,因为如果您能够保持 shell 访问,您总是可以撤销禁令。您可以取消注释此行并添加额外的 IP 地址或由空格分隔的网络到现有列表:
[DEFAULT]
. . .
#ignoreip = 127.0.0.1/8 your_home_IP
您可能想要调整的另一个项目是 bantime
,它控制违规成员被禁止的秒数。最好将此时间设置为足够长的时间以破坏恶意的、自动化的工作,同时又要足够短以允许用户纠正错误。默认情况下,此设置为 10 分钟。您可以增加或减少此值:
[DEFAULT]
. . .
bantime = 10m
接下来的两项确定用于确定违规客户端的日志行的范围。 findtime
指定以秒为单位的时间量,maxretry
指令指示在该时间内可以容忍的尝试次数。如果客户端在 findtime
设置的时间内尝试超过 maxretry
次,他们将被禁止:
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
action
参数配置 Fail2ban 在想要实施禁令时采取的行动。值 action_
在此参数之前的文件中定义。默认操作是更新您的防火墙配置以拒绝来自违规主机的流量,直到禁令时间结束。
[DEFAULT]
. . .
action = $(action_)s
. . .
默认提供了其他的 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"]
…
在下一步中,您将继续进行特定于 Nginx 的配置。
第 2 步 – 配置 Fail2Ban 以监控 Nginx 日志
现在您已经有了一些通用的 fail2ban
设置,您可以启用一些特定于 Nginx 的监狱,这些监狱将监控您的 Web 服务器日志以获取特定模式。
配置文件中的每个 jail 都由一个标头标记,该标头包含方括号中的 jail 名称——除 [DEFAULT]
部分外的每个部分都指示特定 jail 的配置。默认情况下,仅启用 [ssh]
监狱。
要为 Nginx 登录尝试启用日志监控,请启用 [nginx-http-auth]
jail。在此部分中添加一个 enabled=true
指令:
…
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
. . .
完成修改后,保存并关闭文件。如果您使用的是 nano
,请按 Ctrl+X
,然后在出现提示时按 Y
,然后按 Enter。接下来,您将查看 nginx-http-auth
的过滤器配置。
第 3 步 – 检查 Nginx Jails 的过滤器
您可能已经注意到 jail.local
中的 [nginx-http-auth]
块不包含任何特定于 Nginx 的规则。这些规则不会自动硬编码在 Fail2ban 中——事实上,[nginx-http-auth]
标头直接对应于 Fail2ban 的预打包过滤器的 filter.d
目录中的文件名.如果您列出此目录的内容,您可以看到其他可用的预打包过滤器,如果您需要使用它们:
- ls /etc/fail2ban/filter.d
Output3proxy.conf freeswitch.conf proftpd.conf
apache-auth.conf froxlor-auth.conf pure-ftpd.conf
apache-badbots.conf gitlab.conf qmail.conf
apache-botsearch.conf grafana.conf recidive.conf
apache-common.conf groupoffice.conf roundcube-auth.conf
apache-fakegooglebot.conf gssftpd.conf scanlogd.conf
apache-modsecurity.conf guacamole.conf screensharingd.conf
apache-nohome.conf haproxy-http-auth.conf selinux-common.conf
apache-noscript.conf horde.conf selinux-ssh.conf
apache-overflows.conf ignorecommands sendmail-auth.conf
apache-pass.conf kerio.conf sendmail-reject.conf
apache-shellshock.conf lighttpd-auth.conf sieve.conf
assp.conf mongodb-auth.conf slapd.conf
asterisk.conf monit.conf softethervpn.conf
bitwarden.conf murmur.conf sogo-auth.conf
…
现在,看看 nginx-http-auth.conf
:
- cat /etc/fail2ban/filter.d/nginx-http-auth.conf
Output# fail2ban filter configuration for nginx
[Definition]
failregex = ^ \[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$
ignoreregex =
datepattern = {^LN-BEG}
…
这些文件包含正则表达式(文本解析的常用简写),用于确定日志中的一行是否是失败的身份验证尝试。它们可以根据需要直接修改。
在接下来的步骤中,您将启用并测试 Fail2ban。
第 4 步 – 激活您的 Nginx Jails
此时,您可以启用您的 Fail2ban 服务,以便它从现在开始自动运行。首先,运行 systemctl enable
:
- sudo systemctl enable fail2ban
然后,第一次使用 systemctl start
手动启动它:
- sudo systemctl start fail2ban
您可以使用 systemctl status
验证它是否正在运行:
- sudo systemctl status fail2ban
Output● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled
Active: active (running) since Wed 2022-09-14 20:48:40 UTC; 22h ago
Docs: man:fail2ban(1)
Main PID: 5962 (fail2ban-server)
Tasks: 7 (limit: 2327)
Memory: 12.6M
CPU: 195ms
CGroup: /system.slice/fail2ban.service
└─5962 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
注意:要实施任何未来的配置更改,您需要重新启动 fail2ban
服务。您可以使用 sudo systemctl restart fail2ban
来做到这一点
获取有关已启用监狱的信息
您可以使用 fail2ban-client
命令查看所有启用的监狱:
- sudo fail2ban-client status
您应该看到已启用监狱的列表:
OutputStatus
|- Number of jail: 2
`- Jail list: nginx-http-auth, sshd
如果您想查看任何一个监狱执行的禁令的详细信息,请再次使用 fail2ban-client
:
- sudo fail2ban-client status nginx-http-auth
OutputStatus for the jail: nginx-http-auth
|- filter
| |- File list: /var/log/nginx/error.log
| |- Currently failed: 0
| `- Total failed: 0
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 0
在本教程的最后一步,您将有意测试是否被禁止以验证您的 Fail2ban 配置是否正常工作。
第 5 步 – 测试 Fail2Ban 策略
测试您的 Fail2ban 策略以确保它们按预期阻止流量非常重要。为此,请在本地网络浏览器中导航到您的服务器。在 Nginx 身份验证提示中,重复输入错误的凭据。几次尝试后,服务器应该完全停止响应你,就好像你的连接断开了一样:

如果您使用 fail2ban-client
查看 nginx-http-auth
配置的状态,您将看到您的 IP 地址被站点禁止:
- sudo fail2ban-client status nginx-http-auth
OutputStatus for the jail: nginx-http-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 5
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 108.172.85.62
当您对规则的工作感到满意时,您可以使用 fail2ban-client
手动取消禁止您的 IP 地址,方法是键入:
- sudo fail2ban-client set nginx-http-auth unbanip 108.172.85.62
您现在应该能够再次尝试进行身份验证。
结论
Fail2ban 提供了很大的灵活性来构建适合您特定安全需求的策略。通过查看 /etc/fail2ban/jail.local
文件中的变量和模式,以及 /etc/fail2ban/filter.d
中它所依赖的文件> 和 /etc/fail2ban/action.d
目录,您可以找到许多可以根据您的需求进行调整和更改的部分。使用 fail2ban
保护您的服务器可以为您提供有用的安全基线。
要了解更多使用 fail2ban
的方法,请查看如何在 Rocky Linux 9 上使用 Fail2Ban 保护 SSH。