TLS 是什么
TLS(Transport Layer Security)是在 TCP 之上提供机密性、完整性与身份认证的协议,由记录层与握手层组成。握手层负责协商版本与套件、验证证书、协商会话密钥;记录层负责把应用数据切分加密并附上完整性校验。HTTPS 就是 HTTP over TLS,此外邮件、数据库复制、消息队列与 DNS 加密也都跑在 TLS 之上。
基本信息
| 主流版本 | TLS 1.3(RFC 8446)与 TLS 1.2(RFC 5246) |
|---|---|
| 默认端口 | 443(HTTPS) |
| 其他典型端口 | 465/587(SMTPS/Submission)、993(IMAPS)、995(POP3S)、853(DoT)、8883(MQTTS) |
| 协议分层 | 记录层(Record)+ 握手层(Handshake) |
| 身份凭证 | X.509 证书,由受信任 CA 签发或自建 CA |
| 关键扩展 | SNI、ALPN、会话票据、OCSP Stapling |
| 主流实现 | OpenSSL、BoringSSL、LibreSSL、rustls |
典型使用场景
- 网站与小程序后端:HTTPS 是默认要求,涉及支付与登录必须启用
- API 网关与开放平台:外部调用一律走 TLS,内部按零信任要求也常启用
- 数据库与消息中间件:MySQL 的 require_secure_transport、Kafka 与 RabbitMQ 的 TLS 监听
- 服务间通信:Kubernetes 内部服务用 mTLS 做身份认证
- 邮件收发:SMTPS/IMAPS 取代明文协议,避免凭据与正文裸传
- DNS 加密:DoT(853)与 DoH 防止解析结果被旁路篡改
连接与版本测试
连接与版本测试
# 查看握手结果、协议版本、套件与证书主体(必须带 SNI)
openssl s_client -connect example.com:443 -servername example.com </dev/null | head -20
# 限定 TLS 1.3 测试,确认服务端是否真的支持
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>&1 | grep 'Protocol'
# 指定 SNI 与 IP 直连,绕开 DNS 排查源站证书
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null | grep 'subject='
# 抓取服务端实际下发的整条链
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null | grep -c 'BEGIN CERTIFICATE'
# 客户端视角验证:证书是否被系统信任
curl -vI https://example.com 2>&1 | grep -E 'SSL connection|subject|issuer'握手阶段对照
| 阶段 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 第一往返 | ClientHello / ServerHello 明文 | ClientHello 带 key_share,ServerHello 后即加密 |
| 证书与密钥交换 | Certificate、ServerKeyExchange 明文传输 | 证书与 CertificateVerify 在加密信道内发送 |
| 会话密钥 | 由 PreMasterSecret 经 PRF 派生 | 由 HKDF 分层派生 Handshake/Master Secret |
| 完成确认 | ChangeCipherSpec + Finished | Finished,同时保留伪 ChangeCipherSpec 兼容中间盒 |
| 恢复方式 | Session ID 或会话票据 | PSK 与会话票据,可选 0-RTT |
「TLS」与「SSL」常被混称,但 SSL 2.0/3.0 早已废弃,服务端应只启用 TLS 1.2 及以上。看到别人说 SSL 证书,指的其实就是 TLS 使用的 X.509 证书,配置项名仍沿用 ssl_ 前缀。
只配置了证书并不等于启用了 TLS 1.3:版本与套件都要显式配置并验证。若服务端仍允许 TLS 1.0/1.1、CBC 套件或静态 RSA 密钥传输,扫描工具会判为中高风险,且前向保密缺失。
排障排查顺序
- 先看连通性:端口是否可达、是否有防火墙或安全组拦截,客户端是否收到 ServerHello
- 再看证书链:中间证书是否随叶证书下发,顺序是否正确,是否命中默认站点证书
- 然后看版本与套件交集:客户端支持与排除项是否与服务端匹配
- 接着看域名与 SNI:用 IP 直连或未带 SNI 会拿到默认站点证书
- 最后看时间与吊销:证书是否过期、系统时间是否准确、OCSP/CRL 是否可达
证书校验失败分三类原因:链不完整、域名不匹配、有效期不符。三者的报错文案与验证码不同(如 error 20、error 62、error 10),先按错误码归类再排查,能省掉大量试错。
常见校验错误对照
| 报错 | 根因 | 处置方式 |
|---|---|---|
| error 20 / unable to get local issuer | 服务端未下发中间证书或链顺序颠倒 | 拼接完整链后用 -showcerts 确认实际下发内容 |
| error 62 / hostname mismatch | 证书 SAN 里没有客户端访问的域名 | 补签 SAN 或改用包含的域名访问,测试时务必带 SNI |
| error 10 / certificate has expired | 证书过期,或客户端系统时间偏移 | 续签证书并校准 NTP 时间 |
| error 18 / self signed certificate | 自签证书不在客户端信任库中 | 把企业 CA 导入信任库,或改用受信任 CA 签发 |
| no protocols available | 两端支持的版本没有交集 | 核对并放宽服务端版本配置,同时确认中间设备未拦截 |