使用 Fail2ban 保护 WordPress 免受暴力攻击

在本教程中,您将了解如何使用 Fail2ban 保护 WordPress 免受暴力攻击。 Fail2ban 是一个基于 python 的入侵防御工具;

监控日志文件(例如/var/log/auth.log、/var/log/apache/access.log)并通过更新现有的防火墙规则暂时或持久地禁止容易出现故障的地址。 Fail2ban 允许轻松指定不同的操作,例如使用 iptables 或 hostsdeny 规则禁止 IP,或者只是发送通知电子邮件。

默认情况下,它带有用于各种服务(sshd、apache、proftpd、sasl 等)的过滤器表达式,但可以轻松扩展配置以监视任何其他文本文件。 所有过滤器和操作都在配置文件中给出,因此fail2ban 可以用于各种文件和防火墙。 列出了以下建议:

  • iptables/nftables — 默认安装使用 iptables 来禁止。 也支持 nftables。 你很可能需要它
  • whois — 许多邮件-whois 操作使用它来发送带有攻击者主机的 whois 信息的通知电子邮件。 除非你会使用那些你不需要的 whois
  • python3-pyinotify — 除非您通过 systemd 监控服务日志,否则您需要 pyinotify 来有效监控日志文件更改。

使用 Fail2ban 保护 WordPress 免受暴力攻击

尽管有多种方法可以保护 WordPress 登录免受暴力攻击,例如使用 libModSecurity 将 WordPress 登录页面的访问权限限制为特定 IP,但本指南将重点介绍为此目的使用 Fail2ban。

安装 Fail2ban

首先,在您的主机系统上安装 Fail2ban。 Fail2ban 的安装因 Linux 发行版而异。

如果您使用的是 Ubuntu/Debian 系统,只需运行以下命令即可安装 Fail2ban;

apt update
apt install fail2ban

在 CentOS 和类似发行版上,运行以下命令安装 Fail2ban;

dnf install epel-release
dnf update
dnf install fail2ban

配置 Fail2ban 以保护 WordPress 身份验证免受暴力攻击

首先,您需要知道Fail2ban 会监控日志文件(例如/var/log/auth.log、/var/log/apache/access.log)并通过更新现有的防火墙规则临时或持久地禁止容易出现故障的地址。 Fail2ban 允许轻松指定不同的操作,例如使用 iptables 或 hostsdeny 规则禁止 IP……

为了有效地禁止或阻止有问题的 IP 地址,Fail2ban 使用 jails 这基本上是各种的组合 filtersactions. Fail2ban filters 只是与正在监视的相应日志文件中的特定模式相匹配的规则。 can 模式可以对应于失败的登录尝试、请求状态代码、请求 URI 或任何其他可疑活动。 Fail2ban actions 另一方面,定义在过滤器匹配指定模式(例如可疑 IP 地址)时执行的命令。

创建 Fail2ban WordPress 监狱

