排查 https 443 端口握手问题需分层验证:先用 ss/lsof 确认服务监听 0.0.0.0:443;再用 nc/telnet 测试 tcp 连通性;接着用 openssl s_client 检查 tls 握手、证书链完整性及协议兼容性;最后核查 nginx/openresty 的证书路径、权限、ssl_protocols 配置及 error.log 错误关键词。

排查 HTTPS 的 443 端口握手问题,关键不是只看“端口通不通”,而是分层验证:从 TCP 连通性 → TLS 握手能力 → 证书与协议兼容性。跳过任一层,都可能看到 curl: (35) Encountered end of file、ERR_SSL_VERSION_OR_CIPHER_MISMATCH 或浏览器白屏等现象。
一、确认服务是否真正在监听 443(TCP 层)
先排除最基础的绑定失败:
- 运行
sudo ss -tlnp | grep ':443'或sudo lsof -iTCP:443 -sTCP:LISTEN -P -n - 检查输出中监听地址是否为
0.0.0.0:443(对外)或[::]:443(IPv6),而非仅127.0.0.1:443(本机回环) - 若用 Docker/K8s,确认容器内进程监听的是 443(不是 8443),且宿主机端口映射正确:
-p 443:443 - 注意:普通用户无法直接 bind 443,需 root 权限或配置
setcap 'cap_net_bind_service=+ep' /path/to/binary
二、测试 TCP 连通性(网络路径层)
确保三次握手能完成,排除防火墙、安全组、NAT 或中间设备拦截:
- 从客户端执行:
nc -vz your-domain.com 443或telnet your-domain.com 443 - 成功应显示
succeeded或Connected to...;失败则提示Connection refused(服务未监听)或超时(被拦截) - 在服务器本地也试一次:
nc -vz 127.0.0.1 443,区分是服务问题还是网络策略问题
三、验证 TLS 握手与证书链(SSL/TLS 层)
这是 HTTPS 握手失败最常发生的环节:
- 用 OpenSSL 模拟客户端发起完整 TLS 握手:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts - 观察返回:是否有
Verify return code: 0 (ok)?若为非 0(如 21 表示无法验证 CA),说明证书链不全或根证书缺失 - 检查是否返回完整的证书链(尤其是中间证书)。很多服务只配了站点证书,漏掉中间证书,会导致 iOS、旧 Android 或 Java 客户端握手失败
- 加
-tls1_2或-tls1_3可单独测试某协议版本,快速定位是否因禁用旧协议导致兼容性问题
四、检查服务配置与权限(OpenResty/Nginx 常见雷区)
尤其当使用反向代理时,配置细节极易引发静默失败:
- 确认
ssl_certificate和ssl_certificate_key是绝对路径,且 Nginx worker 进程用户(如www-data)有读取权限 - 私钥不能加密(即不能含
DEK-Info行),否则日志报pem_read_bio_x509_aux() failed - 检查
ssl_protocols是否过度收紧(例如只留 TLSv1.3),导致老浏览器/客户端无法协商 - 查看 Nginx/OpenResty 的
error.log,搜索ssl_do_handshake、no suitable signature algorithm、permission denied等关键词
不复杂但容易忽略:很多问题其实卡在证书链、SELinux 策略(如 http_port_t 类型未赋给 443)、或容器里没开 UDP 443(HTTP/3 启用时需要)。











