保哥笔记

WordPress网站DDoS攻击防御实战指南:从识别到拦截的全流程方案

做网站这么多年,保哥见过各种各样的攻击场景。有些站长打开后台发现网站突然变慢,以为是服务器问题;有些人收到主机商的告警邮件,才知道网站已经被打了好几个小时。DDoS攻击这个东西,不遇到的时候觉得离自己很远,真遇上了又手忙脚乱。

这篇文章,保哥不讲那些泛泛而谈的概念,而是从实际运维经验出发,帮你搞清楚三个核心问题:怎么判断你的WordPress网站是不是正在被DDoS攻击?遇到攻击该怎么紧急处理?日常应该部署哪些防御措施?

什么是DDoS攻击?为什么WordPress网站是重灾区

DDoS的全称是Distributed Denial of Service,翻译过来就是"分布式拒绝服务攻击"。通俗来讲,攻击者操控大量被恶意软件感染的设备(称为"僵尸网络"),在同一时间向你的网站发送海量请求,把你服务器的带宽、CPU、内存等资源全部占满,导致正常用户根本无法访问。

举个生活中的例子:你开了一家小餐馆,正常情况下接待30位客人没问题。但突然有人组织了3000个人同时涌进来,虽然他们不是来吃饭的,但把门堵死了,真正想吃饭的客人根本进不来。这就是DDoS攻击的本质。

WordPress为什么特别容易中招

WordPress占据了全球超过43%的网站市场份额,这意味着攻击者研究一套针对WordPress的攻击方法,就能覆盖几乎一半的互联网。具体原因包括:

动态页面机制的天然短板。 WordPress每次请求都要经过PHP解析和MySQL查询,相比纯静态页面,消耗的服务器资源高出很多。攻击者不需要太大的流量就能让一台配置不高的服务器瘫痪。

xmlrpc.php接口的历史遗留问题。 这个文件本来是用来支持远程发布文章的,但它允许单次请求中携带多个方法调用,攻击者可以利用它做放大攻击。一个请求进来,服务器端可能要执行几十次操作。

插件和主题的安全短板。 很多WordPress站长为了功能方便,装了大量第三方插件,其中不少插件存在安全漏洞。攻击者可以利用这些漏洞作为跳板,甚至把你的服务器变成僵尸网络的一部分。说到WordPress漏洞修复,保哥之前处理过一个比较典型的案例,就是WordPress的post.php任意文件删除漏洞修复,这类漏洞如果不及时修补,攻击者甚至可以拿到管理员权限后进一步发起内部攻击。

登录页面暴露在外。 默认的 /wp-login.php/wp-admin/ 路径全世界都知道,成为暴力破解和CC攻击的首选目标。

DDoS攻击的常见类型

在做防御之前,你需要了解攻击者常用的手段,才能对症下药:

流量型攻击(Volumetric Attacks)。 这是最常见的类型,包括UDP洪水、ICMP洪水、DNS放大攻击等。攻击者通过发送大量无效数据包,把你的网络带宽彻底占满。这种攻击的特点是流量巨大,动辄几十Gbps,普通服务器完全扛不住。

协议型攻击(Protocol Attacks)。 主要针对服务器的网络协议栈,比如SYN洪水攻击。攻击者发送大量半开连接请求,耗尽服务器的连接表资源。表现为服务器的TCP连接数暴增,但每个连接都不完成三次握手。

应用层攻击(Application Layer Attacks)。 这是WordPress站长最常遇到的类型,也叫CC攻击(Challenge Collapsar)。攻击者模拟正常的HTTP请求,反复访问你网站的动态页面(比如搜索页面、登录页面),每个请求看起来都是合法的,但数量巨大。由于每个请求都要消耗PHP和数据库资源,几百个并发就可能拖垮一台服务器。

如何判断WordPress网站正在遭受DDoS攻击

当你发现网站变慢或者打不开时,先别急着下结论。保哥建议按以下步骤排查:

