证书是什么:身份档案 + 签名
X.509 证书的核心内容就三样:域名的身份信息、公钥、CA 的数字签名。签名的作用是防伪——CA 用自己的私钥对“身份信息 + 公钥”的摘要签名,谁都能用 CA 的公钥验证:这份公钥确实属于这个域名,中间没人调包。证书不负责加密(加密靠握手篇说的密钥交换),它只回答一个问题:你就是你声称的那个人吗。
信任链:从根到站点逐级背书
浏览器不可能内置全球几十万个网站的证书,它内置的是一百多个根 CA 的公钥,其余全靠逐级验证:
根 CA(内置信任,私钥离线锁保险柜)
└─ 签发 ─→ 中间 CA(日常发证的主力)
└─ 签发 ─→ note.example.com(你的站点证书)
验证过程:
1. 用中间 CA 的公钥验站点证书的签名 ✓
2. 用根 CA 的公钥验中间 CA 证书的签名 ✓
3. 根证书在浏览器内置列表里 ✓
4. 检查域名匹配、有效期、吊销状态 ✓
→ 信任成立(信任是可以传递的)部署时常见翻车点:只配了站点证书、漏配中间证书链——自己浏览器开着没问题(缓存过),用户手机上却报证书错误。用 openssl s_client -connect 域名:443 看 Certificate chain 是否完整。
SNI:一台机器服务一百个域名
TLS 握手发生在 HTTP 请求之前——鸡生蛋问题:服务端要在看到 Host 头之前就挑出正确的证书。早期一 IP 一证书,多域名站点要配多个 IP。SNI(Server Name Indication)扩展破局:客户端在 ClientHello 里就把要访问的域名明文带过来,服务端按域名选证书。副作用:SNI 明文意味着“访问哪个域名”全程可见(这也是 ECH 加密 SNI 要解决的问题)。CDN、一台 Nginx 挂几十个 HTTPS 站点,全靠 SNI。
证书运维事故清单
| 事故 | 根因 | 预防 |
|---|---|---|
| 半夜全站报证书错误 | 过期,没人盯 | 监控剩余天数 < 30 天告警 |
| 部分用户报错部分正常 | 缺中间证书链 | openssl 验证完整链 |
| 域名不匹配 NET::ERR_CERT_COMMON_NAME_INVALID | 证书不含该子域名 | SAN 列表覆盖或泛域名 |
| 续期脚本静默失败 | crontab 无通知 | 失败告警 + 过期监控双保险 |
Let's Encrypt 把证书寿命压到 90 天,就是逼所有人上自动续期(acme.sh / certbot),证书运维的正确姿势是把它变成无人值守的基础设施,而不是留个日历提醒。下一篇:DNS——域名变成 IP 的第一跳,就藏在它的解析链里。
评论 (0)