如何防止黑客利用xmlrpc.php接口分布式暴力破解WordPress网站?

AI 概述
简单 5 个步骤第一步:启用并配置防火墙 UFW第二步:修改 Nginx 配置,记录更详细的日志第三步:配置 Fail2ban第四步:设置白名单并重启 Fail2ban第五步:检查封禁效果 我们在搭建好了 wordpress 个人网站后,但没过多久,就会收到了服务器提供商告警:CPU 资源占用过高。通过日志排查(进入“my_websit...
目录
文章目录隐藏
  1. 简单 5 个步骤

我们在搭建好了 wordpress 个人网站后,但没过多久,就会收到了服务器提供商告警:CPU 资源占用过高。通过日志排查(进入“my_website”文件夹后,输入命令:docker logs wordpress_nginx 2>&1 | tail -n 500),锁定为:黑客暴力攻击式刷 xmlrpc.php 接口(日志中能看到很多个 ip,不停的重复 POST,类似这样:POST //xmlrpc.php HTTP/1.1…)。

如何防止黑客利用 xmlrpc.php 接口分布式暴力破解 WordPress 网站?

xmlrpc.php 是什么?

xmlrpc.php 是 WordPress 提供的一个早期 API 接口,用于允许远程发布(例如通过手机 App 发文章),而黑客利用这个接口,通过一次 POST 请求就可以尝试成百上千个用户名和密码的组合,这比攻击登录页面 wp-login.php 效率高得多。

我的网站虽然设置了每秒 10 个请求的限制,但攻击者用更低的频率攻击,且采用大量 ip 分布式攻击的方式,并掌握了管理员用户名(通过访问 https://xxx.com/?author=1 获取),理论上,只要时间充足,密码一定会被攻破。又因为网站设置主要缓存静态资源,不缓存动态请求,每一次 POST 请求,Nginx 都会把它转发给后面的 WordPress (PHP-FPM) 处理。WordPress 需要连接数据库、验证信息,这个过程会消耗大量的 CPU 和内存,所以导致 CPU 资源占用过高告警。

要解决这个问题,其实有个很简单的解决方案:直接在 Nginx 层拒绝任何对 xmlrpc.php 这个文件的访问,然后只通过 WordPress 后台发布文章就行了。但我个人还是有用到 xmlrpc 接口的场景,所以不能完全封堵了。通过咨询 AI,我找到了“Nginx + Fail2ban”方案,完美解决了现阶段的需求。本篇文章主要记录:使用“Nginx + Fail2ban”方案,解决黑客利用 xmlrpc.php 接口、wp-login.php 页面暴力破解 WordPress 网站的问题。

简单 5 个步骤

  1. 启用并配置防火墙 UFW;
  2. 修改 Nginx 配置,记录更详细的日志;
  3. 配置 Fail2ban;
  4. 设置白名单并重启 Fail2ban;
  5. 检查封禁效果。

第一步:启用并配置防火墙 UFW

  1. 安装:
    apt update && apt install ufw
    
  2. 设置默认规则:
    ufw default deny incoming
    ufw default allow outgoing
    
  3. 开放必要端口:
    ufw allow ssh
    ufw allow http
    ufw allow https
    
  4. 启用 (请确保已放行 SSH):
    ufw enable
    
  5. 检查状态:
    ufw status
    

第二步:修改 Nginx 配置,记录更详细的日志

为了让 Fail2ban 能更好地工作,我们需要让 Nginx 在日志中记录 POST请求的具体内容。这会稍微增加日志文件的大小,但对于安全来说是值得的。

  1. 修改 Nginx 主配置文件 nginx.conf我们需要修改 Nginx 的主配置文件,而不是我们站点的 app.conf。由于我们在 Docker 中运行,这个文件在容器内部。最简单的办法是把它复制出来,修改,然后通过卷映射挂载回去。从容器中复制 nginx.conf到宿主机
    cd ~/my_website
    # 为主配置文件创建一个目录
    mkdir -p ./nginx/main-conf
    # 从正在运行的 nginx 容器中复制文件
    docker cp wordpress_nginx:/etc/nginx/nginx.conf ./nginx/main-conf/nginx.conf
    

    编辑复制出来的 nginx.conf

    nano ./nginx/main-conf/nginx.conf
    

    找到 log_format main,修改为(即末尾添加 $request_body变量,让它记录 POST 的内容):

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" "$request_body"';
    
  2. 修改 docker-compose.yml 挂载配置在 my_website 目录下创建日志文件夹:
    mkdir -p ./nginx/logs
    

    修改 docker-compose.yml,为 nginx 服务添加日志卷映射,和挂载我们修改后的 nginx.conf

    nano docker-compose.yml
    

    在 nginx 服务的 volumes 部分,新增两行:

    volumes:
    -./nginx/main-conf/nginx.conf:/etc/nginx/nginx.conf:ro# <--- 新增
    -./nginx/logs:/var/log/nginx# <--- 新增
    -./nginx/conf.d:/etc/nginx/conf.d
    
  3. 切换网络模式为 host
    (删除 ports,添加 network_mode)我们让 Nginx 容器直接使用宿主机的网络。这样,Nginx 就能直接看到来自外部的、未经 Docker NAT 转换的原始请求,从而获取到真实的客户端公网 IP。继续对 docker-compose.yml 中的 nginx 服务进行如下修改: a. 删除 ports 部分:在 host 模式下,容器直接监听宿主机的端口,不再需要端口映射。 b. 添加 network_mode: “host”。 c. 修改 wordpress 的连接方式:由于 Nginx 现在和宿主机在同一个网络命名空间,它不能再通过服务名 wordpress 来连接了。它需要通过宿主机的 localhost (127.0.0.1) 和 WordPress 容器映射出来的端口来连接。所以我们也要修改 wordpress 服务。请将 docker-compose.yml 文件中的 nginx 和 wordpress 服务部分,修改为以下内容:

    wordpress:
    image:wordpress:php8.2-fpm
    container_name:wordpress_fpm
    restart:always
    # 新增 ports 映射,让 fpm 的 9000 端口暴露给宿主机
    ports:
    -"127.0.0.1:9000:9000"
    depends_on:
    -db
    volumes:
    -./wordpress/html:/var/www/html
    environment:
    WORDPRESS_DB_HOST:db:3306
    WORDPRESS_DB_USER:'wordpress_user'
    WORDPRESS_DB_PASSWORD:'YOUR_STRONG_USER_PASSWORD'
    WORDPRESS_DB_NAME:'wordpress'
    # wordpress 仍然在 app-network 中,以便连接 db
    networks:
    -app-network
    
    nginx:
    image:nginx:1.27.0-alpine
    container_name:wordpress_nginx
    restart:always
    # 关键修改:使用 host 网络模式
    network_mode:"host"
    # 不再需要 ports 映射
    # ports:
    #   - "80:80"
    #   - "443:443"
    volumes:
    -./nginx/main-conf/nginx.conf:/etc/nginx/nginx.conf:ro
    -./nginx/logs:/var/log/nginx
    -./nginx/conf.d:/etc/nginx/conf.d
    -./nginx/cache:/var/cache/nginx
    -./wordpress/html:/var/www/html:ro
    -./certbot/conf:/etc/letsencrypt
    -./certbot/www:/var/www/certbot
    # 在 host 模式下,nginx 不再属于 app-network
    # networks:
    #   - app-network
    
  4. 修改 Nginx 站点配置文件 app.conf由于 Nginx 现在需要通过 localhost 来连接 WordPress,我们需要修改 PHP-FPM 的转发地址。
    nano ./nginx/conf.d/app.conf
    

    找到 location ~ \.php$ { … } 块,将 fastcgi_pass wordpress:9000; 修改为 fastcgi_pass 127.0.0.1:9000;

    location ~ \.php$ {
        # ... (其他配置) ...
        # 连接到宿主机的 9000 端口,该端口已映射到 WordPress 容器
        fastcgi_pass 127.0.0.1:9000;
        # ... (其他配置) ...
    }
    
  5. 重启
    docker compose down
    docker compose up -d
    

第三步:配置 Fail2ban

  1. 安装:
    apt install fail2ban -y
    
  2. 创建 jail 配置:
    nano /etc/fail2ban/jail.d/wordpress-zerotolerance.conf
    

    将以下定制好的内容粘贴进去:

    [wordpress-xmlrpc]
    enabled  = true
    port     = http,https
    filter   = wordpress-xmlrpc
    logpath  = /root/my_website/nginx/logs/access.log
    # 任何一次匹配都立即触发
    maxretry = 1
    # 封禁时间为 30 天
    bantime  = 30d
    # findtime 在 maxretry=1 时意义不大,但最好保留
    findtime = 1m
    
    [wordpress-login]
    enabled  = true
    port     = http,https
    filter   = wordpress-login
    logpath  = /root/my_website/nginx/logs/access.log
    # 任何一次匹配都立即触发
    maxretry = 1
    # 封禁时间为 1 天
    bantime  = 1d
    findtime = 1m
    
  3. 创建对应的 filter (过滤器) 文件为 xmlrpc.php 创建 filter
    nano /etc/fail2ban/filter.d/wordpress-xmlrpc.conf
    

    粘贴以下内容:

    [Definition]
    failregex = ^<HOST> - .* "POST /+xmlrpc.php HTTP/.*
    ignoreregex =
    

    以及为 wp-login.php 创建 filter

    nano /etc/fail2ban/filter.d/wordpress-login.conf

    粘贴以下内容:

    [Definition]
    failregex = ^<HOST> - .* "POST /+wp-login.php.*
    ignoreregex =
    

第四步:设置白名单并重启 Fail2ban

这一步至关重要,防止你被自己锁在外面。

  1. 编辑 jail.local 添加你自己的 IP
    nano /etc/fail2ban/jail.local
    

    找到或添加 ignoreip 这一行,并加上你自己的本机 IP 段(百度“ip”,家用宽带动态 ip 前 3 段一般不变,最后一段全包含即可,比如百度查询到你此时的 ip 是:117.100.100.100,那么加白的 ip 段可以填:117.100.100.0/24)。

    [DEFAULT]
    ignoreip = 127.0.0.1/8 ::1117.100.100.0/24
    
  2. 重启 Fail2ban 使所有配置生效
    systemctl restart fail2ban
    
  3. 检查 Fail2ban 状态
    fail2ban-client status
    

    你应该能看到 Jail list: 下面有 wordpress-login 和 wordpress-xmlrpc 这两个活动的 jail。

第五步:检查封禁效果

wp-login.php 封禁验证:

a. 进行测试:

  • 用你的手机网络(不要用常用 Wi-Fi)访问 https://xxx.com/wp-login.php。
  • 只输入一次错误的密码。
  • 然后尝试刷新页面或再次访问。你应该会发现网站已经无法访问了。
  • 回到服务器,执行 fail2ban-client status wordpress-login,你会看到你手机的 IP 已经被列入了封禁列表。

b. 练习解封:

既然测试成功了,就练习一下解封自己的手机 IP 吧。

# 假设你手机 IP 是 222.222.222.222
fail2ban-client unban 222.222.222.222

xmlrpc.php 封禁验证:

打开 2 个 SSH 终端连接服务器窗口,一个用来操作登录,另一个用来看日志。

  1. 监控日志:
    tail -f /root/my_website/nginx/logs/access.log
  2. 等待新的攻击日志出现。当下一条类似 5.101.157.127 … “POST /xmlrpc.php …” 的日志出现时,Fail2ban 就会立刻匹配到它。
  3. 检查 Fail2ban 状态:
    稍等片刻后,再次执行:

    fail2ban-client status wordpress-xmlrpc

这一次,你应该会看到 Currently failed 和 Total failed 的计数增加了,并且 Banned IP list 中出现了新的被封禁的 IP。

以上关于如何防止黑客利用xmlrpc.php接口分布式暴力破解WordPress网站?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 如何防止黑客利用xmlrpc.php接口分布式暴力破解WordPress网站?

发表回复