通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求

Mr.Bai 49 浏览 0

Fail2Ban 是一个强大且灵活的工具,可以有效地保护服务器免受暴力破解等攻击。通过监控日志文件、设置规则和自动管理防火墙,Fail2Ban 为系统提供了一层额外的安全防护。
通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求
Nginx Proxy Manager(NPM)作为反向代理的 docker 容器可以通过网页界面简单地管理 SSL 证书和代理主机。所有它还是很受欢迎的。它还提供了一个名为 block common exploits 的简单功能,可阻止比较常见的攻击手段和漏洞。

本文主要已Ubuntu环境下的WordPress程序为例,WordPress 程序在访问 不存在(404)的页面时候,会导致服务器的CPU、内存等资源占用大增,通过Fail2ban与Cloudflare实现拦截404页面的功能。

Fail2Ban 的工作原理

  1. 日志监控:Fail2Ban 会不断监控指定的日志文件(如 /var/log/auth.log/var/log/apache2/error.log),来检测是否有匹配特定攻击模式的记录。
  2. 触发规则:如果检测到某IP地址违反了预设的规则(如在一段时间内多次登录失败),Fail2Ban 就会执行特定的动作。
  3. 动作执行:默认情况下,Fail2Ban 会通过配置的防火墙(如 iptables)阻止恶意IP地址。也可以自定义其他动作,如发送通知、修改特定服务的配置等。
  4. 解禁:Fail2Ban 也支持设置自动解禁时间,禁止的IP可以在一段时间后自动解除限制。

Fail2Ban 安装与配置

1.安装Fail2Ban

在大多数Linux发行版中,可以直接通过包管理工具来安装Fail2Ban。以下是一些常见的安装命令:

  • Debian/Ubuntu:

    sudo apt update
    sudo apt install fail2ban
  • CentOS/RHEL:

    sudo yum install epel-release
    sudo yum install fail2ban

2.Fail2Ban的基本配置

Fail2Ban 的主配置文件位于 /etc/fail2ban/jail.conf,但是为了防止在升级时被覆盖,建议将其复制为 /etc/fail2ban/jail.local ,然后在 jail.local 文件中进行自定义配置。

可以参考以下步骤:

  1. 复制配置文件:

    sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  2. 修改 /etc/fail2ban/jail.local,自定义规则:

    • bantime: 设置禁止时间,单位是秒。默认是600秒(10分钟)。
    • findtime: 指定在多长时间内累积触发失败尝试才会触发禁用。
    • maxretry: 指定允许的最大失败尝试次数。
    • ignoreip: 设置永不被禁止的IP列表(如你自己的服务器IP)。

示例配置:

[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次失败尝试

3.启用Fail2Ban并启动服务

完成配置后,启用并启动Fail2Ban服务:

  • 启动服务:

    sudo systemctl start fail2ban
  • 设置开机自启动:

    sudo systemctl enable fail2ban
  • 查看Fail2Ban的状态:

    sudo fail2ban-client status

4.查看和管理被禁止的IP

可以使用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

典型使用场景

  1. SSH防护:Fail2Ban最常用于保护SSH服务器,防止暴力破解攻击。
  2. Web服务器防护:通过监控Nginx、Apache等Web服务器的日志,检测和阻止对登录页面、管理页面的攻击。
  3. 邮件服务器防护:Fail2Ban也能用来防御针对邮件服务器(如 Postfix、Dovecot)的暴力破解。

Fail2Ban的自定义规则

如果默认的规则不够用,Fail2Ban允许自定义规则。你可以通过 filter.d 文件夹下的规则文件来定义新的日志匹配规则。例如,针对Apache的自定义规则可能如下:

  1. 创建一个新的过滤文件,例如 /etc/fail2ban/filter.d/apache-auth.conf

    [Definition]
    failregex = ^<HOST> - - \[.*\] "POST /wp-login.php HTTP/.*" 401
  2. 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、Npm与Cloudflare

上文中已介绍了在主机安装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 的代理主机,选择 AdvancedCustom 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;

通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求

配置Fail2ban

配置jail

/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 不会被禁止
关键配置项
  1. enabled: 设置为 true 表示启用该 jail。
  2. filter: 指定使用的过滤器名称,nginx-4xx 过滤器需要在 /etc/fail2ban/filter.d/ 目录中定义。
  3. port: 指定要监控的端口,通常是 HTTP 和 HTTPS。
  4. action: 指定在检测到恶意行为后采取的动作,cloudflare-4xx 应该是一个自定义的动作,通常用于通过 Cloudflare API 禁止 IP。
  5. logpath: 指定要监控的 Nginx 访问日志的路径,确保该路径正确且 Nginx 正在记录日志。
  6. maxretry: 在 findtime 时间段内允许的最大失败次数,超过这个次数后,IP 将被禁止。
  7. bantime: 被禁止的持续时间(以秒为单位),在这个配置中是 900 秒(15 分钟)。
  8. findtime: 检查失败尝试的时间段(以秒为单位),在这个配置中是 3600 秒(1 小时)。
  9. ignoreip: 指定要忽略的 IP 地址或子网,这些 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 使用规则:

此部分已被隐藏

发表评论刷新页面后方可查看

配置cloudflare

/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&notes=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

以上配置中需要修改的的部分为 cftokencfusermode

  • cftoken 需要到cf后台右上角我的个人资料,选择左侧API令牌,获取Global API Key。https://dash.cloudflare.com/login
    通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求
  • cfuser 为你绑定Cloudflare 的邮箱账户。
  • mode 为防火墙的动作,默认为block。支持四种模式,分别是 "challenge"(质询)、"block"(阻止)、"whitelist"(白名单)、"js_challenge"(Javascript 质询)。

配置好cloudflare-4xx文件后,可以自行测试,然后在cf后台,站点-安全性-事件中查看拦截记录。
通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求

温馨提示

注:CloudFlare API 调用有限制,5 分钟内最多 1200 次,可以调低,调高也没用。

Block响应效果

通过配置Ngixn Proxy Manager 与 Fail2ban 实现在 Cloudflare 上拦截恶意请求
页面显示(Access denied)

参考链接

  1. https://www.cloudflare.com/
  2. https://nginxproxymanager.com/
  3. https://github.com/fail2ban/fail2ban
  4. https://blog.lrvt.de/fail2ban-with-nginx-proxy-manager/
  5. https://vircloud.net/operations/cfapi-add-rules.html#selection-463.0-463.20

发表评论 取消回复
表情 图片 链接 代码

分享
请选择语言