第一步:区分DDoS和暴力破解攻击

DDoS攻击和暴力破解(Brute Force)攻击都会导致网站变慢,但本质完全不同。暴力破解是针对登录页面的密码猜测攻击,而DDoS是针对整个网站的资源耗尽攻击。

判断方法: 查看服务器访问日志中请求的目标页面。如果大量请求集中在 /wp-login.php/xmlrpc.php,大概率是暴力破解;如果请求分散在各种页面,甚至是不存在的页面,那多半是DDoS攻击。

顺带提一句,防范暴力破解最基础的一步就是使用高强度密码。保哥推荐使用随机密码生成器来为你的WordPress后台、数据库、FTP等生成足够复杂的密码,16位以上的混合密码能有效抵御字典攻击。

第二步:检查流量数据

登录你的主机控制面板或使用流量分析工具,重点关注以下指标:

带宽使用量。 正常情况下你的网站每天消耗多少带宽你心里应该有个数。如果某个时间段突然飙升到平时的10倍甚至100倍,几乎可以确认遭受了攻击。

请求数。 在Google Analytics中看到的通常是正常用户的访问量,DDoS流量一般不会执行JavaScript,所以在GA中可能看不到异常。你需要查看服务器原始日志或CDN面板中的请求数。

服务器资源占用。 通过SSH登录服务器,使用 tophtop 命令查看CPU和内存占用。如果PHP-FPM或MySQL进程占用异常高,说明可能正在遭受应用层攻击。

第三步:分析日志特征

通过服务器日志,你可以获得攻击的详细信息。以Nginx为例,执行以下命令:

# 查看最近1小时内访问量最大的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 查看请求最多的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 查看最常见的User-Agent
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

如果你发现某些IP的请求数高达上万次,或者大量请求来自相同的User-Agent(比如 python-requests/2.28.0 或空白UA),那基本可以确认是攻击流量。

第四步:设置实时监控告警

不要等到网站打不开了才去查看,提前设置监控才是正确做法:

UptimeRobot: 免费版支持5分钟间隔的监控,网站宕机时会通过邮件或短信通知你。

服务器监控脚本: 在服务器上设置一个简单的cron任务,当CPU超过90%或者连接数超过阈值时自动发送告警邮件。

Cloudflare告警: 如果你已经使用了Cloudflare,可以在通知设置中开启DDoS攻击告警,它会在检测到异常流量时自动通知你。

DDoS攻击应急处置方案

当你确认网站正在遭受DDoS攻击时,需要快速、有序地进行处置。保哥根据多年经验,总结了一套分阶段的应急响应流程。

第一阶段:立即启用Cloudflare"Under Attack"模式

如果你的网站已经接入了Cloudflare(还没接入的强烈建议立刻接入,免费版就够用),第一时间启用"Under Attack"模式:

登录Cloudflare控制台,选择你的域名,在Overview页面找到"Under Attack Mode"开关,打开即可。

启用后,所有访问你网站的用户都会先看到一个5秒的JavaScript验证页面。这个验证页面的原理是强制浏览器执行一段JS计算,正常浏览器可以在几秒内完成,但大多数攻击工具和僵尸程序无法执行JavaScript,从而被自动拦截。

注意事项: 这个模式会影响正常用户体验,不建议长期开启。当攻击停止后应及时关闭,切换回正常模式。

第二阶段:分析并封锁攻击源

在Cloudflare的Security菜单下,打开Events日志,你可以看到被拦截和通过的请求详情。根据这些数据:

按IP封锁。 如果攻击来自少量固定IP(小型僵尸网络),直接在Cloudflare的IP Access Rules中添加Block规则。在Cloudflare控制台中,进入Security → WAF → Tools,输入需要封锁的IP地址或IP段,选择Block操作即可。

按地区封锁。 如果你的网站主要面向国内用户,但攻击流量来自某些特定国家,可以在Cloudflare中设置国家级封锁或挑战。进入Security → WAF → Custom rules,创建一条规则,当来源国家不在你的目标市场列表中时,要求进行Managed Challenge验证。

