网关做 TLS 终止要把证书链配成什么样?RSA 和 ECDSA 的握手差多少?会话复用有多大帮助?到上游是明文还是重新加密,代价和安全性怎么样?这篇用自己签的证书链和 nginx 1.31.6 量出来。
ssl_certificate | client(只信根 CA)的结果 | nginx 发出的证书数 ----------------------+---------------------------------------------+------------- 只有叶子证书 | 校验失败:unable to get local issuer certificate | 1 张 叶子 + 中间 CA(fullchain) | 握手成功,校验通过 | 2 张 叶子证书不是根 CA 直接签的,client 需要中间 CA 才能一路验证到自己信任的根;服务端不发中间证书,有的 client 会自己去下载(AIA),这里的 Python 不会,所以失败。根 CA 一般不需要发,client 本来就有
叶子证书之外要把中间 CA 一起发出去,client 才能验证到根。
叶子证书 | 服务端允许的版本 | 实际协商 | 握手耗时中位数(TCP + TLS) | p99 --------+----------+---------+--------------------+-------- ec256 | TLSv1.2 | TLSv1.2 | 0.78 ms | 2.19 ms ec256 | TLSv1.3 | TLSv1.3 | 0.88 ms | 1.52 ms rsa2048 | TLSv1.2 | TLSv1.2 | 1.23 ms | 2.54 ms rsa2048 | TLSv1.3 | TLSv1.3 | 1.36 ms | 2.76 ms rsa4096 | TLSv1.2 | TLSv1.2 | 4.25 ms | 6.68 ms rsa4096 | TLSv1.3 | TLSv1.3 | 4.14 ms | 7.42 ms 配置(TLS 1.3 默认,RSA 2048) | 带着上次的会话重连,被复用的次数 | 复用的握手中位数 | 没复用的握手中位数 ---------------------------------+------------------+----------+---------- 无会话缓存(ssl_session_cache off) | 0 / 100 | - | 1.35 ms shared 会话缓存 + session tickets 默认 | 100 / 100 | 0.68 ms | -
密钥类型的影响大于 TLS 版本;会话复用把握手耗时降一半。
到上游的方式 | 延迟中位数 | p99 | 状态码
--------------------------------------------------+---------+---------+-----------
proxy_pass http://(明文) | 0.15 ms | 0.48 ms | {200: 500}
proxy_pass https://,默认 | 0.15 ms | 0.47 ms | {200: 500}
https:// + Connection: close(每个请求新建 TLS 连接) | 1.53 ms | 2.93 ms | {200: 500}
https:// + Connection: close + 会话复用 | 0.74 ms | 1.75 ms | {200: 500}
proxy_pass http:// + Connection: close(明文也每次新建连接) | 0.27 ms | 0.66 ms | {200: 500}
proxy_pass https:// + upstream keepalive 16 | 0.15 ms | 0.46 ms | {200: 500}
https:// + proxy_ssl_verify on(信任根 CA) | 0.15 ms | 0.47 ms | {200: 500}
上游证书的校验:默认的 proxy_ssl_verify 是 off,nginx 不检查上游证书是否可信、名字是否对得上;下面让上游用一张叶子证书(没有发中间 CA),分别在 verify off / on 下请求
配置 | 状态码 | error.log
-------------------------+-----+-----------------------------------------------------------------------------------------------------------------------------------
proxy_ssl_verify off(默认) | 200 | (没有错误)
proxy_ssl_verify on | 502 | 296#0: *2 upstream SSL certificate verify error: (21:unable to verify the first certificate) while SSL handshaking to upstream, cl连接被复用时几乎没有额外延迟,新建连接时每次多一次握手;默认不校验上游证书,重新加密不等于认证。