云锁防盗链与静态资源防护图片CSS,JS 被外站引用怎么拦又不误伤搜索引擎

最终结论(不再给选项):保持云锁「防护模式」+ 防盗链开启;.htaccess 用「A 版底子 + 搜索引擎放行 + 字体补全 + Google 多后缀」这一版;B 版(拦空 Referer)永远不要上;云锁防盗链例外里只补 google.com(裸域名,不是路径);cnblogs 不加、原有七条不删、不勾允许空 Referer。
这份笔记和另外两份的分工:《win-acme 证书续订排障笔记》管出站与 ACME;《裸域 HTTPS 无样式排查教程》管 443 层裸域 301;本份管入站静态资源被外站引用。三件事不是一层,别混着查。

一、现象与定性:8214 条日志到底是什么

防护日志里 2026-11-11 ~ 11-12 共 8214 条、83 页(单页 100 条),几乎全是「防盗链 / 盗链防护(会话方式) / 已被拦截」。典型一条:

2026-11-12 22:33:27  防盗链  113.24.225.235(中国山西长治)
访问 www.511yj.com/wp-content/uploads/2016/07/511yujian25.jpg
触发规则:盗链防护(会话方式),已被拦截。
(http://www.cnblogs.com/xiager/p/6855533.html 正在盗链您的资源)

同一秒里 .235 / .29 / .73 / .96 各来一条、全是 511yujian*.jpg —— 这是一个外部页面里嵌了四张图,浏览器并发加载,不是四个攻击者。波兰、法国、美国、大连、南京那些 IP 同理,是外站读者点开旧文、图片缓存服务、爬虫各来一次。

三条必须先纠的误读:

  • 8214 是两天累计,按时间倒序显示,不是「十分钟八千次」,也不是攻击爆发。
  • 日志条数 ≠ 服务器负载。这些 .jpg 被挡在 Apache 外面,不进 PHP、不查库、不读磁盘上的图,单次成本只是「匹配一次 Referer 规则 + 写一条日志 + 回一段响应」。约每小时 170 次,对 4G 机器很轻。之前 CPU 冲 100% 又掉回 2% 那波,是 /index.php 动态请求 + 扫描并发 + 弹窗重绘的瞬时尖峰,和这些被秒拒的图片不同步。
  • 博客园那篇是别人的站(作者 xiager),你没权限改它的 HTML、删不了它引用的 img 标签。「去把那篇旧文的图搬走」是站着说话不腰疼,做不到。

所以真正能做的,不是让请求消失(只要对方 HTML 还指向 www.511yj.com,DNS 就解析到你 ECS,TCP 就得建一次),而是决定「它来时这台机器用多小的代价把它打发掉」。

二、先分清三层,不然一定改错地方

层 在哪 它干什么 能不能动
别人的 HTML 博客园等外站 写着 <img src="https://www.511yj.com/..."> 或 <link href=".../bootstrap.min.css"> 动不了
云锁「网站防盗链」 本地云锁客户端,Apache 之前 按 Referer 判来源,非法来源回一整页 5758 字节「网站防火墙」HTML 能改例外名单、拦截文案
Apache .htaccess C:\xampp\htdocs\.htaccess 第二道保险,按 Referer + 后缀回 403 能改,本文重点

关键认知:防盗链不是「拒收」,是「收进来、判一下、再回一个拦截页」。所以它会占一点 CPU 和出站带宽,但没有把真图供出去。云锁在 Apache 之前,带外站 Referer 的请求已经被它截了,根本到不了 .htaccess —— 所以新加的 Apache 规则是双保险,补的是「云锁被切回监控模式 / 漏判 / 空 Referer」那部分,不追求在 curl 里看到 403。

三、云锁「网站防盗链」:例外名单是放行列表,不是黑名单

设置页那份「网站例外名单」里原有七条:

baidu.com   so.com   sogou.com   bing.com   bbs.511yj.com   weibo.com   qq.com

标题写得清楚:「加入到例外名单的项,不再受此功能的保护」。也就是这七条是允许的来源(给搜索引擎收录、微博 / QQ 分享、自己 bbs 子域看的)。cnblogs 不在里面,所以博客园那篇取图被拦 —— 和日志完全对得上。

  • 七条一条都别删:删了会误伤 SEO 收录和 bbs 引用主站资源。
  • 绝不加 www.cnblogs.com:目标是拦,不是放行。上一轮把「放行 cnblogs」摆成选项是跑偏的。
  • 不勾「允许空 Referer / 允许直接访问」(如果面板有这一项)。
  • 「拦截信息提示」那个长文本框只是 HTML 页里的文案,清空或改成短词可以让拒绝更便宜;不影响拦截逻辑。右下「恢复默认配置」别点,一点把所有例外全清。
监控模式 vs 防护模式

监控模式只记日志不拦,防护模式真拦并返回「网站防火墙」页。别人以前能用你的 css/js,很可能是当时在监控模式;切到防护模式后,实测 Referer: https://www.cnblogs.com/ 和空 Referer 都返回 200 text/html(拦截页),说明云锁两层都拦住了。

切到防护模式后观察两天:WP 后台发文章、前台含代码 / SQL 示例的页面有没有被误拦。真被拦就去防护日志看是哪条规则,按规则加白,不要整体关防护。

为什么 CSS / JS 也会被外站用

防盗链默认按 Referer 判「图片等资源」,对 .css / .js 这类静态文本资源检查常偏松;再加上 ExpiresByType text/css "access plus 1 year",外站一旦把 <link> 引进去,浏览器缓存一年,二次请求甚至不带 Referer。三种漏口:

  1. 请求不带 Referer(直接 script src / link,或缓存后不再发 Referer)
  2. 用了 rel="noreferrer" / Referrer-Policy: no-referrer
  3. 来源站被列进了例外名单(cnblogs 不在,所以这条不成立)

云锁这层加不了严:它的防盗链设置里只有「例外名单 + 拦截信息提示」,没有「文件类型」「空 Referer」开关。要按后缀锁死 css/js,只能靠下面的 .htaccess。

四、Apache 层:最终版 .htaccess 片段

先答一个常问的:<IfModule mod_rewrite.c> / RewriteEngine On / RewriteBase / 这三行不是要新增的东西,是文件里 # BEGIN WordPress 下面早已存在的外壳。别再新起一个块,直接把规则插进现有块内部。

精确插入点:两条裸域 301 之后、RewriteRule ^index\.php$ - [L] 之后、/weixin/ 与 Super Static Cache 之前。原因:301 要最先把 Host 统一;缓存那两条 [L] 会终止本轮重写,规则放它后面就永远跑不到。

# ---- HTTP → HTTPS + www(原有,不动)----
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www\.)?511yj\.com$ [NC]
RewriteRule ^(.*)$ https://www.511yj.com%{REQUEST_URI} [L,R=301]

