Fail2Ban 是一个强大且灵活的工具,可以有效地保护服务器免受暴力破解等攻击。通过监控日志文件、设置规则和自动管理防火墙,Fail2Ban 为系统提供了一层额外的安全防护。

Nginx Proxy Manager(NPM)作为反向代理的 docker 容器可以通过网页界面简单地管理 SSL 证书和代理主机。所有它还是很受欢迎的。它还提供了一个名为 block common exploits 的简单功能,可阻止比较常见的攻击手段和漏洞。
本文主要已Ubuntu环境下的WordPress程序为例,WordPress 程序在访问 不存在(404)的页面时候,会导致服务器的CPU、内存等资源占用大增,通过Fail2ban与Cloudflare实现拦截404页面的功能。
/var/log/auth.log 或 /var/log/apache2/error.log),来检测是否有匹配特定攻击模式的记录。iptables)阻止恶意IP地址。也可以自定义其他动作,如发送通知、修改特定服务的配置等。在大多数Linux发行版中,可以直接通过包管理工具来安装Fail2Ban。以下是一些常见的安装命令:
Debian/Ubuntu:
sudo apt update
sudo apt install fail2ban CentOS/RHEL:
sudo yum install epel-release
sudo yum install fail2ban Fail2Ban 的主配置文件位于 /etc/fail2ban/jail.conf,但是为了防止在升级时被覆盖,建议将其复制为 /etc/fail2ban/jail.local ,然后在 jail.local 文件中进行自定义配置。
可以参考以下步骤:
复制配置文件:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local 修改 /etc/fail2ban/jail.local,自定义规则:
示例配置:
[DEFAULT]
bantime = 3600 # 禁止时间设置为1小时
findtime = 600 # 检查过去10分钟内的失败尝试
maxretry = 5 # 允许最多5次失败尝试
ignoreip = 127.0.0.1 # 忽略本地回环地址
[sshd]
enabled = true # 启用对SSH的监控
port = ssh # 监控的端口,默认为22
logpath = /var/log/auth.log
maxretry = 3 # SSH登录最多允许3次失败尝试 完成配置后,启用并启动Fail2Ban服务:
启动服务:
sudo systemctl start fail2ban 设置开机自启动:
sudo systemctl enable fail2ban 查看Fail2Ban的状态:
sudo fail2ban-client status 可以使用Fail2Ban提供的命令行工具 fail2ban-client 来管理和查看状态。
查看某个监控规则(如SSH)的状态:
sudo fail2ban-client status sshd 查看所有被禁止的IP:
sudo fail2ban-client status 手动禁止一个IP:
sudo fail2ban-client set sshd banip 192.168.1.100 手动解除对某个IP的禁令:
sudo fail2ban-client set sshd unbanip 192.168.1.100 如果默认的规则不够用,Fail2Ban允许自定义规则。你可以通过 filter.d 文件夹下的规则文件来定义新的日志匹配规则。例如,针对Apache的自定义规则可能如下:
创建一个新的过滤文件,例如 /etc/fail2ban/filter.d/apache-auth.conf:
[Definition]
failregex = ^<HOST> - - \[.*\] "POST /wp-login.php HTTP/.*" 401 在 jail.local 文件中,添加对应的 jail 规则:
[apache-auth]
enabled = true
filter = apache-auth
action = iptables-multiport[name=apache-auth, port="http,https"]
logpath = /var/log/apache*/*access.log
bantime = 3600
maxretry = 3 这段配置会监控Apache的访问日志,当某个IP尝试在 wp-login.php 页面多次失败登录时,将被暂时禁止。
上文中已介绍了在主机安装Fail2ban以及基础的配置方法,当然Fail2ban也有Docker版本,可以自行查询Docker 的应用,本文不做介绍,使用方法基本一致。现在开始做 fail2ban、Nginx Proxy Manager、Cloudflare 的配置。
使用cloudflare并且开启了小黄云,这样才能使用到它的Waf功能,也可以隐藏你的真实IP。
由于使用cloudflare 的cdn 功能,后端不能获取正确的ip地址,Cloudflare通常通过CF-Connecting-IP或X-Forwarded-For头传递真实的客户端IP。所有需要通过设置 real_ip_header CF-Connecting-IP; 来获取真实的客户端ip。添加这一主机头才能让NPM在网站访问日志中包含真实IP。
编辑 Nginx Proxy Manager 的代理主机,选择 Advanced 在Custom Nginx Configuration中添加以下配置:
# Cloudflare IPv4 addresses
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
# Cloudflare IPv6 addresses
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP; 当然Cloudflare的cdn 地址会经常性更新,可以通过官网给的地址自行更新,或者自行写个shell 脚本自动更新。官网cdn 网段发布页:[https://www.cloudflare.com/zh-cn/ips/]() 。
还是一种写法就是直接允许任意网段访问,但这种写法就好导致安全性降低。
# Cloudflare IPv4 and IPv6 addresses
set_real_ip_from 0.0.0.0/0;
set_real_ip_from ::/0;
real_ip_header CF-Connecting-IP; 在 /etc/fail2ban/jail.local 中新增以下内容:
[npm-4xx]
enabled = true # 启用此 jail
filter = npm-4xx # 使用的过滤器名称
port = http,https # 监控的端口(HTTP 和 HTTPS)
action = cloudflare-4xx # 当检测到恶意行为时采取的动作
logpath = /opt/npm/data/logs/proxy-host-3_access.log # Nginx 访问日志的路径
maxretry = 3 # 在 findtime 时间段内允许的最大失败次数
bantime = 900 # 被禁止的持续时间(以秒为单位,15分钟)
findtime = 3600 # 检查失败尝试的时间段(以秒为单位,1小时)
ignoreip = 172.17.0.1/24 192.168.0.1/24 # 忽略的 IP 地址或子网,这些 IP 不会被禁止 true 表示启用该 jail。nginx-4xx 过滤器需要在 /etc/fail2ban/filter.d/ 目录中定义。cloudflare-4xx 应该是一个自定义的动作,通常用于通过 Cloudflare API 禁止 IP。findtime 时间段内允许的最大失败次数,超过这个次数后,IP 将被禁止。logpath 这一项为Npm日志路径,如果你要监控所有站点的话需要把 proxy-host-3_access.log 改为 proxy-host-*_access.log 改为* 号即可。
在/etc/fail2ban/filter.d 目录下新增一个名为 npm-4xx.conf的配置文件,内容为拦截规则,支持正则表达式。
通用拦截规则:
[Definition]
failregex = ^.* "(GET|POST|HEAD).*HTTP.*" ([45]\d\d) .*
ignoreregex =.*(robots.txt|favicon.ico|jpg|png) Npm 使用规则:
在/etc/fail2ban/action.d中新建一个名为cloudflare-4xx.conf文件,(默认在此目录下也有一个cloudflare 的配置文件,以下配置改自此文件)内容如下:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -o /dev/null -X POST <_cf_api_prms> \
-d '{"mode":"<mode>","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"Fail2Ban <name>"}' \
<_cf_api_url>
actionunban = id=$(curl -s -X GET <_cf_api_prms> \
"<_cf_api_url>?mode=<mode>&configuration_target=<cftarget>&configuration_value=<ip>&page=1&per_page=1¬es=Fail2Ban%%20<name>" \
| { jq -r '.result[0].id' 2>/dev/null || tr -d '\n' | sed -nE 's/^.*"result"\s*:\s*\[\s*\{\s*"id"\s*:\s*"([^"]+)".*$/\1/p'; })
if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found"; exit 0; fi;
curl -s -o /dev/null -X DELETE <_cf_api_prms> "<_cf_api_url>/$id"
_cf_api_url = https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
_cf_api_prms = -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' -H 'Content-Type: application/json'
[Init]
cftoken = APIKEY00000ABC
cfuser = [email protected]
mode = block
cftarget = ip
[Init?family=inet6]
cftarget = ip6 以上配置中需要修改的的部分为 cftoken 、cfuser 和 mode 。

block。支持四种模式,分别是 "challenge"(质询)、"block"(阻止)、"whitelist"(白名单)、"js_challenge"(Javascript 质询)。配置好cloudflare-4xx文件后,可以自行测试,然后在cf后台,站点-安全性-事件中查看拦截记录。

Fail2Ban 是一个强大且灵活的工具,可以有效地保护服务器免受暴力破解等攻击。通过监控日志文件、设置规则和自动管理防火墙,Fail2Ban 为系统提供了一层额外的安全防护。

Nginx Proxy Manager(NPM)作为反向代理的 docker 容器可以通过网页界面简单地管理 SSL 证书和代理主机。所有它还是很受欢迎的。它还提供了一个名为 block common exploits 的简单功能,可阻止比较常见的攻击手段和漏洞。
本文主要已Ubuntu环境下的WordPress程序为例,WordPress 程序在访问 不存在(404)的页面时候,会导致服务器的CPU、内存等资源占用大增,通过Fail2ban与Cloudflare实现拦截404页面的功能。
/var/log/auth.log 或 /var/log/apache2/error.log),来检测是否有匹配特定攻击模式的记录。iptables)阻止恶意IP地址。也可以自定义其他动作,如发送通知、修改特定服务的配置等。在大多数Linux发行版中,可以直接通过包管理工具来安装Fail2Ban。以下是一些常见的安装命令:
Debian/Ubuntu:
sudo apt update
sudo apt install fail2ban CentOS/RHEL:
sudo yum install epel-release
sudo yum install fail2ban Fail2Ban 的主配置文件位于 /etc/fail2ban/jail.conf,但是为了防止在升级时被覆盖,建议将其复制为 /etc/fail2ban/jail.local ,然后在 jail.local 文件中进行自定义配置。
可以参考以下步骤:
复制配置文件:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local 修改 /etc/fail2ban/jail.local,自定义规则:
示例配置:
[DEFAULT]
bantime = 3600 # 禁止时间设置为1小时
findtime = 600 # 检查过去10分钟内的失败尝试
maxretry = 5 # 允许最多5次失败尝试
ignoreip = 127.0.0.1 # 忽略本地回环地址
[sshd]
enabled = true # 启用对SSH的监控
port = ssh # 监控的端口,默认为22
logpath = /var/log/auth.log
maxretry = 3 # SSH登录最多允许3次失败尝试 完成配置后,启用并启动Fail2Ban服务:
启动服务:
sudo systemctl start fail2ban 设置开机自启动:
sudo systemctl enable fail2ban 查看Fail2Ban的状态:
sudo fail2ban-client status 可以使用Fail2Ban提供的命令行工具 fail2ban-client 来管理和查看状态。
查看某个监控规则(如SSH)的状态:
sudo fail2ban-client status sshd 查看所有被禁止的IP:
sudo fail2ban-client status 手动禁止一个IP:
sudo fail2ban-client set sshd banip 192.168.1.100 手动解除对某个IP的禁令:
sudo fail2ban-client set sshd unbanip 192.168.1.100 如果默认的规则不够用,Fail2Ban允许自定义规则。你可以通过 filter.d 文件夹下的规则文件来定义新的日志匹配规则。例如,针对Apache的自定义规则可能如下:
创建一个新的过滤文件,例如 /etc/fail2ban/filter.d/apache-auth.conf:
[Definition]
failregex = ^<HOST> - - \[.*\] "POST /wp-login.php HTTP/.*" 401 在 jail.local 文件中,添加对应的 jail 规则:
[apache-auth]
enabled = true
filter = apache-auth
action = iptables-multiport[name=apache-auth, port="http,https"]
logpath = /var/log/apache*/*access.log
bantime = 3600
maxretry = 3 这段配置会监控Apache的访问日志,当某个IP尝试在 wp-login.php 页面多次失败登录时,将被暂时禁止。
上文中已介绍了在主机安装Fail2ban以及基础的配置方法,当然Fail2ban也有Docker版本,可以自行查询Docker 的应用,本文不做介绍,使用方法基本一致。现在开始做 fail2ban、Nginx Proxy Manager、Cloudflare 的配置。
使用cloudflare并且开启了小黄云,这样才能使用到它的Waf功能,也可以隐藏你的真实IP。
由于使用cloudflare 的cdn 功能,后端不能获取正确的ip地址,Cloudflare通常通过CF-Connecting-IP或X-Forwarded-For头传递真实的客户端IP。所有需要通过设置 real_ip_header CF-Connecting-IP; 来获取真实的客户端ip。添加这一主机头才能让NPM在网站访问日志中包含真实IP。
编辑 Nginx Proxy Manager 的代理主机,选择 Advanced 在Custom Nginx Configuration中添加以下配置:
# Cloudflare IPv4 addresses
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
# Cloudflare IPv6 addresses
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP; 当然Cloudflare的cdn 地址会经常性更新,可以通过官网给的地址自行更新,或者自行写个shell 脚本自动更新。官网cdn 网段发布页:[https://www.cloudflare.com/zh-cn/ips/]() 。
还是一种写法就是直接允许任意网段访问,但这种写法就好导致安全性降低。
# Cloudflare IPv4 and IPv6 addresses
set_real_ip_from 0.0.0.0/0;
set_real_ip_from ::/0;
real_ip_header CF-Connecting-IP; 在 /etc/fail2ban/jail.local 中新增以下内容:
[npm-4xx]
enabled = true # 启用此 jail
filter = npm-4xx # 使用的过滤器名称
port = http,https # 监控的端口(HTTP 和 HTTPS)
action = cloudflare-4xx # 当检测到恶意行为时采取的动作
logpath = /opt/npm/data/logs/proxy-host-3_access.log # Nginx 访问日志的路径
maxretry = 3 # 在 findtime 时间段内允许的最大失败次数
bantime = 900 # 被禁止的持续时间(以秒为单位,15分钟)
findtime = 3600 # 检查失败尝试的时间段(以秒为单位,1小时)
ignoreip = 172.17.0.1/24 192.168.0.1/24 # 忽略的 IP 地址或子网,这些 IP 不会被禁止 true 表示启用该 jail。nginx-4xx 过滤器需要在 /etc/fail2ban/filter.d/ 目录中定义。cloudflare-4xx 应该是一个自定义的动作,通常用于通过 Cloudflare API 禁止 IP。findtime 时间段内允许的最大失败次数,超过这个次数后,IP 将被禁止。logpath 这一项为Npm日志路径,如果你要监控所有站点的话需要把 proxy-host-3_access.log 改为 proxy-host-*_access.log 改为* 号即可。
在/etc/fail2ban/filter.d 目录下新增一个名为 npm-4xx.conf的配置文件,内容为拦截规则,支持正则表达式。
通用拦截规则:
[Definition]
failregex = ^.* "(GET|POST|HEAD).*HTTP.*" ([45]\d\d) .*
ignoreregex =.*(robots.txt|favicon.ico|jpg|png) Npm 使用规则:
在/etc/fail2ban/action.d中新建一个名为cloudflare-4xx.conf文件,(默认在此目录下也有一个cloudflare 的配置文件,以下配置改自此文件)内容如下:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -o /dev/null -X POST <_cf_api_prms> \
-d '{"mode":"<mode>","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"Fail2Ban <name>"}' \
<_cf_api_url>
actionunban = id=$(curl -s -X GET <_cf_api_prms> \
"<_cf_api_url>?mode=<mode>&configuration_target=<cftarget>&configuration_value=<ip>&page=1&per_page=1¬es=Fail2Ban%%20<name>" \
| { jq -r '.result[0].id' 2>/dev/null || tr -d '\n' | sed -nE 's/^.*"result"\s*:\s*\[\s*\{\s*"id"\s*:\s*"([^"]+)".*$/\1/p'; })
if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found"; exit 0; fi;
curl -s -o /dev/null -X DELETE <_cf_api_prms> "<_cf_api_url>/$id"
_cf_api_url = https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
_cf_api_prms = -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' -H 'Content-Type: application/json'
[Init]
cftoken = APIKEY00000ABC
cfuser = [email protected]
mode = block
cftarget = ip
[Init?family=inet6]
cftarget = ip6 以上配置中需要修改的的部分为 cftoken 、cfuser 和 mode 。

block。支持四种模式,分别是 "challenge"(质询)、"block"(阻止)、"whitelist"(白名单)、"js_challenge"(Javascript 质询)。配置好cloudflare-4xx文件后,可以自行测试,然后在cf后台,站点-安全性-事件中查看拦截记录。
