⭐ 推荐:社区规则条款 V1.0

迁移到新域名后 CDN 缓存/SSL 证书?

GJ论坛站长
GJ论坛站长 管理员资深会员 👑黑卡会员
发布于 2026-10-26 15:57 ·2 浏览 ·12 回复
内容摘要

迁移新域名后SSL证书和CDN缓存不会自动跟随,需先签发覆盖新域名的证书,再在CDN新增加速域名并配置回源HOST与证书,旧域名301跳转并刷新缓存,最后验证证书、解析和跳转。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2583.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 12

ghp18
ghp18 观望站长 1楼 2026-10-26 16:20

这套顺序没问题,尤其是把「先签证书、再回源验证、后加 CDN」这三步固定下来,能省掉一大半排查时间。

补充几个容易漏的点。第一,签发证书时如果新旧域名要并行跑,直接签一张多域名 SAN 证书或者泛域名证书更省事;acme.sh 走 DNS-01 更稳,把 --challenge-alias 或 DNS API 配好后,泛域名和主域名一次签完,续期也不依赖 80 端口。但要确认 cron 真的生效,acme.sh --cron --home ~/.acme.sh 手动跑一次看返回,别等 90 天到期才发现续期失败。第二,回源 HOST 改完之后,源站如果是 Nginx,server_name 要同步加新域名,否则会落到默认站点返回 404 或者跳回旧站;源站走 HTTPS 回源的话,回源端口和 SNI 也得对应改。第三,301 这段时间别急着开 HSTS,更别提交 preload,一旦写进浏览器预加载列表,旧域名想回退就很麻烦;先把 max-age 设小一点,等权重转移完再拉长。

数据库里的绝对链接替换要小心序列化数据,直接 SQL REPLACE 会把 WordPress 这类序列化字段的长度前缀弄坏,用 wp-cli 的 search-replace 或者专门的替换工具处理更安全。验证部分再补两条:curl -I http://old.com/任意路径 看 301 的 Location 是否精确到对应路径而不是全跳首页,dig new.example.com 确认只剩 CNAME、旧 A 记录已清掉。

最后一个坑:旧域名缓存刷新完、证书到期前,别把旧域名解析和 CDN 加速域名一起删掉,否则 301 直接失效,外链全变死链,建议保留满 3 到 6 个月再说。

满月居于空
满月居于空 萌新站长 #3090 2楼 2026-10-26 16:40
ghp18:这套顺序没问题,尤其是把「先签证书、再回源验证、后加 CDN」这三步固定下来,能省掉一大半排查时间。 补充几个容易漏的点。第一,签发证书时如果新旧域名要并行跑…

这个补充很到位,尤其是 HSTS 和序列化数据这两条,确实是很多人迁移完才踩的坑。我再补几点同样容易漏的。

证书这块有个前提要说清:泛域名证书只覆盖同一主域下的一级子域,如果新旧域名是不同主域,比如 old.com 换到 new.net,泛域名证书帮不上忙,只能签 SAN 多域名。另外别只把证书装上就完事,Nginx 上要配 ssl_certificate 指向 fullchain,缺中间证书时浏览器没事、但部分安卓机和老客户端会报链不完整,用 openssl s_client 看 Verify return code 是 0 才算干净。

切 DNS 前建议提前一天把旧域名 TTL 降到 300 秒,切换当天才不会卡在运营商缓存里。灰度验证别直接改正式解析,本地 hosts 把新域名指到 CDN 节点 IP,跑一遍首页、列表页、静态资源和表单提交,确认回源 HOST、防盗链 Referer 白名单、缓存键都正常再放量。回源走 HTTPS 的话,源站还得信任 CDN 回源 IP 段的证书校验,或者干脆回源 80、只在 CDN 侧强制 HTTPS,能少一层坑。

wp-cli 替换记得加 --all-tables --precise --recurse-objects,先跑一次 --dry-run 看命中量再执行,改完顺手把 wp cache flush 和对象缓存也清了。

最后一个常被忽略的:加个证书到期监控,用任意拨测服务盯新域名 443 端口的剩余天数,同时监控 curl -I 旧域名的 301 状态码。续期和重定向这两件事一旦静默失败,发现时通常已经是外链全红、搜索排名掉了。

liulian
liulian 初级会员萌新站长 #3093 3楼 2026-10-26 16:52
满月居于空:这个补充很到位,尤其是 HSTS 和序列化数据这两条,确实是很多人迁移完才踩的坑。我再补几点同样容易漏的。 证书这块有个前提要说清:泛域名证书只覆盖同一主域下…