# ---- HTTPS 但仍是裸域 → 补跳 www(原有,不动)----
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^511yj\.com$ [NC]
RewriteRule ^(.*)$ https://www.511yj.com%{REQUEST_URI} [L,R=301]

RewriteRule ^index\.php$ - [L]

# ===== 静态资源防盗链(最终版,就放这里)=====
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?511yj\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^https?://bbs\.511yj\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^https?://([a-z0-9-]+\.)?(baidu|so|sogou|bing|weibo|qq)\.com(\.cn)?/ [NC]
RewriteCond %{HTTP_REFERER} !^https?://([a-z0-9-]+\.)?google\.(com|com\.hk|co\.jp|co\.uk|cn)(\.[a-z]{2})?/ [NC]
RewriteRule \.(jpe?g|png|gif|webp|ico|svg|css|js|woff2?|ttf|eot|otf)$ - [F,NC]

# ===== /weixin/ 动态取件目录(原有,不动)=====
RewriteRule ^weixin/ - [L]

# ===== Super Static Cache 开始(原有,不动)=====

这一版定死的几件事

决定 理由
保留 !^$(A 版底子) 空 Referer 交给云锁拦,Apache 不重复下手。且 Googlebot、图片爬虫、访客新标签直接打开图片常不带 Referer,删了会误伤收录。
B 版(删掉 !^$)永远不上 实测空 Referer 已经被云锁回 200 text/html,删掉零收益;只带来搜索引擎图片 / 社交抓取 / 缓存复用的误伤。
搜索引擎对齐云锁原有七条 云锁已放行 baidu / so / sogou / bing / weibo / qq,Apache 若不放行等于白放行还伤收录。([a-z0-9-]+\.)? 覆盖 image.baidu.com、pic.sogou.com、cn.bing.com 这类子域。
Google 单独一条多后缀 并进单行版会漏 google.com.hk / google.co.jp —— (\.cn)? 只兼容 .com.cn / .cn。用两行版不留漏口。
用 RewriteRule 判后缀,不用 REQUEST_URI 本站 CSS 全带 ?ver=1791971959,%{REQUEST_URI} 含 query string,$ 锚不到 .css 结尾,规则会整个跳过。RewriteRule 匹配不含 query 的路径,自动剥掉 ?ver=。
[F] 不写 [L] 不是漏项,[F] 隐含 [L]。403 比云锁回 5758 字节 HTML 便宜得多,正是「把拒绝做便宜」。
补 ttf|eot|otf font-awesome 老版本字体一起锁住。
三个天然不碰的地方:/.well-known/acme-challenge/<token> 无后缀、probe.txt 是 .txt,都不进正则;/wp-admin/load-styles.php 是 .php,WP 后台不会裂;Super Static Cache 内部重写到 .gz 后,内层第一句 RewriteRule ^super-static-cache/ - [L] 先终止,第二轮不会再跑防盗链。1/5 自动续期不受影响。
边界:这段在 C:\xampp\htdocs\.htaccess,只管主站。bbs.511yj.com 是独立 DocumentRoot(C:/xampp/htdocs/bbs),有自己那份 .htaccess,这段对它不生效。写的 !^https?://bbs\.511yj\.com/ 是放行「bbs 页面引用主站 CSS」,方向没错。外站若引的是 bbs 自己的图片,得单独在 bbs 那份里补(且要先补 RewriteEngine On),先别开新线。

