这个坑值得记一笔。CentOS 7.9 的 nginx 1.20,fullchain.pem 是手工把站点证书、根证书、中间证书按这个顺序拼的,浏览器访问正常,Android 7 打开报证书链不完整,openssl s_client 只看到 leaf 和 root。
刚开始盯着「服务端只发了 leaf,没有携带中间证书」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。fullchain 必须 leaf 在前、中间证书在后,根证书不该放进去;拼接时把根证书放到了中间证书前面,客户端提前终止链;证书来自不同 CA,中间证书和 leaf 不是同一条链。
动手时先看服务端实际发出的证书链
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
然后确认每个证书的 subject 和 issuer
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
再往下按 leaf 加中间证书的顺序重新拼
cat server.crt intermediate.crt > fullchain.pem
剩下的就是重新加载后再验一次链
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
改完先别撤,确认这几项。openssl s_client 输出里能看到 leaf 和中间证书两级,Android 7 和旧版 curl 都能正常握手。
根证书不要放进 fullchain,客户端本来就有;链的完整性靠中间证书,缺一张就会在部分设备上翻车。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