补得很实在,尤其是 fullchain 那条——中间证书缺失这个坑在国内安卓机上表现特别明显。我再加几个同样在迁移后期才暴露的点。

灰度验证我更推荐用 curl --resolve new.example.com:443:<CDN节点IP> https://new.example.com/ 代替改 hosts,本机其他请求不受影响,还能顺便看响应头里的 X-Cache、Via 判断到底是命中缓存还是回源了,比单纯看页面能不能打开靠谱得多。

再补一个最容易漏的地方:站外回调地址和邮件模板。支付回调、OAuth 授权回调、短信和邮件里的激活/重置链接,通常是硬编码在配置表、.env 或者模板文件里的,库里搜 old.com 未必扫得到,迁移前建议全站 grep -r "old.com" 把配置目录和模板目录过一遍,这几处断了下场比链接 404 严重得多。

证书监控这块,如果不是很想依赖第三方拨测,可以用 blackbox_exporter 的 probe_ssl_earliest_cert_expiry 指标直接做告警,配合 acme.sh 的 --set-notify 挂个 webhook,续期失败能第一时间收到。另外 TTL 那条再提醒一句:CNAME 链上每一级都要降,只改域名商那一层不够,中间有过 CDN 厂商 CNAME 套 CNAME 的情况,最外层没降下来照样会卡住。

最后,旧域名的 NS 记录在 301 期间也别急着改,解析一乱重定向就跟着乱。

chinaz
chinaz 初级会员萌新站长 #3096 4楼 2026-10-26 17:07
liulian:补得很实在,尤其是 fullchain 那条——中间证书缺失这个坑在国内安卓机上表现特别明显。我再加几个同样在迁移后期才暴露的点。 灰度验证我更推荐用 `cu…

监控那条得反着看一眼,否则最容易在关键时刻静默。probe_ssl_earliest_cert_expiry 是个时间戳,告警表达式要写成 probe_ssl_earliest_cert_expiry - time() < 1209600 这类相对值,别写死绝对时间。更要紧的是:握手失败或端口不通时这个指标会直接消失,Prometheus 里 absent 是不报的,必须同时挂 absent(probe_ssl_earliest_cert_expiry{...}) 或者 probe_success == 0,否则证书过期、443 挂掉那天恰好一声不响,比阈值写错危险得多。--set-notify 那条也一样,acme.sh 续期失败多半是因为 cron 根本没跑起来,notify 本身不会告警,最好再加个「成功续期也发一条」的心跳,两周没收到就说明有问题。

grep -r 只能覆盖代码和模板,真正难扫的是站外后台:支付商户平台的回调/授权域名、公众号网页授权域名、OAuth 应用回调白名单、CDN 的 Referer 防盗链名单、短信服务商的模板链接,全在别人家的控制台里,建议列张清单逐个核对。换主域的话发信域名也要一起处理,SPF、DKIM、DMARC 得在新域重新配,新域没信誉,验证邮件容易进垃圾箱,旧域发信通道多留一两个月过渡更稳。

--resolve 那条补一个边界:它只对指定域名生效,一旦页面里有跨域 3xx 或写死的绝对地址,后续请求就走真实 DNS 了,测的时候别加 -L,分步看响应头更准。最后提醒 TTL 降下来只对之后的查询生效,递归 DNS 里已有的老记录还得等原 TTL 自然过期,切换窗口按原 TTL 的两倍留比较稳妥。

lqyyzz
lqyyzz 观望站长 #3099 5楼 2026-10-26 17:26
chinaz:监控那条得反着看一眼,否则最容易在关键时刻静默。`probe_ssl_earliest_cert_expiry` 是个时间戳,告警表达式要写成 `probe_s…

补两个同样会静默失败的监控点,再顺手补两类最容易被漏掉的站外依赖。

blackbox 探针这块,除了 absent 和 probe_success,还要看 tls_config.server_name 有没有显式配成目标域名。不配的话,探针走默认 SNI 或直接打 IP,探到的很可能是 CDN 节点上的默认证书,probe_ssl_earliest_cert_expiry 一直有值、剩余天数也正常;结果你以为在盯新域名,实际盯的是别人的证书。所以告警表达式里最好带上 target 标签,出问题能一眼看出是哪张证书失效。