五、Google 怎么加:两边写法不一样,别填串

1)云锁防盗链例外 —— 填「裸域名」

  1. 应用防护 → 网站防盗链 → 白名单设置 / 例外名单
  2. 点「新增」,输入框逐条填:google.com
  3. 点「加入例外 / 确定」,回到设置页再单独点一次「保存」
  4. 先只加这一条,观察两天防护日志里还有没有 google... 被拦,有再补 google.com.hk

格式:裸域名,不带 https://、不带路径、不带端口、不带星号。多数面板对 google.com 会连带匹配 www.google.com 这类子域。

最容易填错的一处:这个弹窗和「网站漏洞防护 / 抗CC」的「网站例外名单(文件或目录)列表」长得几乎一样,但不是同一个。
· 防盗链这页要来源域名:google.com
· 那两页要路径:/.well-known/acme-challenge/
别把 google.com 加到 ACME 那两页,也别把路径加到防盗链。切左侧菜单时看清标题是「网站防盗链」。

2).htaccess —— 用上面的两行版

即「原 7 家」一条 + 「Google 多后缀」一条并列,别两条都塞进同一个括号里图省事。Google Search Console 的「抓取诊断」测不出这两行加没加对:Googlebot 通常不带 Referer,走的是 !^$ 那条。要验就用下面手工带 Referer 的 curl。已收录链接不用重新提交、不用改 robots.txt、不用动 sitemap。

六、验证:命令与判读

先备份。.htaccess.bakN 会被 <FilesMatch "^\.ht"> 挡住,不会被下载。.htaccess 即时生效,不用重启 Apache。

copy C:\xampp\htdocs\.htaccess C:\xampp\htdocs\.htaccess.bak5

ECS 上把 probe 放回去(这台机器 curl.exe 被本机拦截,只用 CMD 内置命令):

mkdir "C:\xampp\htdocs\.well-known\acme-challenge" 2>nul
echo ok> C:\xampp\htdocs\.well-known\acme-challenge\probe.txt

在本地电脑(zcp52)跑,全部完整 URL、无省略号:

