DNS 迁移到 Cloudflare 后的一系列部署问题排查
#Git #Cloudflare #acme.sh #部署
背景
博客采用如下部署架构:
1 | 本地 Mac ──git push──▶ 内网服务器 (hexo.git bare repo) |
将域名 DNS 从阿里云迁移到 Cloudflare 后,连锁触发了三个问题:SSL 续签失败、git push 超时、hexo hook 不触发。以下记录完整排查过程。
一、SSL 续签失败
现象
1 | [ERROR] Le_OrderFinalize |
原因
libcurl 错误码 3 为 CURLE_URL_MALFORMAT,acme.sh 缓存的 ACME 订单状态中 Le_OrderFinalize URL 损坏,通常在续签中断或订单状态不一致时出现。
解决
1 | # 删除损坏的缓存,强制重新发起 |
在 DNS 控制台添加 _acme-challenge TXT 记录,等待解析生效后:
1 | ~/.acme.sh/acme.sh --renew -d "<domain>" \ |
二、迁移到 Cloudflare 后 git push 超时
现象
1 | ssh: connect to host <domain> port 6002: Operation timed out |
排查
1 | ping -c 3 <domain> |
根本原因:104.21.56.64 是 Cloudflare 的代理 IP。DNS 迁移后域名 A 记录默认开启橙云(Proxied),Cloudflare 只代理 HTTP/HTTPS 流量,SSH 端口被拦截,push 无法到达内网服务器。
解决方案
方案一(推荐):git remote 直接使用服务器真实 IP,彻底绕过 CF 代理:
1 | git remote set-url deploy ssh://user@<真实IP>:<port>/~/hexo.git |
方案二:CF 控制台将 A 记录改为 DNS Only(灰云),域名直接解析到真实 IP。
CF 橙云适合 HTTP/HTTPS 流量加速与防护,SSH / 自定义端口 Git 部署必须用灰云或直连 IP。
三、post-receive hook 不触发
现象
push 命令显示超时失败,服务器上博客未更新,以为是 hook 失效。
实际原因
Push 根本没有到达服务器(被 CF 拦截),hook 从未被调用。fix git remote 后 push 恢复正常,hook 触发正常。
hook 的条件触发逻辑
现有 post-receive 脚本只在特定文件变更时才执行 hexo generate:
1 | CHANGED_FILES=$(git diff --name-only HEAD^ HEAD) |
坑:若 push 的提交只改了 server/、README 等非内容文件,hexo 不会重建,新文章不会部署。调试时注意区分"hook 未触发"和"hexo generate 被跳过"。
四、sudo 下 $HOME 路径错误
用 sudo bash script.sh 运行脚本时,$HOME 解析为调用用户的家目录(如 /home/username),而非 /root,导致 acme.sh 路径、account.conf 写入全部指向错误位置。
修复:脚本中所有 acme.sh 相关路径硬编码为 /root/.acme.sh/,不使用 $HOME 或 ~。
五、清理 git 历史中的敏感文件
误将包含配置脚本的目录提交进了 git 历史,需要从所有提交中彻底删除。
工具:git-filter-repo
1 | pip3 install git-filter-repo |
之后需要强制推送
1 | git push deploy master --force |
git filter-repo会重写全部提交的哈希值,force push 后所有已克隆的副本都会与新历史diverge,需要重新 clone 或 reset。
总结
| 问题 | 根本原因 | 解决 |
|---|---|---|
| SSL 续签失败 | acme.sh 订单缓存损坏 | 删除 _ecc/ 目录重新签发 |
| git push 超时 | CF 橙云拦截 SSH 端口 | remote 改用真实 IP |
| hook 不触发 | push 未到达服务器 | 同上 |
| hexo 不重建 | hook 条件判断跳过 | 检查变更文件是否匹配触发模式 |
| $HOME 路径错误 | sudo 不切换 HOME | 脚本内硬编码 /root/ |
| 历史含敏感文件 | 误 git add | git-filter-repo + force push |