按User-Agent封锁。 很多攻击工具使用固定的User-Agent字符串。在Cloudflare的WAF规则中,你可以创建自定义规则来拦截这些特征明显的UA。关于WordPress如何在代码层面过滤恶意User-Agent,保哥之前写过一篇WordPress中wp_http_validate_url函数IP验证漏洞修复方案,其中涉及到的请求验证逻辑同样值得参考。

第三阶段:服务器层面的紧急限流

如果攻击流量绕过了CDN直接打到你的源站(这种情况通常是因为源站IP泄露),你需要在服务器层面进行限制。

Nginx限流配置示例:

# 在http区块中定义限流规则
http {
    # 限制每个IP每秒最多10个请求
    limit_req_zone $binary_remote_addr zone=anti_ddos:10m rate=10r/s;
    
    # 限制每个IP的并发连接数
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    server {
        # 应用限流规则,突发允许20个请求排队
        limit_req zone=anti_ddos burst=20 nodelay;
        
        # 单IP最大并发连接数50
        limit_conn conn_limit 50;
        
        # 超出限制返回429状态码
        limit_req_status 429;
        limit_conn_status 429;
    }
}

使用iptables紧急封锁IP段:

# 封锁单个IP
iptables -A INPUT -s 192.168.1.100 -j DROP

# 封锁整个C段
iptables -A INPUT -s 192.168.1.0/24 -j DROP

# 限制每个IP的并发连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 -j REJECT

# 使用conntrack限制新连接速率
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT

第四阶段:联系主机商协助

大多数正规的主机商(如SiteGround、Cloudways、阿里云、腾讯云等)都有DDoS防护能力。在遭受大规模流量攻击时,你应该:

及时联系主机商技术支持,告知攻击情况。他们可以在网络层面帮你过滤异常流量,或者临时为你切换到更高防护的节点。需要注意的是,部分共享主机服务商在检测到攻击时会直接暂停你的网站以保护其他用户。如果你经常遭受攻击,建议升级到独立的云服务器或高防服务器。

WordPress网站DDoS长期防御体系

应急处置只能解燃眉之急,要从根本上降低被攻击的风险和影响,你需要搭建一套完整的防御体系。

一、CDN和DNS层防护

Cloudflare防护配置深度优化。 即使你用的是Cloudflare免费版,也有很多安全配置值得优化:

开启Bot Fight Mode。在Security → Bots设置中开启,可以自动识别并拦截已知的恶意爬虫和攻击工具。

配置Rate Limiting规则。在Security → WAF → Rate limiting rules中,为关键页面设置速率限制。比如,对/wp-login.php设置每分钟最多5次请求,超过则封锁10分钟。

设置Page Rules缓存策略。对于不经常变化的页面,在Page Rules中设置"Cache Level: Cache Everything",让Cloudflare直接返回缓存内容,请求根本不会到达你的服务器。

开启Browser Integrity Check。这个功能会检查请求头中是否包含常见的恶意特征,自动拦截可疑流量。

隐藏源站IP。 这是非常关键的一步。如果攻击者知道你服务器的真实IP,就可以绕过Cloudflare直接攻击。确保以下几点:在接入Cloudflare之前更换服务器IP;不要在DNS中留下非代理的A记录指向源站;检查邮件服务器的MX记录是否暴露了源站IP;使用独立的邮件服务,不要在Web服务器上运行邮件服务。

二、WordPress应用层安全加固

禁用xmlrpc.php。 如果你不使用Jetpack插件或远程发布功能,直接禁用这个接口。在Nginx配置中添加:

location = /xmlrpc.php {
    deny all;
    return 403;
}

或者在.htaccess中添加(Apache服务器):

<Files xmlrpc.php>
    Order Deny,Allow
    Deny from all
</Files>