curl.exe -s -o nul -w "self=%{http_code} %{content_type}\n" -H "Referer: https://www.511yj.com/" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "baidu=%{http_code} %{content_type}\n" -H "Referer: https://image.baidu.com/" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "google_com=%{http_code} %{content_type}\n" -H "Referer: https://www.google.com/" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "google_hk=%{http_code} %{content_type}\n" -H "Referer: https://www.google.com.hk/" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "cnblogs=%{http_code} %{content_type}\n" -H "Referer: https://www.cnblogs.com/" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "empty=%{http_code} %{content_type}\n" "https://www.511yj.com/wp-content/themes/aldehyde/style.css?ver=1791971959"
curl.exe -s -o nul -w "acme=%{http_code} %{content_type}\n" "https://www.511yj.com/.well-known/acme-challenge/probe.txt"
条 必须是 说明
self 200 text/css 本站必须正常,否则就是规则写错
baidu 200 text/css 若回 200 text/html,是云锁白名单没覆盖 image.baidu.com 子域,去防盗链例外补一条即可,不改 .htaccess
google_com 200 text/css 云锁放行 + .htaccess 放行,两层都过
google_hk 200 text/css 两行版就过;若单行版会 text/html,去云锁补 google.com.hk
cnblogs 200 text/html 云锁在 Apache 之前先拦成 HTML 页,测不到新规则,正常
empty 200 text/html 空 Referer 也已被云锁拦。这正是「B 版零收益」的实测证据
acme 200 text/plain probe 文件放回去就对了
判读两条铁律:
① 别拿 cnblogs / empty 判断新规则生没生效 —— 它们都在云锁层被截了,到不了 Apache。这层是双保险,不追求在 curl 里看到 403;真看到 403 反而说明云锁没拦住。
② acme=404 不是被防盗链拦的。[F] 回的是 403,404 是 Apache 的 Not Found,只说明 probe.txt 不在磁盘上(被删了,或被 Validation.CleanupFolders: true 清掉)。把文件放回去即可,跟证书路径无关。

self 不是 200,或 acme 不是 200,就回退,即时生效:

copy C:\xampp\htdocs\.htaccess.bak5 C:\xampp\htdocs\.htaccess

测完删掉 probe.txt。

七、ACME 例外:和防盗链弹窗长得像,但不是一回事

之前给「网站漏洞防护」和「抗CC攻击」加的 */.well-known/acme-challenge/ 是路径例外,按功能隔离,防盗链不认。实测 www / bbs 两条 probe 都是 200 text/plain 4。目录平时不存在是正常的 —— wacs 续期时自己 mkdir → 写无扩展名 token → 验证完删掉,例外名单存的是路径字符串,不要求目录当前存在,直接手打即可。

抗 CC 阈值是 60 秒 200 次 / 锁定 300 分钟,三个域名一共几个 GET 连零头都够不到,「脚本验证跳转方式 HTTP 200 / 302」保持默认 200 别动 —— 真被挑战,两种都拿 HTML 而不是 token,关键从来是别触发。

八、顺带核查过的云锁设置:全部保持原样

页 / 项 现状 结论
允许的请求类型 GET / POST / HEAD 全齐,别加 OPTIONS / PUT / DELETE / TRACE。GET 覆盖 LE 回读 token
禁止下载的文件类型 db mdf log mdb dat myd bak sql md 合理。没有 css/js/png/gz 是对的,尤其别加 gz(首页缓存本身就是 index.html.gz)
网页浏览实时防护后缀表 asa / asp / aspx / cgi / jsp / php / php3 / php5 / php7 / phtml … 防源码被当文本读,不阻断 PHP 执行。别删 php、别加 html / gz。ACME token 无后缀天然不进表
网站漏洞防护四个未勾 溢出防护 / HTTP响应内容保护 / 请求头防护 / 隐藏版本 前三个保持不勾(本站全是代码 / SQL / 命令行教程,响应内容保护必误伤);只勾「隐藏WebServer版本信息」
隐藏版本信息 已勾,实测 Server: 511yj 达标。后面的「设置」不用点,别去改自定义串
防端口扫描 10 秒内 10 个端口 / 锁定 60 分钟 合适,别动。别从本地跑 nmap 扫自己 ECS,封的是源 IP,会把自己的 3389 锁 60 分钟
抗 CC 60 秒 200 次 / 300 分钟 / 低(智能验证) 偏宽松但够用,别为 8214 条日志调紧