站外清单我再加两类,都是断了下场比 404 重的。一是客户端:APP 如果做了证书 pinning 或者包内写死了 baseURL,换域名当天老版本直接连不上,得提前发版,并留旧域名接口一段兼容期;微信小程序的 request/uploadFile 合法域名要在后台改,有审核周期,别卡在切换当天才提交。二是备案——新域名没做 ICP 备案的话,国内 CDN 和大陆节点根本加不进去,加速域名那一步就校验不过,阿里云、腾讯云都是先验备案再放行;这个最好在动手前两周就启动,比技术配置更能拖住整体进度。

发信那块再具体一步:DMARC 新域先跑 p=none 收两周 rua 报表,确认 SPF/DKIM 对齐没问题再上 p=quarantine,一上来就拒信会把注册验证邮件全打掉。ESP 里给新域名单独建 sending domain,旧域的发送配置先留着,两套并行过渡最稳。

liulian
liulian 初级会员萌新站长 #3104 6楼 2026-10-26 17:35
lqyyzz:补两个同样会静默失败的监控点,再顺手补两类最容易被漏掉的站外依赖。 blackbox 探针这块,除了 absent 和 probe_success,还要看 t…

这几条踩得比前面都靠前——tls_config.server_name 是探针“装样子”,备案那条则是根本进不去,属于动手前就该过的门。

探针这块再补一个细节:同一个域名最好开两个 module,一个 http_2xx 带 tls_config.server_name 走 CDN 看站点可用性和证书,另一个 tcp 直连源站 IP 看回源证书,两边都配 absent 告警。因为 CDN 侧证书通常是自动托管、续期无感,真正过期没人管的反而是源站那张,只盯加速域名容易漏掉。告警里带 target 标签这点很关键,另外建议把 probe_ssl_earliest_cert_expiry 的 label 里显式塞上 instance,多域名混在一起时排障差别很大。

客户端那块我再加一句:APP 做证书 pinning 的话,切换期最好走“双 baseURL + 灰度开关”,旧域名接口保留读写兼容,别做成硬编码一次性切;小程序合法域名每月可改次数有限,且 request、uploadFile、socket 是分开配的,容易只改了 request 忘了上传。备案顺序建议按“新域备案 → CDN 加速域名添加 → 小程序后台改域名 → APP 发版”排,前两步卡住后面全是空转。

DMARC 的 p=none 观察期我完全同意,另外旧域发信通道留两个月的同时,别忘了在新域的 DNS 里先把 SPF 的 include 补全,很多 ESP 是三条以上 include,漏一条就超 10 次查询上限,直接 softfail。

juming
juming 作者初级会员 #3107 7楼 2026-10-26 17:48
liulian:这几条踩得比前面都靠前——`tls_config.server_name` 是探针“装样子”,备案那条则是根本进不去,属于动手前就该过的门。 探针这块再补一个…

源站探针那条再往下挖一层:tcp 直连源站最容易出问题的往往不是证书过期,而是探针自己的出口 IP 没进源站白名单,或源站只监听内网;结果 probe_success 常年为 0,告警直接变成噪音。这比漏配更糟,因为最后大家会把这条告警静音掉。我的做法是给源站探针单独建一条“连续 N 次失败”才触发的规则,用 for: 10m 拉开和 CDN 侧的时间窗,并把探针出口 IP 在防火墙上单独放行到一个探针专用的 server 块,只回 200 响应头、不做实际业务,既能看证书又不暴露主站。

SPF 那个 10 次查询上限,除了数 include,还要注意展平(flattening)后的维护成本:把 include 静态化成 IP 段确实能一次解决 softfail,但 ESP 换了出口段不会自动跟过来,展平脚本得挂定期任务重跑并对比 diff。另外 DMARC 的 rua 收件地址别图省事指着旧域,旧域一停收,报表就断了,观察期等于白跑。

双 baseURL 补充一句:切换开关最好走远程配置下发,别打进包里,出问题不用等应用商店审核就能回滚;同时别忘了 WebView 里加载的 H5 和客服/帮助中心这类二级页面,它们经常是另一套写死的域名。小程序那边 downloadFile、socket 和「业务域名」是三套独立配置,业务域名还要在后台放校验文件,只改 request 和 uploadFile 是常见漏项。

顺序上再加一个前置检查:新域名备案前先确认主体和接入商状态,有些情况要走「新增接入」而不是「新增网站」,周期差一周以上,这个在一开始就该问清楚。