限制WordPress REST API。 默认情况下,REST API会暴露站点的用户信息等敏感数据。在主题的functions.php中添加:

// 禁止未登录用户访问REST API
add_filter('rest_authentication_errors', function($result) {
    if (!is_user_logged_in()) {
        return new WP_Error('rest_not_logged_in', '需要登录后才能访问API', array('status' => 401));
    }
    return $result;
});

修改默认登录地址。 使用WPS Hide Login插件或手动修改登录URL,把默认的/wp-login.php改成只有你自己知道的路径,比如/my-secret-login-2024

限制登录尝试次数。 安装Limit Login Attempts Reloaded插件,或者在functions.php中实现:

function check_attempted_login($user, $username, $password) {
    if (get_transient('attempted_login')) {
        $dession = get_transient('attempted_login');
        if ($dession['tried'] >= 3) {
            $until = get_option('_transient_timeout_attempted_login');
            $time = time_to_go($until);
            return new WP_Error('too_many_tried', sprintf('登录尝试次数过多,请在%s后重试。', $time));
        }
    }
    return $user;
}
add_filter('authenticate', 'check_attempted_login', 30, 3);

三、服务器层面的安全配置

启用SYN Cookies防护。 在Linux服务器上,通过以下内核参数优化TCP连接处理:

# 编辑 /etc/sysctl.conf 添加以下配置
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300

# 使配置生效
sysctl -p

配置fail2ban自动封禁。 fail2ban可以自动检测并封锁异常IP:

# 安装fail2ban
apt-get install fail2ban

# 创建WordPress登录保护规则
cat > /etc/fail2ban/jail.d/wordpress.conf << EOF
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 3600
action = iptables-multiport[name=wordpress, port="http,https"]
EOF

# 创建过滤规则
cat > /etc/fail2ban/filter.d/wordpress-login.conf << EOF
[Definition]
failregex = <HOST>.*POST.*/wp-login.php
ignoreregex =
EOF

# 重启fail2ban
systemctl restart fail2ban

数据库优化减轻攻击影响。 当遭受应用层攻击时,数据库往往是最先崩溃的环节。做好以下优化可以提高抗攻击能力:安装Redis或Memcached作为对象缓存;优化慢查询,使用Query Monitor插件排查性能瓶颈;限制MySQL的最大连接数,防止被撑爆。

四、全站缓存策略

缓存是最有效的被动防御手段之一。当攻击流量到达你的服务器时,如果大部分请求都能被缓存直接响应,PHP和数据库就不会被压垮。

推荐的缓存方案: 使用WP Super Cache或W3 Total Cache插件开启页面缓存;在Nginx中配置FastCGI Cache,直接在Web服务器层面缓存PHP输出;对于静态资源(CSS、JS、图片),设置长期浏览器缓存。

Nginx FastCGI Cache配置示例:

# 在http区块中添加
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

server {
    set $skip_cache 0;
    
    # 登录用户不缓存
    if ($http_cookie ~* "wordpress_logged_in") {
        set $skip_cache 1;
    }
    
    # POST请求不缓存
    if ($request_method = POST) {
        set $skip_cache 1;
    }
    
    location ~ \.php$ {
        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
        add_header X-Cache-Status $upstream_cache_status;
    }
}

五、定期安全审计和版本更新

保持WordPress核心、主题、插件的及时更新,这是最基本但很多人做不到的事情。每次更新不仅是功能改进,更重要的是安全补丁的修复。

同时建议定期做一次安全审计:检查是否有不明用户账号;审查已安装的插件是否都是必需的;检查文件权限设置是否合理(目录755,文件644);确认wp-config.php的权限为400或440。

DDoS防御工具推荐和对比

工具/服务类型免费版功能适用场景防护等级
CloudflareDNS级CDN/WAF基础DDoS防护、SSL、缓存所有WordPress网站★★★★☆
Sucuri云WAF无免费版中高价值商业网站★★★★★
WordfenceWordPress插件基础防火墙、扫描小型个人网站★★★☆☆
fail2ban服务器工具完全免费开源有SSH权限的VPS★★★☆☆
阿里云DDoS防护云服务基础防护5Gbps国内用户、高防需求★★★★★
Cloudflare ProDNS级CDN/WAF付费$20/月起中型企业网站★★★★★

