WordPress 教程

WordPress 网站被攻击了怎么办:从判断到止血

网站突然打不开、CPU 跑满、数据库连接数爆掉——多数时候不是被 DDoS,而是被 CC 或爬虫。这篇讲怎么在五分钟内判断攻击类型,以及对应每一种的止血动作。

约 12 分钟读完

01第一步:别急着上防护,先判断是什么

把「网站慢」笼统当成「被攻击」是最常见的误判。先看这三个指标,基本能定位方向:

现象大概率原因首要动作
CPU 跑满但带宽正常CC 攻击 / 恶意爬虫持续请求动态页面看访问日志里的 IP 与 URL 分布
带宽跑满、入流量异常DDoS 流量攻击联系主机商 / 上高防 IP
数据库连接数爆满未缓存的动态查询被高频触发开页面缓存 + 限流
后台登录页大量失败记录暴力破解限制登录尝试 + 改登录地址
突然出现大量陌生管理员账号已经被攻破立刻改密码、查后门文件

如果已经出现陌生管理员账号或可疑的定时任务,说明不是「正在被攻击」而是「已经被攻破」。这时候先隔离(暂停站点或改数据库密码),再谈防护,顺序不能反。

02第二步:从访问日志读出攻击特征

命令行快速统计(把日志路径换成你自己的):

  1. 1统计访问量最高的 20 个 IP:对 access log 按第一列排序后计数取头部。
  2. 2统计被请求最多的 URL:按请求行字段排序后计数。
  3. 3看是否有单 IP 请求量占总请求量 20% 以上的情况 —— 这就是攻击源特征。
  • 同一 IP 的高频请求:正常用户不会在 10 秒内请求 200 次页面
  • 被集中的 URL:如果请求都压向 `wp-login.php`、`xmlrpc.php`、搜索页 `?s=`,那是针对性的资源消耗攻击
  • UA 特征:空 UA、伪造 UA、以及自称各种「SEO 工具」「AI 爬虫」的高频访问,多数是恶意抓取

03第三步:两层防护的思路 —— 限流 + 熔断

很多安全插件的做法是「每来一个请求就判断一次规则」,这在高频攻击下本身就是负担:判断逻辑跑在 PHP 里,攻击流量依然会打到 PHP,站点照样会被拖垮。

更合理的结构是两层:

判断防护插件好不好用的一个标准:看它是否在「不加载 WordPress 完整内核」的阶段就能拒绝请求。如果所有判断都要走完 PHP 初始化,攻击量大时它自己也扛不住。

第一层:全局 QPS 硬闸门

在所有业务逻辑之前设一个全站每秒请求数上限。超过阈值直接快速拒绝,不进入 WordPress 初始化流程。这一层的目的是「保命」——哪怕误伤一部分正常访客,也要先让服务器活下来。

第二层:智能动态限流

针对单个 IP / 单会话做频率约束,并且阈值要能根据站点当下的压力动态调整。压力低时宽松,攻击时收紧。这样正常时段不会有误伤,攻击时段能自动加严。

04第四步:别忽略的几个低垂果实

  • 禁用 XML-RPC:如果不用桌面客户端发文,`xmlrpc.php` 只有坏处没有好处,它是暴力破解的高频入口。
  • 限制登录尝试:失败若干次后锁定该 IP 一段时间,能挡掉绝大多数自动化爆破。
  • 改掉默认登录地址:`/wp-admin` 和 `/wp-login.php` 是扫描器的默认目标,换一个入口能直接过滤掉大量无差别扫描。
  • 关闭目录索引:避免 `wp-content/uploads` 被直接列目录。
  • 定时任务查一遍:`wp-cron` 里被插入的恶意任务往往是后门持续性的来源。

05第五步:IP 归属地追踪有什么用

知道攻击来自哪些地区不是为了「封整个地区」——那会误伤真实用户。它的实际用途是:

  • 判断是不是针对性攻击:攻击 IP 高度集中在少数几个机房段,通常是有组织的资源消耗,而不是随机扫描
  • 决定要不要上高防:如果攻击源分散在大量不同地区的住宅 IP,靠 IP 黑名单是挡不住的,需要靠行为限流
  • 给主机商报障时提供证据:有归属地分布的数据,主机商更容易判断是否需要上游清洗

06为什么不建议只靠 Cloudflare 免费版

比较务实的组合是:源站做限流熔断(保证活下来)+ CDN 做前置过滤(减少无效流量)+ 隐藏源站 IP(防止被绕过)。三层各司其职。

  • 在国内访问的延迟可能反而变高,用户体验受损
  • 免费版对 CC 攻击的防护能力有限,且没有细粒度的按路径限流
  • 所有请求仍会回源到你的服务器,源站 IP 一旦泄露,攻击者可以绕过 CDN 直打源站
  • 被误封的正常访客无法自助申诉,容易造成真实流量损失

常见问题

WordPress 被 CC 攻击,最有效的止血动作是什么?+

先开启全局 QPS 上限把服务保住,再按访问日志找出高频 IP 与被打的 URL,针对性地做单 IP 限流。不要一上来就封整个 IP 段,容易误伤真实访客。

开了防护插件之后正常访客会不会被误封?+

取决于阈值设置。合理的做法是把「全局熔断」阈值设得较高(只在真正过载时触发),把「单 IP 限流」设得较细(按正常人类浏览频率的 3 到 5 倍),这样正常时段几乎不会误伤。

怎么区分正常爬虫和恶意爬虫?+

看三个维度:请求频率(正常爬虫有 crawl-delay 概念)、请求范围(正常爬虫会遍历全站,恶意爬虫只打搜索页和动态参数)、UA 与 IP 反查是否一致(伪造 UA 的爬虫,其 IP 反查结果与自称的身份对不上)。

网站被打的时候 PHP 进程全占满,插件还起得了作用吗?+

如果防护逻辑放在 WordPress 内核加载之后,就起不了作用。要选在更早阶段就能拒绝请求的方案——全局 QPS 闸门应该在加载完整 PHP 应用之前生效,攻击流量不落地 PHP 才叫真防护。

怎么判断站点是否已经被攻破?+

检查后台用户列表是否有陌生管理员、wp-cron 是否有可疑定时任务、主题与插件目录是否有近期被改动的文件、以及数据库里是否出现陌生的 option 记录。发现任何一项都应按「已攻破」处理。

继续阅读