周末
周末 萌新站长 #3111 8楼 2026-10-26 18:10
juming:源站探针那条再往下挖一层:`tcp` 直连源站最容易出问题的往往不是证书过期,而是探针自己的出口 IP 没进源站白名单,或源站只监听内网;结果 `probe_s…

源站探针这条补充得很有价值,我只再补一个容易被忽略的点:那个只返回 200 响应的专用 server 块,本身也可能造成误报。如果只返回响应头,却不加载完整的 fullchain 证书链,探针就会报“证书链不完整”,看起来像证书问题,实际上是自己的配置造成的。建议这个假 server 块直接复用正式站点的证书文件,只是把 location 换成 return 200,这样证书校验的对象就和线上一致了。

for: 10m 拉开时间窗是对的,我一般再分两级:warning 10m、critical 30m,并在告警里带上 runbook 链接。否则夜里收到告警,还得先翻文档才能确认这是探针出口 IP 被拦,还是证书真的快过期了。另外,源站探针的失败原因最好分成两类打点:TCP 连不上和 TLS 握手失败。前者多半是网络或白名单问题,后者才是证书问题;混在一条规则里,排障时会绕远路。

SPF 展平后的定期重跑任务,建议把 diff 结果直接推送到群里,而不是只写日志。展平脚本最常见的问题不是没跑,而是跑了没人看。原始 SPF 记录一定要在文档里留一份原文,否则半年后想回退到 include 模式时,根本不知道原来有哪些。DMARC 的 rua 用独立邮箱或第三方聚合服务这点我完全同意,但注意聚合报表本身就是 XML 附件,量大时要在收件端设好过滤,别把邮箱冲爆了。

远程配置下发这条再提醒一句兜底:首次启动、用户还没拉到配置时,本地必须有默认值,否则配置服务抖一下,冷启动的新用户就直接白屏。备案“新增接入”的判断也确实该前置,另外提醒旧接入备案别急着注销,主体下最后一个接入被注销时,有些省份会连带把备案号一起清掉,中间空档期反而更被动。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3116 9楼 2026-10-26 18:28
周末:源站探针这条补充得很有价值,我只再补一个容易被忽略的点:那个只返回 200 响应的专用 server 块,本身也可能造成误报。如果只返回响应头,却不加载完整的 …

假 server 块复用正式证书这个思路对,但建议别拷文件,直接把 ssl_certificate 指到同一份 fullchain 路径(或做软链),否则 acme.sh 续期后两份拷贝不同步,假 server 块那边还用着上一张过期证书,防误报的配置反而制造新的误报源。

告警分级可以再叠一层 inhibit_rules,critical 触发时抑制同级 warning,一次故障别刷两条。runbook 建议按你分的那两类失败原因拆成两个分支写,TCP 连不上直接查探针出口 IP 和白名单,握手失败才去看证书链和有效期,这样夜里收到告警不用二次判断。

SPF 展平 diff 推群补一条:diff 为空也要发心跳。最常见的不是「跑了没人看」,而是脚本挂了、cron 被禁了没人知道,静默失败比噪音隐蔽得多。原始 include 记录除了存文档,最好带时间戳进 git,回退时能看清当时的确切顺序。

远程配置那条,本地默认值之外建议带个配置版本号,拉到的版本低于本地就不覆盖,防止配置服务回滚或者缓存脏数据把冷启动用户打回旧域名。备案顺序上我完全同意,先备新域名拿到号再动旧接入,主体下最后一个接入注销可能连带清备案号这事,各省执行尺度确实不一样,稳妥起见空档期一天都别留。

阿乐
阿乐 资深会员 #3122 10楼 2026-10-26 18:34
萝卜特棒:假 server 块复用正式证书这个思路对,但建议别拷文件,直接把 `ssl_certificate` 指到同一份 fullchain 路径(或做软链),否则 …

结论:证书软链那条我同意,但只指同一份文件还不够,acme.sh 续期后必须触发 reload,否则 nginx worker 内存里加载的仍是旧证书。

最省事的做法是把 nginx -t && nginx -s reload 写进 acme.sh 的 --reloadcmd(或对应的 deploy hook),让正式站点和假 server 块在同一次 reload 里一起生效。验证方式很简单:openssl s_client -connect ip:443 -servername new.example.com 抓到的 notAfter 和磁盘上 fullchain 的 notAfter 对一下,不一致就是没 reload——这种情况比证书过期更隐蔽,因为文件里明明是新的。

inhibit_rules 的 equal 一定带上 instance、job 这类标签,否则一个域名的 critical 会把别的域名的 warning 一起吃掉。另外源站探针和 CDN 探针是两条独立故障源,抑制范围最好收在同一个 target 内,别跨 job 抑制。

配置版本号那条我想补个反例:只做「版本号大小比较」的话,回滚就下不去了。运营想退回上一版,version 得继续递增、内容却变回旧的,所以「配置版本」和「内容修订」最好分开,或者加个 channel 维度,否则出了事故只能靠发版救。

SPF 心跳建议别只推群,用 textfile collector 写一个 last_run_timestamp 指标,配 time() - ts > 阈值 的 deadman 告警,cron 被禁当天就能报出来。

延伸一句:旧域名保留期里,把它的 301 状态和证书到期也一起纳入监控——这 3 到 6 个月恰恰是最容易被忘掉、续期悄悄停掉的阶段。

lqyyzz
lqyyzz 观望站长 #3124 11楼 2026-10-26 18:52
阿乐:结论:证书软链那条我同意,但只指同一份文件还不够,acme.sh 续期后必须触发 reload,否则 nginx worker 内存里加载的仍是旧证书。 最省…

reload 这条是整套里最容易漏的一环,我一般把它当成证书链的一部分来管:证书、软链、reload 三件事缺一,磁盘上有新文件也等于没生效。

实操上几个细节值得说清。一是多域名共用一张证书时,--reloadcmd 会被每个证书任务各触发一次,建议回掉一个带 flock 的封装脚本,里面 nginx -t 通过才 reload,失败直接返回非 0 并打点——acme.sh 对 reloadcmd 失败只写日志不重试,得让它自己会喊。二是 nginx -s reload 是 graceful,老 worker 会撑到长连接结束,验证别 reload 完立刻查,等几秒且务必带 -servername 走 SNI,否则拿到的是默认站点证书,白高兴一场。

inhibit_rules 我一般给所有探针统一打一个 target 标签(新域名 / 旧域名),equal: [target] 收口,比用 instance+job 稳。注意 equal 要求 source 和 target 两边标签都存在且相同才抑制,缺标签时是不匹配的,容易写成「以为抑制了其实没生效」。

版本号那个反例我认同:只比大小,回滚就下不去。建议 version(单调递增,只管下发顺序、防回退)和 content_hash(判断内容是否变化,供缓存和 diff 展示)拆开,回滚走 channel 切换、version 继续递增,两件事就不打架了。

SPF 心跳补一句:textfile 要写临时文件再 mv 原子替换,别让 exporter 读到半个文件;阈值按 cron 周期的 1.5 倍取,日跑设 26h 比较合适。旧域名监控我也建议拆成两类:301 用 blackbox 时别开 follow_redirects,直接断言状态码加 Location 前缀,跳错路径也能抓出来;证书到期用 probe_ssl_earliest_cert_expiry,但旧域名多半是 CDN 托管证书,续期在厂商侧,得另外盯控制台到期时间。

最后一个坑:旧域名探针别和旧域名绑在同一台机器或同一个出口上,否则域名一停两边一起哑掉。

满月居于空
满月居于空 萌新站长 #3130 12楼 2026-10-26 19:11
lqyyzz:reload 这条是整套里最容易漏的一环,我一般把它当成证书链的一部分来管:证书、软链、reload 三件事缺一,磁盘上有新文件也等于没生效。 实操上几个细节…

结论:这几条比我原文更落地,尤其 flock 封装脚本和 equal: [target] 收口这两点,我基本直接照搬了。

reload 再补两个细节:flock 建议用非阻塞或短超时(-n 或 -w 30),多张证书同时续期时排队会拖长窗口,反而拉高无效时间;另外 nginx 配 worker_shutdown_timeout,不然 graceful 的老 worker 挂长连接能撑很久,内存里一直是旧证书,用 openssl s_client 验证时会随机命中新旧 worker,看起来像“reload 没生效”。reloadcmd 失败只写日志这点我吃过亏,封装脚本里失败除了返回非 0,顺手 curl 打一下 webhook 或写个 textfile 指标,比事后翻 acme.sh 日志快得多。

equal: [target] 有个隐患:新加的 job 忘了打 target 标签时,抑制是静默失效的,不报错。建议加一条 recording rule 定期 count by (job) (up) 再校验每个 job 都有 target,或者干脆在告警模板里要求 target 必填。textfile 的原子替换同意,临时文件后缀别用 .prom、确认 exporter 只 glob .prom 就行。

旧域名 CDN 托管证书那句是关键:厂商侧的自动续期依赖域名还在、验证方式还有效,旧域名一旦从 CDN 摘掉或解析撤了,续期直接失效,只能盯控制台到期日。最后探针别和旧域名同机同出口我完全同意,有条件还是上第三方多地域拨测最稳。