Nginx在phpEnv中启用TLS 1.2/1.3需先用nginx -V | grep OpenSSL确认运行时OpenSSL≥1.1.1,再配置ssl_protocols TLSv1.2 TLSv1.3并分段设置ssl_ciphers(ECDHE套件与TLS13-前缀套件用冒号隔开),同时设ssl_prefer_server_ciphers off且监听行必须含http2。

phpEnv 默认不启用 TLS 1.2/1.3,必须手动修改 Nginx 配置并验证 OpenSSL 运行时版本——否则即使写了 TLSv1.3,Nginx 启动也不报错,但实际握手永远 fallback 到 TLS 1.2 或更低。
确认 phpEnv 中 Nginx 真实使用的 OpenSSL 版本
phpEnv 是集成环境,它打包的 Nginx 往往静态链接了自建 OpenSSL,openssl version 命令显示的不是它用的版本。必须用:
nginx -V 2>&1 | grep -o 'built with OpenSSL [^ ]*'
输出类似 built with OpenSSL 1.0.2k 就说明 TLS 1.3 不可用;只有 OpenSSL 1.1.1 及以上才支持。常见坑:
- phpEnv 官方 Windows 版(如 2.4.x)多数仍捆绑 OpenSSL 1.0.2u,无法启用 TLS 1.3
- Linux 下若用 apt/yum 安装的系统 nginx,可能被 phpEnv 的启动脚本绕过,实际运行的是系统版,需检查
which nginx和ps aux | grep nginx - Mac 上通过 Homebrew 安装的 phpEnv 变体,常因 OpenSSL 路径混乱导致编译时用新版、运行时加载旧 dylib
在 phpEnv 的 Nginx 配置中安全启用 TLS 1.2 和 1.3 共存
不要直接删掉 TLSv1.2——微信小程序、部分安卓 WebView、老版企业内网客户端仍依赖它。共存配置的关键是隔离 cipher 控制:
立即学习“PHP免费学习笔记(深入)”;
-
ssl_protocols TLSv1.2 TLSv1.3;—— 必须显式列出,不能写TLSv1.2+或漏掉空格 -
ssl_ciphers要分两段写:TLS 1.2 用传统 ECDHE 套件,TLS 1.3 用专用前缀套件,中间用冒号隔开:ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256; - 务必设
ssl_prefer_server_ciphers off;,否则 TLS 1.2 下可能强制弱协商,且该指令对 TLS 1.3 无影响
phpEnv 中 HTTP/2 与 TLS 版本的隐性冲突
phpEnv 的默认 Nginx 配置常漏掉 http2 关键字,或只在 listen 443 ssl; 里写,导致 HTTP/2 实际未启用。正确写法必须是:
listen 443 ssl http2;<br>listen [::]:443 ssl http2;
但注意:如果底层 OpenSSL http2,ALPN 协商也会失败,浏览器降级到 HTTP/1.1。验证方式不是看响应头,而是用:
curl -I --http2 https://localhost
返回 HTTP/2 200 才算真正生效。常见错误:
- Windows 上 phpEnv 启动的 Nginx 绑定在 127.0.0.1,但
curl默认走 IPv6,导致连接超时,应加--ipv4 - 证书为自签名时,
curl需加-k,否则拒绝建立 TLS 连接,更别说协商 HTTP/2
phpEnv 下容易被忽略的兼容性断点
phpEnv 多用于本地开发和测试,但一旦部署到客户现场,以下三点常引发连接失败,且日志里几乎不报错:
- Android 4.4(WebView 内核基于 OpenSSL 1.0.1m)不支持 TLS 1.3,但若你只配了
TLSv1.3,它会直接拒绝握手,表现为白屏或 ERR_SSL_VERSION_OR_CIPHER_MISMATCH - IE11 on Windows 7 默认不支持 SNI,而 phpEnv 的多站点配置常依赖 SNI 区分域名,结果只有一个站点能走 HTTPS
-
ssl_dhparam缺失时,TLS 1.2 的 DHE 套件无法使用,但 ECDHE 仍可工作;而 TLS 1.3 强制使用 ECDHE,所以看似正常,实则丧失前向保密能力——这点在 phpEnv 的一键生成证书流程里基本被跳过



