保哥的建议是:大部分WordPress网站,Cloudflare免费版 + fail2ban + 合理的Nginx配置就足以应对绝大多数攻击场景。如果你运营的是高价值的电商网站或企业站,建议升级到Cloudflare Pro或使用Sucuri提供的专业WAF服务。

遭受攻击后的恢复与复盘

攻击停止后,不要急着庆祝,还有几件重要的事情要做。

检查网站是否被植入后门。 有些攻击者在DDoS期间会趁你忙于应对流量攻击时,通过其他漏洞在你的服务器上植入木马或后门。使用Wordfence的扫描功能,或者手动检查最近修改的文件:

# 查找最近24小时内被修改的PHP文件
find /var/www/html -name "*.php" -mtime -1

# 查找包含可疑函数的文件
grep -rn "eval\|base64_decode\|system\|exec\|passthru" /var/www/html/wp-content/

备份和恢复。 确保你有攻击前的干净备份。如果发现文件被篡改,应从干净备份中恢复,而不是简单地删除可疑文件。

复盘攻击过程。 记录攻击的时间、类型、流量大小、攻击来源等信息,分析你的防御体系在哪些环节起了作用,哪些环节有缺陷,为下一次防御做准备。

常见问题

DDoS攻击和CC攻击有什么区别?

DDoS是一个总称,CC攻击是DDoS攻击中"应用层攻击"的一种。DDoS包含流量型、协议型和应用层三大类。CC攻击专门针对网站的HTTP/HTTPS服务,通过模拟大量正常用户请求来耗尽服务器的PHP和数据库资源。对于WordPress网站来说,CC攻击是最常见也最难防的类型,因为每个请求从表面上看都像是正常访问。

Cloudflare免费版能防住DDoS攻击吗?

能防住大部分中小规模的攻击。Cloudflare免费版提供了无限带宽的DDoS防护,对于流量型攻击的防护效果很好。但对于精心构造的应用层攻击,免费版的WAF规则有限,可能需要开启Under Attack模式或升级到Pro版才能有效拦截。保哥的经验是,配合服务器端的Nginx限流和fail2ban,Cloudflare免费版在80%的攻击场景下都够用。

网站被DDoS攻击会影响SEO排名吗?

短期的宕机通常不会影响排名。Google的John Mueller曾明确表示,几个小时的宕机不会导致排名下降。但如果攻击持续数天导致网站长时间无法访问,Google可能会暂时降低你的抓取频率,进而影响新内容的收录速度。最严重的情况是攻击者在DDoS期间植入了恶意代码,触发Google Safe Browsing标记,这对SEO的打击是毁灭性的。

如何判断攻击流量的规模?

在Cloudflare后台的Analytics页面可以看到总请求数和被拦截的威胁数。在服务器端,使用 iftopvnstat 命令可以实时监控网络流量。一般来说,日流量不到1万PV的小站,如果突然出现每分钟上万次请求,就可以判断是攻击行为。

换服务器IP能解决DDoS攻击吗?

能在短期内解决,但不是根本方案。如果攻击者已经知道了你的源站IP,更换IP后需要确保新IP不被再次暴露。配合Cloudflare使用时,确保所有DNS记录都经过Cloudflare代理(橙色云朵图标),不要有任何直接暴露源站IP的记录。

WordPress需要安装几个安全插件才够?

保哥的建议是只安装一个综合性安全插件就够了,多个安全插件同时运行反而会互相冲突,增加服务器负担。推荐Wordfence(功能最全面)或iThemes Security(配置更简单)二选一即可。核心的安全防护应该在Cloudflare和服务器层面完成,而不是依赖WordPress插件。