Fail2ban 有四种配置文件类型:

  • fail2ban.conf:Fail2Ban 全局配置(如日志记录)
  • filter.d/*.conf: 指定如何检测身份验证失败的过滤器
  • action.d/*.conf: 定义禁止和取消禁止 IP 地址命令的操作
  • jail.conf:定义过滤器与动作组合的监狱。

笔记: 建议 *.conf 文件应保持不变以方便升级。 如果需要,应在 *.local 文件中提供自定义。

复制 jail.conf 归档到 jail.local 文件;

cp /etc/fail2ban/jail.{conf,local}

接下来,编辑 jail.local 文件并在下面设置默认参数 [DEFAULT] 部分。

vim /etc/fail2ban/jail.local

我们将调整的一些参数包括;

  • 忽略ip: 指定要忽略的 IP 地址或主机名。
  • 禁止时间: 定义主机被禁止的持续时间(以秒为单位)。 默认值为 600 秒(10 分钟)。
  • 最大重试: 定义 a 被禁止之前的失败次数。
  • 查找时间: 定义一个时间段,在该时间段内,如果主机超过 最大重试次数 价值,它被禁止。
... ignoreip = 127.0.0.1/8 192.168.57.33 ... bantime  = 3600 ... findtime  = 60 ... maxretry = 3

这基本上意味着,如果在一分钟内出现超过 3 次登录失败等可疑活动,除了 localhost 和 192.168.57.33 之外的可疑主机将被禁止一小时。

一旦你定义了上面的默认选项,就为 wordpress 创建一个 jail。 例如,将下面的内容粘贴到上面jail.local文件的底部;

... # WordPress Jail [wordpress-auths] enabled = true port = http,https filter = wordpress-auth logpath = /var/log/apache2/wp.access.log

您可以调整所有这些设置以满足您的需要!!

上面的大多数选项都是不言自明的。 过滤器指定我们将创建的过滤器的名称 filter 标识 WordPress 登录的日志记录在由 logpath.

Save 并退出文件。

创建 Fail2ban WordPress 登录过滤器

接下来,您需要创建一个过滤器来定义一个正则表达式,用于从指定的日志文件中过滤掉 WordPress 身份验证日志。

请注意,在我们的例子中,我们使用日志文件, /var/log/apache2/wp.access.log.

对于每次 WordPress 登录尝试, POST 请求被发送到 /wp-login.php 带有 200 状态代码的文件并写入 Web 服务器访问日志。 以下是我们登录的示例日志;

tail -f /var/log/apache2/wp.access.log | grep "POST /wp-login.php"
192.168.57.33 - - [11/Mar/2021:20:18:15 +0000] "POST /wp-login.php HTTP/1.1" 200 2825 "https://kifarunix-demo.com/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" 192.168.57.1 - - [11/Mar/2021:20:19:14 +0000] "POST /wp-login.php HTTP/1.1" 200 2815 "https://kifarunix-demo.com/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"

因此,在创建过滤器时,我们将使用正则表达式从日志文件中过滤掉此类日志行。

多个 Fail2ban 过滤器位于, /etc/fail2ban/filter.d/. 您可以检查其中任何一个,了解如何创建过滤器。

创建 WordPress 身份验证过滤器。 注意过滤器配置文件的名称

vim /etc/fail2ban/filter.d/wordpress-auth.conf
[Definition] failregex = ^<HOST> .* "POST /wp-login.php HTTP.* 200

这是我们 WordPress 登录的示例失败正则表达式。

Save 并退出。 您可以添加更多适合您需要的过滤器。

测试 Fail2ban WordPress 过滤器

要验证您的过滤器是否可以匹配日志文件中的模式,请使用 fail2ban-regex 工具如下。

命令概要。

fail2ban-regex [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]

所以要测试我们的 WordPress 过滤器;

fail2ban-regex /var/log/apache2/wp.access.log /etc/fail2ban/filter.d/wordpress-auth.conf

显示匹配行的示例输出;

Running tests =============  Use   failregex filter file : wordpress-auth, basedir: /etc/fail2ban Use         log file : /var/log/apache2/wp.access.log Use         encoding : UTF-8   Results =======  Failregex: 10 total |-  #) [# of hits] regular expression |   1) [10] ^<HOST> .* "POST /wp-login.php HTTP.* 200 `-  Ignoreregex: 0 total  Date template hits: |- [# of hits] date format |  [577] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:.Microseconds)?(?: Zone offset)? `-  Lines: 577 lines, 0 ignored, 10 matched, 567 missed [processed in 0.25 sec]  Missed line(s): too many to print.  Use --print-all-missed to print all 567 lines

这证实过滤器工作正常。

运行 Fail2ban

重启 Fail2ban 服务。 请注意,安装时已启动并启用以在系统引导时运行。

systemctl restart fail2ban

检查状态;

systemctl status fail2ban
● fail2ban.service - Fail2Ban Service      Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled)      Active: active (running) since Thu 2021-03-11 20:43:32 UTC; 44s ago        Docs: man:fail2ban(1)     Process: 5484 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)    Main PID: 5486 (f2b/server)       Tasks: 7 (limit: 2282)      Memory: 11.8M      CGroup: /system.slice/fail2ban.service              └─5486 /usr/bin/python3 /usr/bin/fail2ban-server -xf start  Mar 11 20:43:32 ubuntu20 systemd[1]: Starting Fail2Ban Service... Mar 11 20:43:32 ubuntu20 systemd[1]: Started Fail2Ban Service. Mar 11 20:43:33 ubuntu20 fail2ban-server[5486]: Server ready

检查已启用的 Fail2ban Jails

使用检查启用的监狱 fail2ban-client status 命令。

fail2ban-client status
Status |- Number of jail:	2 `- Jail list:	sshd, wordpress-auths

验证 WordPress 身份验证保护

您可以模拟 WordPress 多次失败身份验证的事件,以检查是否会发生任何禁止。

在跟踪日志并运行失败的登录测试时;

tail -f /var/log/apache2/wp.access.log | grep "POST /wp-login.php"
192.168.57.1 - - [11/Mar/2021:20:47:59 +0000] "POST /wp-login.php HTTP/1.1" 200 2825 "https://kifarunix-demo.com/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36" 192.168.57.1 - - [11/Mar/2021:20:48:02 +0000] "POST /wp-login.php HTTP/1.1" 200 2814 "https://kifarunix-demo.com/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36" 192.168.57.1 - - [11/Mar/2021:20:48:04 +0000] "POST /wp-login.php HTTP/1.1" 200 2825 "https://kifarunix-demo.com/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"

第三次登录失败后,我的IP被封锁并在浏览器上出现这样的错误;

检查Fail2ban禁止IP的状态

要检查被禁止的 IP 的状态,请使用 fail2ban-client 命令;

fail2ban-client status wordpress-auths
Status for the jail: wordpress-auths |- Filter |  |- Currently failed:	0 |  |- Total failed:	3 |  `- File list:	/var/log/apache2/wp.access.log `- Actions    |- Currently banned:	1    |- Total banned:	1    `- Banned IP list:	192.168.57.10

您可以使用获取监狱列表 fail2ban-client status 命令。

检查 Iptables;

iptables -L -nv
... Chain f2b-wordpress-auths (1 references)  pkts bytes target     prot opt in     out     source               destination             21  9078 REJECT     all  --  *      *       192.168.57.1         0.0.0.0/0            reject-with icmp-port-unreachable     0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

取消禁止 Fail2ban 被禁止的 IP

如果你想解封一个IP,运行命令;

fail2ban-client set <jail> unbanip <IP>
fail2ban-client set wordpress-auths unbanip 192.168.57.1

还有更多关于Fail2ban。 但这标志着我们关于如何使用 Fail2ban 保护 WordPress 免受暴力攻击的教程的结束。

进一步阅读

Fail2ban 手册

在 ELK Stack 上可视化 WordPress 用户活动日志

在 WordPress 报纸主题上创建滚动文本框

如何修复 WordPress 无法与 WordPress.org 建立安全连接

如何安装和使用 WPScan WordPress 漏洞扫描器 Ubuntu 18.04