高级管理文档

暴力破解攻击

💡 云策文档标注

概述

本文档针对 WordPress 网站面临的暴力破解攻击,提供了 2025 年的最佳实践防御指南。攻击者通过自动化尝试用户名/密码组合来入侵,文档强调采用多层次防护策略,包括 WordPress 层面、服务器/代理/WAF 层面的措施,并推荐优先使用边缘防护以减轻服务器负载。

关键要点

  • 使用强密码、密码管理器和双因素认证(2FA)来增强登录安全。
  • 考虑使用 Passkeys(WebAuthn)实现防钓鱼的无密码登录。
  • 在边缘(WAF/CDN)或服务器层面实施登录尝试速率限制。
  • 在登录页面添加 CAPTCHA/turnstile 以减缓机器人攻击。
  • 保护或禁用 XML-RPC,除非必要,并对其进行限制和速率限制。
  • 保持 WordPress 核心、主题和插件更新。
  • 监控认证异常并临时封禁滥用 IP。
  • 优先使用边缘/WAF 防护(如 Cloudflare、Sucuri)以在流量到达服务器前拦截恶意请求。

代码示例

# Apache 示例:限制 IP 访问 wp-login.php
<Files "wp-login.php">
    Require ip 203.0.113.15 203.0.113.16
</Files>

# Nginx 示例:速率限制登录和 XML-RPC
limit_req_zone $binary_remote_addr zone=logins:10m rate=10r/m;
location = /wp-login.php {
    limit_req zone=logins burst=20 nodelay;
    include fastcgi_params;
}

# Caddy 示例:基于 IP 限制访问 wp-login.php
@blacklist {
    not client_ip forwarded 203.0.113.15 203.0.113.16
    path /wp-login.php
}
respond @blacklist "Forbidden" 403 {
    close
}

# Windows IIS 示例:通过 web.config 限制 wp-admin 访问
<location path="wp-admin">
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="false">
        <add ipAddress="203.0.113.15" allowed="true" />
        <add ipAddress="203.0.113.16" allowed="true" />
      </ipSecurity>
    </security>
  </system.webServer>
</location>

注意事项

  • 避免使用 admin 作为用户名,创建独立的管理员账户并降级或移除旧用户。
  • 限制管理员数量,日常工作中使用最小权限角色。
  • 审计失败登录日志并枚举来源,使用 Fail2ban 等工具临时封禁滥用 IP。
  • 避免使用永久性国家 IP 封锁列表,以免误封合法用户且难以维护。
  • 确保全站使用 HTTPS 以保护传输中的凭据。
  • 维护经过测试的离线备份并演练恢复流程。
  • 过时的防护方法(如重写 .htaccess、国家 IP 封锁)可能不可靠或破坏插件功能,建议优先采用边缘防护、2FA 和针对性速率限制。

📄 原文内容

A brute force attack is the simplest way to break in: an attacker repeatedly tries username/password combinations until one works. Because these attempts are automated and often distributed (botnets), even unsuccessful attacks can overwhelm your site with requests.

This is not unique to WordPress—every web application that exposes a login surface can be targeted—but WordPress’s popularity makes it a common focus. The guidance below reflects current best practices for WordPress sites in 2025 and replaces older, more fragile techniques.


Key Defenses at a Glance

  • Use strong, unique passwords and a password manager.
  • Enable two‑factor authentication (2FA) for all administrator accounts (use a plugin or your identity provider; WordPress core does not include 2FA).
  • Consider passkeys (WebAuthn) via a reputable plugin for phishing‑resistant login.
  • Rate‑limit login attempts at the edge (WAF/CDN) or the web server.
  • Put a CAPTCHA/turnstile on login to slow bots (e.g., Cloudflare Turnstile, reCAPTCHA).
  • Protect or disable XML‑RPC if you don’t need it; otherwise restrict and rate‑limit it.
  • Keep WordPress core, themes, and plugins up to date.
  • Monitor and alert on authentication anomalies; ban abusive IPs temporarily.
  • Prefer edge/WAF protections (Cloudflare, Sucuri, host‑provided WAF) so bad traffic is blocked before it reaches your server.

Tip: Obscuring the login URL can reduce noise but should not be your only defense.


WordPress‑Level Protections

Enforce Strong Passwords

WordPress shows a strength meter when changing passwords. Encourage unique, long passwords (or passphrases) and the use of password managers. Avoid dictionary words and personal info.

Two‑Factor Authentication (2FA)

Enable 2FA for all administrators and privileged users using a reputable plugin or your identity provider (TOTP app, hardware key, SMS fallback). As of 2025, WordPress core does not ship 2FA; it must be added via a plugin or SSO/IdP.

Passkeys (WebAuthn)

Passkeys provide phishing‑resistant, passwordless login using platform authenticators (Face ID/Touch ID, Windows Hello, security keys). Add via a maintained plugin that supports WebAuthn/Passkeys and enroll at least two authenticators per admin.

Application Passwords (for Integrations)

For API access by trusted apps/services, use Application Passwords (introduced in WordPress 5.6). They scope access and can be revoked without changing your user password.

Limit Login Attempts (App Layer)

