Skip to content
// 0x
Go back
0x05 // 工具设计

本地开发 SSL 证书踩坑实录 — 通配符、SAN 与 Chrome 信任链

本地开发环境通常用自签 SSL 证书或本地 CA 签发的证书来支持 HTTPS。多数时候配置一次就能稳定运行,但某天某个新域名突然在 Chrome 中抛出了 ERR_CERT_COMMON_NAME_INVALID,而其他域名一切正常,curl 和 openssl 也验证通过。本文记录完整的排查过程。

现象

这是一个典型的”部分正常、部分异常”问题,意味着方向不是证书信任缺失,而是域名匹配

排查过程

Step 1: 确认证书 SAN

openssl x509 -in fullchain.pem -noout -text | grep -A1 "Subject Alternative Name"

输出:

DNS:*.test, DNS:*.region-a.test, DNS:*.warehouse.test,
DNS:*.app.test, DNS:*.demo.test, DNS:*.fetch.test,
DNS:*.crawler.test, DNS:corpix.test, DNS:traefik.localhost,
DNS:health.localhost

*.test 应该匹配 app.test 吧?直觉上是的,但问题的根源就在这里。

Step 2: 通配符 SAN 的匹配规则

RFC 2818 规定,TLS 证书中的通配符 * 只能匹配一个标签(single label),不能跨级也不能匹配空标签:

证书 SAN匹配不匹配
*.example.comwww.example.comexample.com
*.testfoo.testapp.test
*.app.testapi.app.testapp.test
app.testapp.test

所以 app.test 匹配 *.test 的通配符模式只是直觉上的错觉——app.test 本身是根域名(零级子域),通配符并不会匹配。这是 ERR_CERT_COMMON_NAME_INVALID 的真因。

Step 3: Chrome 证书存储策略变化

解决 SAN 后,重新签发证书,Chrome 仍然报错——这次是 NET::ERR_CERT_AUTHORITY_INVALID

经过检查发现:

修复方式:

# 删除旧 CA
sudo rm -f /usr/local/share/ca-certificates/localdeva.crt
sudo rm -f /etc/ssl/certs/localdeva.pem
sudo update-ca-certificates

# 安装新 CA
sudo cp ca-cert.pem /usr/local/share/ca-certificates/localdevca.crt
sudo update-ca-certificates

Step 4: curl 与系统的证书路径差异

排查过程中另一个干扰项:curl 使用 anaconda/miniconda 自带的 CA bundle,不包含本地 CA,导致 curl 也验证失败。

curl-config --ca
# ~/miniconda3/ssl/cacert.pem

而系统 openssl 使用 /etc/ssl/certs/ca-certificates.crt,两者路径不同。测试时需注意区分:

# 跳过验证
curl -sk https://app.test
# 或指定系统 CA bundle
curl --cacert /etc/ssl/certs/ca-certificates.crt https://app.test

最终解决方案

三个问题逐一修复后,证书生成的工作流确定为一套自包含脚本:

  1. 证书生成generate-local-ca.sh

    • SAN 中同时包含通配符和裸域名:*.app.test + app.test
    • fullchain.pem 包含服务器证书 + CA 证书两个 PEM 块,形成完整信任链
    • 自动安装 CA 到系统信任存储
  2. CA 安装:仅需系统级安装(update-ca-certificates),不再需要 NSS 导入

经验总结

问题教训
SAN 通配符* 只匹配单级子域,不匹配根域名,每个裸域名必须显式声明
Chrome 证书存储134+ 使用系统 cert store,旧的 NSS 导入方式已失效
同名 CA 冲突更新 CA 前先清理旧证书,同名 CA 会被 update-ca-certificates 跳过
curl CA 路径Anaconda/miniconda 的 curl 使用独立的 CA bundle,测试时需区分

HTTPS 证书的问题往往不是单一原因,而是多条线索交织的结果。系统化的排查思路——从域名匹配、证书链验证、客户端信任存储到基础设施配置——比记忆具体命令更有长期价值。


Share this post on:

Previous Post
WMS 与 Shopify 的数据交响:订单同步全链路解析
Next Post
图片比例自动归类与裁剪系统设计