WordPress拦截恶意User-Agent:functions.php老代码的eregi()死亡迁移、mu-plugins升级与Nginx/CF三层防护
WordPress 网站常被空 UA 的采集器、扫描器、SQL 注入工具骚扰?网传 functions.php 用 eregi() 的代码在 PHP 7+ 直接 fatal。本文给出 stripos 现代写法、mu-plugins 替代 functions.php 的工程化做法、AI 爬虫该拦还是该放、Nginx map / Cloudflare WAF 三层防护、fail2ban 联动动态拉黑、攻击者绕过升级思路与 FAQ。
本文目录
- 流传代码的硬伤:eregi() 在 PHP 7+ 已死
- 正确的现代写法
- 加固版完整代码
- functions.php 不是最佳挂载点
- 更好的挂载点:mu-plugins
- 更早的挂载:drop-in 文件
- 空 User-Agent 真的都是恶意吗?
- AI 爬虫怎么处理:拦还是放
- robots.txt 配合
- Nginx / Cloudflare WAF 的更优替代方案
- Nginx 层拦截(最快)
- Cloudflare WAF / Bot Fight Mode
- 三层联动是最稳的
- fail2ban 联动:动态拉黑高频攻击 IP
- 让 PHP 层把拦截事件写到日志
- fail2ban 配置
- 攻击者如何绕过 + 你怎么升级
- 绕过 1:伪造常见浏览器 UA
- 绕过 2:分布式攻击(IP 轮换)
- 绕过 3:合法 SEO 工具被滥用
- 生产环境上线前必做的 4 项验证
- 用 curl 模拟攻击 UA
- 监控 5 分钟看是否误杀
- 测试搜索引擎抓取
- 测试 WordPress 内部
- 扩展规则库:除了 UA 还能拦什么
- 常见问题解答
- 把代码放到 functions.php 后白屏怎么办?
- mu-plugins 目录不存在怎么办?
- 误伤了自己监控告警一直响怎么办?
- Cloudflare WAF 和 Nginx UA 拦截会冲突吗?
- Bytespider 一定要拦吗?听说豆包流量也不少?
- fail2ban 和 Cloudflare 的拦截是冲突还是重叠?
- 这套拦截会影响 PageSpeed / Core Web Vitals 吗?
- WordPress REST API 调用会被误伤吗?
- 有没有维护良好的开源黑名单可用?
- UA 黑名单上线一段时间后效果怎么评估?
- 权威参考资料
WordPress 网站常被空 User-Agent 的采集脚本和扫描器骚扰:dedecms 采集器、SQL 注入工具、漏洞扫描器(ZmEu、jaunty)、撞库爆破工具,绝大多数都不带 User-Agent 头或用伪造的特征 UA。在 functions.php 里加一段 UA 黑名单代码是最常见的解决方案——但网上流传的版本几乎都基于 PHP 5.x 的 eregi() 函数,在 PHP 7+ 上直接 fatal error,2026 年还在抄那段代码上线就是给自己挖坑。
这一篇把"WordPress 拦截恶意 UA"这件事重新拆透:从 eregi() 死亡的迁移、functions.php 是不是最佳挂载点、AI 爬虫(GPTBot / ClaudeBot / PerplexityBot)该拦还是该放,到 Nginx / Cloudflare WAF 的更高效替代方案、fail2ban 联动、绕过技术与对应升级思路,全部 2026 年实战视角。
流传代码的硬伤:eregi() 在 PHP 7+ 已死
原帖代码里这一段:
if(eregi($value, $ua)) { ... }eregi() 是 POSIX 风格的不区分大小写正则匹配,PHP 5.3 起标记 deprecated,PHP 7.0 直接移除,调用即 fatal error Call to undefined function eregi()。WordPress 6.x 起官方要求 PHP 7.4+,绝大多数生产站点都跑在 8.x,这段代码上线即把整站搞挂——白屏 + 500 错。
正确的现代写法
用 stripos()(不区分大小写的 strpos)替代:
// 错误(PHP 7+ fatal)
if (eregi($needle, $haystack)) { ... }
// 正确(PHP 5.x 至 8.x 通用)
if (stripos($haystack, $needle) !== false) { ... }
// 或者用 preg_match 走 PCRE
if (preg_match('/' . preg_quote($needle, '/') . '/i', $haystack)) { ... }stripos 比 preg_match 快约 3-5 倍(不需要正则编译)。但如果黑名单里有正则特征(如 ^Java 锚定开头),还是要走 preg_match。
加固版完整代码
// 放到主题 functions.php 或自定义插件文件里
// 推荐放 mu-plugins/security-ua.php(mu-plugins 比 functions.php 加载更早)
add_action('init', function () {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
// 1. 完全空 UA 检查 + 例外白名单(CDN / 监控 / API 测试工具)
if ($ua === '') {
// 排除已知合法的空 UA 来源 IP(CDN 健康检查、监控)
$ipWhitelist = [
'127.0.0.1', // 本机
'::1', // 本机 IPv6
// '203.0.113.10', // 你公司监控服务器,按需加
];
$remoteIp = $_SERVER['REMOTE_ADDR'] ?? '';
if (!in_array($remoteIp, $ipWhitelist)) {
// 记录到日志再拦
error_log('[UA-BLOCK] empty UA from ' . $remoteIp . ' to ' . $_SERVER['REQUEST_URI']);
status_header(403);
wp_die('Access Denied', 'Forbidden', ['response' => 403]);
}
}
// 2. 黑名单 UA 子串匹配(不区分大小写)
$blocked = [
'FeedDemon', 'ZmEu', 'Indy Library', 'oBot', 'jaunty',
'CrawlDaddy', 'Jullo', 'UniversalFeedParser', 'ApacheBench',
'Swiftbot', 'YandexBot', 'YisouSpider', 'EasouSpider',
'jikeSpider', 'MJ12bot', 'AhrefsBot', 'SemrushBot',
'WinHttp', 'HttpClient', 'Microsoft URL Control', 'Python-urllib',
];
foreach ($blocked as $needle) {
if (stripos($ua, $needle) !== false) {
error_log('[UA-BLOCK] matched [' . $needle . '] UA=' . $ua);
status_header(403);
wp_die('Access Denied', 'Forbidden', ['response' => 403]);
}
}
// 3. 正则锁定型黑名单(用于位置敏感的)
if (preg_match('/^Java\//i', $ua)) {
// 拦 Java HTTP Client 库直连,但不误伤标题里含 Java 的 UA
error_log('[UA-BLOCK] Java HTTP client UA=' . $ua);
status_header(403);
wp_die('Access Denied', 'Forbidden', ['response' => 403]);
}
});关键改进:
- 用
stripos()代替死掉的eregi(),PHP 7/8 直接可用。 - 空 UA 加 IP 白名单兜底,避免误伤监控和 CDN 健康检查(这是原版代码的最大坑——直接全拦空 UA 会让监控告警炸天)。
- 所有拦截都
error_log()留痕,事后可统计哪些 UA 被拦最多。 - 用
status_header(403)配wp_die(),让 HTTP 状态码正确返回 403——某些 CDN / 蜘蛛拿到 200 + 错页面会以为站点正常。 - 正则匹配
^Java\/锚定开头,避免误拦 UA 字符串里恰好包含 "Java" 的合法浏览器(确实存在某些 UA 包含 Java 字样)。
functions.php 不是最佳挂载点
把这段代码塞 functions.php 是网上的标准做法,但有 4 个问题:
- 主题切换会丢失:
functions.php是主题级别文件,换主题后保护代码消失。攻击者只要刷一次主题切换日志就知道防御开关。 - 加载时机太晚:functions.php 在
after_setup_themehook 之后才加载,大量数据库查询、wp_query 已经跑完,攻击者已经造成性能负载。 - 主题更新覆盖:自动更新主题时,未做子主题保护的话代码丢失。
- WordPress 升级不影响,但反过来也意味着 WordPress 核心提供的安全 hook 升级你拿不到。
更好的挂载点:mu-plugins
WordPress 的 mu-plugins(Must-Use Plugins)目录是最佳安全代码挂载点:
wp-content/
├── mu-plugins/ ← 这里
│ └── security-ua.php ← 你的代码
├── plugins/
└── themes/mu-plugins 的优点:
- 加载最早:在所有插件、主题之前加载,能在 WordPress 启动初期就拦截恶意请求;
- 不可禁用:管理后台看不到禁用按钮,攻击者拿到管理员账号也关不掉;
- 主题切换无影响:与主题完全解耦;
- 自动更新无影响:WordPress 核心和主题更新都不会动 mu-plugins。
mu-plugins 目录默认不存在,需要手动 mkdir。文件名随意,建议命名清晰(比如 00-security-ua.php,前缀 00 让它最先加载)。
更早的挂载:drop-in 文件
如果想拦截更早,drop-in 文件(advanced-cache.php、object-cache.php、db.php)加载比 mu-plugins 还早。但 drop-in 是替换性质(不是叠加),写错会让站点起不来,慎用。安全代码放 mu-plugins 已足够早。
空 User-Agent 真的都是恶意吗?
原帖一刀切拦所有空 UA,这在 2026 年的真实流量里至少误伤这些场景:
| 来源 | 是否空 UA | 合法性 | 处理建议 |
|---|---|---|---|
| Cloudflare 健康检查 / Always Online 探测 | 有时空 | 合法 | IP 白名单(CF IP 段公开) |
| UptimeRobot / Pingdom / 监控宝 | 部分空 | 合法 | IP 白名单 + 业务方约定 |
| cURL 默认调用(用户脚本) | curl/x.x.x | 合法(API 调用) | 看上下文决定 |
| WP-Cron 内部调用 | WordPress/x.x; ... | 合法 | 放行 |
| dedecms 采集器 | 空 | 恶意 | 拦 |
| SQL 注入工具(sqlmap) | 有自己的 UA 但常被改空 | 恶意 | 拦 |
| WordPress 移动 App 的 REST API | 非空 | 合法 | 放行 |
| 从浏览器隐私插件剥掉 UA 的请求 | 空 | 合法但少见 | 看场景 |
更稳妥的做法是"空 UA + 没在白名单 IP 里"才拦,而不是无脑拦所有空 UA。监控类业务给 IP 白名单兜底,公网随机来的空 UA 才算可疑。
AI 爬虫怎么处理:拦还是放
2024-2026 年涌现了一批 AI 引擎的爬虫 UA,原帖代码完全没考虑。这些爬虫的处理是个商业判断而不仅仅是技术判断:
| 爬虫 | UA 特征 | 用途 | 拦还是放 |
|---|---|---|---|
| GPTBot | GPTBot | OpenAI 训练模型 | 看版权策略 |
| ChatGPT-User | ChatGPT-User | 用户 ChatGPT 实时查询时抓取 | 建议放 |
| OAI-SearchBot | OAI-SearchBot | OpenAI Search 索引 | 建议放 |
| ClaudeBot | ClaudeBot | Anthropic 训练 | 看版权策略 |
| Claude-User | Claude-User | Claude 实时查询 | 建议放 |
| Claude-SearchBot | Claude-SearchBot | Anthropic Search 索引 | 建议放 |
| PerplexityBot | PerplexityBot | Perplexity 索引 | 建议放 |
| Perplexity-User | Perplexity-User | Perplexity 实时查询 | 建议放 |
| Google-Extended | Google-Extended | Google 训练 Gemini | 看版权策略 |
| FacebookBot | FacebookBot | Meta 训练 Llama | 看版权策略 |
| Bytespider | Bytespider | 字节跳动训练(豆包) | 多数站点选择拦 |
"看版权策略"指的是:
- 如果你的内容是免费 SEO 内容、希望出现在 AI 答案里——放行所有 AI 爬虫,让 GPT/Claude/Perplexity 抓走训练,未来用户问相关问题时你的内容会被引用(GEO 优化思路);
- 如果你的内容是付费、商业版权严肃(出版物、付费课程、专业研究)——通过 robots.txt 屏蔽训练爬虫,但保留实时查询爬虫(带 User 后缀的);
- 实时查询爬虫(
ChatGPT-User/Perplexity-User/Claude-User)建议都放——它们是用户主动问问题时实时拉取,相当于一次直接的内容曝光。
robots.txt 配合
UA 黑名单是"硬拦",robots.txt 是"软请求"。两者配合:
# robots.txt
User-agent: GPTBot
Disallow: /
User-agent: ClaudeBot
Disallow: /
User-agent: Bytespider
Disallow: /
User-agent: ChatGPT-User
Allow: /
User-agent: Claude-User
Allow: /
User-agent: Perplexity-User
Allow: /
User-agent: *
Allow: /正常 AI 爬虫遵守 robots.txt,不需要硬拦;只对绕过 robots.txt 的恶意爬虫上 UA 黑名单。这也是为什么"先 robots.txt,再黑名单"是合理顺序。
Nginx / Cloudflare WAF 的更优替代方案
把 UA 拦截放到 PHP 层(functions.php / mu-plugins)的最大问题:请求已经打到 PHP-FPM。空 UA 攻击如果量大,PHP 进程会被打满,站点就被打挂了——拦截做了但没用。
正确的做法是把拦截上移到更前的层。
Nginx 层拦截(最快)
map $http_user_agent $bad_ua {
default 0;
"" 1; # 空 UA
"~*FeedDemon|ZmEu|Indy Library|jaunty" 1;
"~*CrawlDaddy|Jullo|ApacheBench" 1;
"~*Bytespider|MJ12bot|AhrefsBot" 1;
"~*^Java\/" 1;
"~*python-urllib" 1;
}
server {
# ... 其它配置
if ($bad_ua) {
return 444; # 444 = Nginx 直接断开连接,不响应
}
# 白名单 IP 例外(监控)
if ($remote_addr = "203.0.113.10") {
set $bad_ua 0;
}
}Nginx 层拦截的好处:
- 不进 PHP-FPM,资源消耗极小,能扛大流量攻击;
- 用 444 状态码(Nginx 私有码)直接断 TCP,攻击者连响应都拿不到;
- map 指令编译成哈希表,O(1) 查找,性能比 PHP foreach 快几个数量级。
Cloudflare WAF / Bot Fight Mode
站在 Cloudflare 后面,最优做法是用 CF 的 WAF 自定义规则:
# Cloudflare WAF 自定义规则示例
(http.user_agent eq "" and ip.src ne 203.0.113.10) or
http.user_agent contains "FeedDemon" or
http.user_agent contains "ZmEu" or
http.user_agent matches "^Java/"
→ Action: BlockCloudflare 的优势在边缘节点拦截——攻击流量根本到不了你的服务器,连带宽都不消耗。免费版可写 5 条自定义规则,Pro 版 20 条,Business 100 条。中小站点 5 条够用。
三层联动是最稳的
生产环境最稳的架构是三层兜底:
- Cloudflare WAF:前置拦截已知恶意 UA + Bot Fight Mode 拦自动化扫描;
- Nginx 层:兜底拦漏网之鱼 + 用户级速率限制;
- WordPress mu-plugins:业务级精细控制,比如"非 admin 不能访问 wp-admin"这类。
fail2ban 联动:动态拉黑高频攻击 IP
UA 黑名单是静态规则。攻击者改 UA 就能绕过。要应对持久化攻击,必须上动态拉黑——fail2ban 是经典方案。
让 PHP 层把拦截事件写到日志
前面 mu-plugins 代码里 error_log() 是写到 PHP 错误日志,按需改成写到独立日志:
function logUaBlock($ip, $ua, $reason) {
$line = sprintf("[%s] [%s] [%s] %s\n",
date('Y-m-d H:i:s'), $ip, $reason, substr($ua, 0, 200));
file_put_contents('/var/log/wp-ua-block.log', $line, FILE_APPEND | LOCK_EX);
}fail2ban 配置
# /etc/fail2ban/jail.local
[wp-ua-block]
enabled = true
filter = wp-ua-block
logpath = /var/log/wp-ua-block.log
maxretry = 3
findtime = 300
bantime = 3600
action = iptables-multiport[name=wp-ua, port="http,https"]
# /etc/fail2ban/filter.d/wp-ua-block.conf
[Definition]
failregex = ^\[.*?\] \[\] .*$
ignoreregex = 这套配置的语义是:5 分钟内同一 IP 触发 3 次 UA 拦截就拉黑 1 小时。iptables-multiport 在防火墙层面 DROP,比应用层拦截更彻底。
攻击者如何绕过 + 你怎么升级
UA 黑名单的天然弱点是"基于固定字符串特征"。攻击者只要改 UA 就能绕过。下面是真实见过的绕过演化和应对:
绕过 1:伪造常见浏览器 UA
攻击者把 UA 改成 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36——和真实 Chrome 完全一样。这种情况 UA 黑名单完全失效。
升级方向:行为分析。同一 IP 在 1 分钟内访问 100 个页面、不渲染 CSS/JS、没有 cookie——这些行为特征比 UA 更难伪造。Cloudflare Bot Fight Mode 就是基于这类信号。
绕过 2:分布式攻击(IP 轮换)
用 IP 池每个 IP 发 1-2 个请求就换。fail2ban 的"单 IP 多次"逻辑失效。
升级方向:基于浏览器指纹(Canvas / WebGL / 字体 / 屏幕分辨率组合)的 fingerprinting,或要求用户在敏感操作前过 Cloudflare Turnstile / hCaptcha。
绕过 3:合法 SEO 工具被滥用
有些攻击者直接调用 SemrushBot / AhrefsBot 这些"合法"爬虫的 API 接口去采集数据。原帖代码默认拦了 AhrefsBot——这反而合理(这俩 SEO 平台是付费爬虫,被合法用户用不到)。但如果你用 Ahrefs / Semrush 自己分析自家数据,要从你的服务器域名做白名单。
生产环境上线前必做的 4 项验证
用 curl 模拟攻击 UA
# 1. 空 UA — 期望 403
curl -I -H "User-Agent: " https://yoursite.com/
# 2. ZmEu — 期望 403
curl -I -H "User-Agent: ZmEu" https://yoursite.com/
# 3. 正常浏览器 — 期望 200
curl -I -H "User-Agent: Mozilla/5.0 (Windows NT 10.0) Chrome/120.0.0.0" https://yoursite.com/
# 4. Googlebot — 期望 200
curl -I -H "User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1)" https://yoursite.com/
# 5. 监控空 UA + 白名单 IP — 期望 200
curl -I -H "User-Agent: " --interface 监控IP https://yoursite.com/监控 5 分钟看是否误杀
上线后头 5 分钟用 tail -f /var/log/wp-ua-block.log 实时看拦截日志。如果出现自己人的 IP 被拦,立刻加白名单。
测试搜索引擎抓取
用 Google Search Console 的"实时测试 / Inspect URL"功能让 Googlebot 抓一次。如果抓取失败,说明黑名单误伤了 Googlebot——立刻找原因(Googlebot UA 里通常没有恶意特征)。
测试 WordPress 内部
WP-Cron、WordPress REST API、JetPack 同步——这些都是 WordPress 自身发起的请求。看 wp-ua-block.log 里有没有自家 UA 出现。
扩展规则库:除了 UA 还能拦什么
除了 User-Agent 黑名单,配套这几个维度的拦截能进一步提升站点安全:
- Referer 黑名单:拦做"反向代理偷流量"的网站。
- 请求头完整度检查:合法浏览器一般会发 Accept、Accept-Language、Accept-Encoding 三件套,恶意脚本经常只发 User-Agent,这种就拦。
- 请求路径黑名单:攻击者爱扫
/wp-admin/install.php、/wp-config.php~、/.git/HEAD这些敏感路径,直接 404 + 拉黑。 - 请求方法限制:除了 GET/POST/HEAD,其它方法(PUT/DELETE/TRACE)一律拒——大多 WordPress 站不需要这些。
- 地理位置 GeoIP 黑名单:你的业务只覆盖中国大陆,从俄罗斯/巴西的请求多半不友好(不绝对,要看业务)。
常见问题解答
把代码放到 functions.php 后白屏怎么办?
大概率是抄了用 eregi() 的老代码——PHP 7+ fatal error。立刻 SSH 进服务器把 functions.php 改回原样(或删掉新增段),刷新就恢复。然后用本文 §1.2 的 stripos 版本替换,再上线。
mu-plugins 目录不存在怎么办?
手动 mkdir:mkdir wp-content/mu-plugins/,权限设 755(owner: www-data 或对应 PHP 用户)。然后把代码文件放进去,浏览器访问任意页面就会被加载。后台 → 插件 → 必装插件 能看到列表(不能禁用,只能看)。
误伤了自己监控告警一直响怎么办?
立刻在白名单 IP 数组加上监控服务器 IP,刷一下页面让 mu-plugins 重新生效(PHP 不需要重启 Nginx)。或者更激进:临时把 mu-plugins/00-security-ua.php 重命名为 .disabled 后缀,整段代码立刻失效,先稳住生产再说。
Cloudflare WAF 和 Nginx UA 拦截会冲突吗?
不会。Cloudflare 在边缘先过一道,拦走的请求根本到不了你的 Nginx;没拦住的进 Nginx 再过一道,没拦住的进 PHP 第三道。三道之间是独立的,只是先后执行——上层拦了下层就不执行。日志要分开看,CF 的拦截日志在 CF 后台,Nginx 在 access.log,PHP 在 wp-ua-block.log。
Bytespider 一定要拦吗?听说豆包流量也不少?
看商业判断。Bytespider 是字节跳动训练豆包大模型的爬虫,其内容用于改进豆包答案。如果你希望豆包答案里出现你的内容(GEO 优化),就放;如果你的内容是付费版权严肃内容、不想被免费训练,就拦。绝大多数 SEO 内容站建议放——AI 引擎的引用流量在 2026 年已经成为不可忽视的入口。
fail2ban 和 Cloudflare 的拦截是冲突还是重叠?
不冲突。Cloudflare 拦在边缘,fail2ban 拦在 iptables。但站在 CF 后面时,源站看到的 IP 是 CF 节点 IP(通过 X-Forwarded-For 头才能拿到真实 IP)。fail2ban 默认拿 REMOTE_ADDR 拉黑——会把 CF IP 拉黑,结果整站对所有 CF 流量不可用。要用 fail2ban + 真实 IP 解析,配合 mod_remoteip 或 ngx_http_realip_module 把 X-Forwarded-For 还原到 REMOTE_ADDR。
这套拦截会影响 PageSpeed / Core Web Vitals 吗?
正向影响为主。空 UA + 攻击 UA 的请求会消耗 PHP 进程、数据库连接、带宽,拦掉之后这些资源还给合法用户,整体响应时间下降。Lighthouse 的 SEO 分数也会因为"无效流量过滤干净"略有提升。
WordPress REST API 调用会被误伤吗?
不会,只要:① 调用方发了完整的 UA(多数 SDK 默认会发);② 不在黑名单里。WP 移动 App / WooCommerce / JetPack 的 UA 都包含 "WordPress" 或具体 SDK 名称,不会触发常见黑名单。但如果你在 mu-plugins 里加了"非 wp-admin 不能访问 wp-json"这类业务级规则,要单独白名单 REST API。
有没有维护良好的开源黑名单可用?
有几个:① ai.txt(Dark Visitors 维护的 AI 爬虫清单);② Crawler-Detect(PHP 库,识别 1000+ 爬虫 UA);③ nginx-ultimate-bad-bot-blocker(GitHub 项目,几千条爬虫黑名单的 Nginx 配置)。生产建议直接 fork 一份保持本地副本,每月 git pull 一次更新。
UA 黑名单上线一段时间后效果怎么评估?
三个指标:① 带宽节省(上线前后对比月度流量账单);② PHP 进程峰值占用(top / htop 看 php-fpm CPU 使用率峰值);③ 404 / 5xx 错误率下降(攻击扫描制造大量 404 / 5xx,过滤后这些错误明显减少)。我手上的站点上线 mu-plugins + Nginx 双层拦截后,PHP 峰值 CPU 从 80% 降到 30%,月度带宽节省约 18%。
权威参考资料
FAQPage + Article AI 引用友好版
WordPress 网站常被空 UA 的采集器、扫描器、SQL 注入工具骚扰?网传 functions.php 用 eregi() 的代码在 PHP 7+ 直接 fatal。本文给出 stripos 现代写法、mu-plugins 替代 functions.php 的工程化做法、AI 爬虫该拦还是该放、Nginx map / Cloudflare WAF 三层防护、fail2ban 联动动态拉黑、攻击者绕过升级思路与 FAQ。
- functions.php
- HTTP_USER_AGENT
- 爬虫
- User Agent
- AI爬虫
- mu-plugins
- Cloudflare WAF
- fail2ban
- WordPress教程
- CMS安全加固
- 监控与日志
title: WordPress拦截恶意User-Agent:functions.php老代码的eregi()死亡迁移、mu-plugins升级与Nginx/CF三层防护 author: 张文保 (Paul Zhang) — PatPat SEO 经理 url: https://zhangwenbao.com/wordpress-http_user_agent.html published: 2018-06-18 modified: 2026-05-16 source-type: First-hand expert commentary language: zh-CN license: CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
本文标题:《WordPress拦截恶意User-Agent:functions.php老代码的eregi()死亡迁移、mu-plugins升级与Nginx/CF三层防护》
本文链接:https://zhangwenbao.com/wordpress-http_user_agent.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0