If your host/CDN doesn’t rate‑limit at the edge, a security plugin can throttle login attempts. Note that app‑level plugins still execute within PHP and thus consume some resources under heavy attack; prefer edge or server‑level throttling when possible.

XML‑RPC Considerations

xmlrpc.php is a frequent brute‑force target (especially the system.multicall method). If you don’t use XML‑RPC, disable it. If you do (e.g., Jetpack, mobile apps), restrict it (WAF rules) and rate‑limit aggressively.


Server / Proxy / WAF Protections

These examples require server or proxy access and may vary by environment. Test in staging before applying to production.

Apache (examples)

Block or rate‑limit abusive login attempts (examples require appropriate modules such as mod_rewrite, mod_authz_host, or third‑party tools like ModSecurity or mod_evasive).

Deny by IP (Apache 2.4+):

# wp-login.php: allow specific IPs only
<Files "wp-login.php">
    Require ip 203.0.113.15 203.0.113.16
</Files>

Send 401/403 to a static error page:

ErrorDocument 401 /401.html
ErrorDocument 403 /403.html

Consider ModSecurity rulesets (e.g., OWASP CRS) to detect and block brute‑force patterns at the server layer.

Nginx (examples)

Rate‑limit login and XML‑RPC:

# Define a shared zone for rate limiting
limit_req_zone $binary_remote_addr zone=logins:10m rate=10r/m;

server {
    # ...

    location = /wp-login.php {
        limit_req zone=logins burst=20 nodelay;
        include fastcgi_params;
        # pass to PHP-FPM or upstream as usual
    }

    location = /xmlrpc.php {
        limit_req zone=logins burst=20 nodelay;
        include fastcgi_params;
        # pass to PHP-FPM or upstream as usual
    }
}

Deny by IP:

location = /wp-login.php {
    allow 203.0.113.15;
    allow 203.0.113.16;
    deny all;
    # pass to PHP-FPM or upstream as usual
}

Custom error pages:

error_page 401 /401.html;
error_page 403 /403.html;

Caddy (v2) (examples)

Password‑protect /wp-login.php with Basic Auth:

# Hash passwords first: `caddy hash-password`
basicauth /wp-login.php {
    user1 JDJhJDEw$example-hash-value...
    # add more users as needed (one per line)
}

Caddy requires hashed passwords in the Caddyfile.

Limit access to /wp-login.php by IP:

@blacklist {
    not client_ip forwarded 203.0.113.15 203.0.113.16
    path /wp-login.php
}
respond @blacklist "Forbidden" 403 {
    close
}

Return 401 for /wp-admin/* and serve a custom error page:

@wpadmin path /wp-admin/*
respond @wpadmin "Unauthorized" 401

handle_errors {
    @need401 status 401
    rewrite @need401 /401.html
    file_server
}

Deny “no‑referrer” POSTs to login/comments (optional, use with caution):

# Legitimate clients or privacy tools may omit Referer; test before enforcing.
@protected path_regexp protected (wp-comments-post|wp-login).php$
@no_referer {
    not header Referer https://{host}*
    method POST
}
abort @no_referer

Using abort immediately drops the connection, which is efficient for bots.

For more Caddy discussion and rationale, see: Using Caddy to deter brute force attacks in WordPress (community thread).

Windows IIS (examples)

Restrict WP Admin by IP using web.config:

<location path="wp-admin">
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="false">
        <add ipAddress="203.0.113.15" allowed="true" />
        <add ipAddress="203.0.113.16" allowed="true" />
      </ipSecurity>
    </security>
  </system.webServer>
</location>

Custom 401 page:

<system.webServer>
  <httpErrors errorMode="Custom">
    <remove statusCode="401" />
    <error statusCode="401" path="/401.html" responseMode="File" />
  </httpErrors>
</system.webServer>

Host / CDN WAF Protections

A managed WAF (Cloudflare, Sucuri, or your hosting provider) can:
– Filter known bad IPs and automated login attempts at the edge.
– Enforce bot management, challenge‑pages, and login‑specific rules.
– Apply rate limits to /wp-login.php and /xmlrpc.php globally.
– Add CAPTCHA/turnstile challenges for suspicious requests.

Advantage: traffic is blocked before reaching your server, preserving resources during high‑volume attacks.


Additional Hardening & Operational Tips

  • Do not use the username admin. Create a separate admin account and demote or remove legacy users.
  • Limit administrator count; use least‑privilege roles for day‑to‑day work.
  • Audit logs for failed logins and enumerate sources; temporarily block abusive IPs (e.g., Fail2ban).
  • Avoid permanent country blocklists. They can block legitimate users and are difficult to maintain.
  • Ensure HTTPS everywhere to protect credentials in transit.
  • Backups: Maintain tested, offline‑capable backups and rehearse restore procedures.

See Also


Notes on Deprecated / Legacy Content

Older guidance often recommended heavy .htaccess rewrites, country IP blocklists, or BasicAuth over the entire /wp-admin directory. Today these measures are either unreliable, break AJAX‑based plugins, or degrade user experience. Prefer edge‑level WAF, 2FA, passkeys, and targeted rate‑limiting instead. When you do apply server‑level blocks, scope them narrowly (e.g., /wp-login.php, /xmlrpc.php) and document exceptions your site needs (mobile apps, Jetpack, SSO).