Caddy 终端 HTTPS 正常,systemd 启动后证书不可信:核对本地 CA
Caddy 改用 systemd 后内部 HTTPS 不可信,先区分启动权限与客户端校验,再比较数据目录、本地 CA 指纹及客户端信任库。
用自己的账户运行 Caddy 时,https://localhost:8443/ 可以访问;改由 systemd 的 caddy 用户运行后,服务已经启动,客户端却报 unable to get local issuer certificate。对于 Caddy 2 的内部 HTTPS,这时应比较两种启动方式使用的本地 CA 和客户端信任库。
运行账户或存储目录发生变化,可能让服务使用另一套内部 CA,而浏览器还信任以前那一套。这是一个可核对的原因,不能仅凭切换启动方式就认定。本文适用于 localhost、内部名称或明确采用内部签发机构的站点;公有 CA 证书的证书链问题需要另行检查。
服务未启动,先处理文件访问错误
查看服务日志,区分两种状态:
open .../Caddyfile: permission denied或读取root.crt失败,发生在配置读取或内部 CA 初始化阶段,服务可能尚未成功提供 HTTPS。- 服务已正常监听,客户端出现证书校验错误,才进入 CA 身份和信任库检查。
以 caddy 用户能读文件,只证明该用户在当前命令环境下有普通文件权限。systemd 的文件系统限制、目录逐级访问权限及 SELinux 标签仍可能阻止服务访问。配置用了符号链接时,也要检查最终目标及其父目录。
按日志定位被拒绝的具体路径,修正该路径的权限或发行版要求的标签。不要把配置、证书目录统一设成全员可写,也不要把关闭 SELinux 当成证书信任的修复步骤。
比较实际存储目录和 CA
Caddy 的默认本地文件存储在 Linux 上通常是 $HOME/.local/share/caddy;设置了 XDG_DATA_HOME 时使用 $XDG_DATA_HOME/caddy。自定义存储模块或服务环境可以改变位置,因此要查看实际 unit、环境和启动日志。
按官方 Linux 服务配置,caddy 用户的 HOME 是 /var/lib/caddy,默认数据目录是:
/var/lib/caddy/.local/share/caddy
内部 CA 的证书和密钥位于数据目录内的 pki/authorities/local。个人账户下生成的 CA,与服务账户另一数据目录中生成的 CA,可能有不同的根证书和密钥;两份证书都叫“Caddy Local Authority”并不能证明它们相同。
分别查看旧运行方式和当前服务的数据位置,比较根证书指纹,再从浏览器证书详情确认当前访问到的服务器证书是否由预期 CA 签发。还要排除端口上仍有旧进程、访问了不同主机以及证书名称不匹配。错误只发生在某个浏览器时,也可能是它使用独立信任库。
数据目录保存了证书和私钥,必须可写且持久化。删除目录让 Caddy 重建会改变 CA 身份,可能使所有信任旧根的客户端失效。
信任当前 CA,或有计划地保留原 CA
如果服务账户使用新 CA 是预期安排,从管理员确认过的实际数据目录取得它的 root.crt,核对指纹后导入需要访问站点的客户端信任库。导入的是公开根证书,不能分发 root.key 或其他私钥。操作会让客户端信任该 CA 所签发的证书,应只导入由自己管理且身份已核实的 CA。
系统信任库和浏览器信任库可能不同;远程设备也各自需要信任。Caddy 在服务器上尝试安装根证书,不会自动替所有客户端完成这一步。
若必须保留旧 CA,先备份相关持久化状态,确认安全的迁移方案,再在维护窗口把必要状态迁移到服务可访问的存储位置,保留私钥的受限权限。不能为复用 CA 把服务直接改成 root,或开放整个个人 HOME。修改运行环境和存储位置后可能需要重启,期间会中断连接;保留旧环境、unit 与数据备份供回退,避免两个实例同时使用迁移中的状态。
创建内部 CA 需要对存储位置有适当权限;把根证书加入系统信任库则可能需要管理员权限,两者是不同操作。skip_install_trust 只跳过自动安装信任,不会关闭内部 CA,也不会让客户端自动接受证书。
确认修复没有依赖跳过校验
用正常启用证书验证的客户端访问预期名称和端口,确认实际服务证书、CA 指纹与所信任的根一致,且不再出现签发者错误。不要用 curl -k 或浏览器临时例外作为成功标准。
再经过一次受控服务重启,确认数据位置没有改变、CA 没有重新生成,必要客户端仍能访问。若撤销新 CA 的信任,要从对应的系统或浏览器信任库移除已核实的那份根证书;恢复旧服务设置不会自动清理客户端新增的信任。