累计拦截攻击次数 117.10 万次 是这台机器云锁所有防护的全局累计,不是某一功能、更不是今天的新故障;「今日拦截 5138 / 5220 次」才是当天量。别被大数吓到去调参。CPU 平时低于 10%、内存 70% 主要是 httpd 1.1~1.2 GB(mod_php 内存池只申请不归还),跟这些勾选无关,别为内存去关防护。

九、踩坑清单

云锁例外名单是放行列表,不是黑名单。看标题「不再受此功能的保护」,别当成拦截名单去清空或往里加敌人。
三个功能的例外名单各存各的。每页单独点一次「保存」,关掉弹窗再进来确认条目还在,才算落地。
填错格式。防盗链填域名 google.com;漏洞防护 / 抗CC 填路径 /.well-known/acme-challenge/;带尾斜杠、不写 http://、不写盘符。
用省略号当占位。把 ... -H ... ...style.css 原样粘进 CMD 会得到 curl: (3) URL rejected: Bad hostname 和 (6) Could not resolve host —— 不是网站问题、不是 DNS 问题,是 curl 把 ... 当成字面主机名。所有命令写完整 URL。
修复后用手工伪造的裸域 Referer 自证失败。真实浏览器地址栏已是 www,不会发那种请求;判断只看最终 URL 和新无痕窗口。
把 css/js 加进「禁止下载的文件类型」。那是另一张表,加了自己站也没样式。
点「恢复默认配置」。一点刚加的例外全清。
在 ECS 上跑 curl.exe 做验证。这台机器会报「拒绝访问」—— 是本机进程创建被拦,不是网络不通(不通会显示 code=000)。网络类验证一律在本地电脑跑。

十、命令速查

用途 命令 在哪跑
备份 .htaccess copy C:\xampp\htdocs\.htaccess C:\xampp\htdocs\.htaccess.bak5 ECS
回退 copy C:\xampp\htdocs\.htaccess.bak5 C:\xampp\htdocs\.htaccess ECS
确认新增行落盘 findstr /i /c:"静态资源防盗链" C:\xampp\htdocs\.htaccess ECS
确认 junction 还挂着 fsutil reparsepoint query "C:\xampp\htdocs\bbs\.well-known" ECS
带 Referer 验证 curl.exe -s -o nul -w "%{http_code} %{content_type}\n" -H "Referer: ..." "完整URL" 本地
确认版本头已隐藏 curl.exe -sI https://www.511yj.com/ | findstr /i "server" 本地
看证书到期(顺手) C:\xampp\apache\bin\openssl.exe x509 -in C:\xampp\apache\conf\ssl\www.511yj.com-crt.pem -noout -dates ECS

十一、不动清单与边界

  • 不加 cnblogs、不删原有七条、不勾允许空 Referer、不上 B 版、不整体关防盗链。
  • 其余全不动:两条裸域 301、证书(2026-11-12 00:36 落地,下次自动续期 2027/1/5)、ECN disabled、junction、Certificates_bak、两处 ACME 例外、抗 CC、防端口扫描阈值、监控/防护模式。
  • ACME 的 /.well-known/acme-challenge/ 会被裸域 301 带到 www,LE 允许跟随 301、junction 让两边读同一份文件,1/5 自动续期不受这轮任何改动影响。
  • 别人 HTML 里那行 img / link 删不了,请求还是会来;能做的是让「不认自己人」的请求在尽量靠前的位置被便宜地拒掉。真「本机零处理」只有把图片 / CSS 迁到带 Referer 黑名单的 CDN / OSS,那是改媒体库 URL 的大工程,不是这次做的。
  • 抓取结果里那些「资源解析服务请求失败」:畸形 www.511yj.com%、W3C XHTML DTD、style.css 的「网站防火墙」旧留存、首页正文快照,全是抓取通道超时或历史留存,不是站点状态,别当新线索。
一句话收住:别人的文章你删不了,也别放行;云锁保持防护模式把外站 Referer 挡在 Apache 之前,.htaccess 做第二道按后缀的便宜拒绝,搜索引擎和 Google 两边按各自格式补白名单。日志还在涨不代表机器在扛,收录也不会因此掉。

记录时间:2026-11-12 · 三份笔记之三(证书续订 / 裸域 301 / 防盗链)

分享到:

用微信扫一扫,分享给朋友


发布日期:

所属分类: SEO 网站运营 标签:  



下一篇:

没有了,已经是最新文章