设置了sni访问域名下的IP出现403或请求错误curl: (35) error:0A000410:SSL routines::sslv3 alert handshake failure。
curl --connect-to djicdn.com::36.150.42.236:443 -k -v -H 'Host: djicdn.com' https://djicdn.com
* Connecting to hostname: 36.150.42.236
* Connecting to port: 443
* Trying 36.150.42.236:443...
* Connected to (nil) (36.150.42.236) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Unknown (21):
* TLSv1.3 (IN), TLS alert, handshake failure (552):
* error:0A000410:SSL routines::sslv3 alert handshake failure
* Closing connection 0
curl: (35) error:0A000410:SSL routines::sslv3 alert handshake failure
查看openssl版本:
使用如下命令:
openssl version
或者
openssl version -a
从错误信息 sslv3 alert handshake failure
看,这是 SSL/TLS 握手失败的问题。以下是逐步排查和解决方法:
1. 强制使用 TLS 1.2 协议
服务器可能不支持 TLS 1.3 或存在兼容性问题。尝试强制使用 TLS 1.2:
curl --connect-to djicdn.com::36.150.42.236:443 -k -v -H 'Host: djicdn.com' --tlsv1.2 https://djicdn.com
--tlsv1.2
指定使用 TLS 1.2 协议(更广泛兼容)。
2. 检查服务器支持的协议和加密套件
用 openssl
测试服务器支持的协议:
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -tls1_2
- 如果成功,会显示证书和会话信息;失败则会有错误提示。
- 替换
-tls1_2
为-tls1_3
测试 TLS 1.3。
3. 验证 SNI(Server Name Indication)配置
确保 SNI 正确传递(已通过 -servername
或 URL 主机名隐式设置):
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com
- 若缺少
-servername djicdn.com
,某些服务器可能拒绝连接。
4. 检查防火墙或网络策略
- 本地防火墙:临时关闭防火墙(测试用):
sudo ufw disable # Ubuntu
- 公司网络/ISP:可能拦截非标准端口或 HTTPS 流量。
- 服务器防火墙:确保
36.150.42.236:443
允许外部访问。
5. 服务器端问题排查
- 证书有效性:检查证书是否过期或域名不匹配:
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com | openssl x509 -noout -dates -subject
- 服务器配置:服务器可能禁用了某些协议(如 TLS 1.3)或使用了不兼容的加密套件。
6. 其他尝试
- 更新工具和库:升级
curl
和 OpenSSL 到最新版本:sudo apt update && sudo apt upgrade curl openssl # Debian/Ubuntu
- 调试模式:使用
-v
已开启,关注握手阶段的详细错误。
从您的测试结果来看,使用 OpenSSL 连接时也遇到了相同的 “sslv3 alert handshake failure” 错误。这表明问题不在于 curl
本身,而是客户端与服务器之间的 TLS 协议协商失败。以下是关键分析和解决方案:
问题根本原因
-
协议/加密套件不兼容(最常见):
- 服务器可能只支持较旧的 TLS 版本(如 TLS 1.0/1.1)或特定的加密套件
- 您的客户端(OpenSSL/curl)默认配置可能禁用了服务器要求的协议或套件
-
服务器端配置问题:
- 服务器证书链不完整或配置错误
- 服务器防火墙或安全组拦截了特定类型的 TLS 握手
解决方案
1. 强制使用旧版 TLS 协议
测试不同 TLS 版本,找到服务器支持的版本:
# 测试 TLS 1.2
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -tls1_2
# 测试 TLS 1.1
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -tls1_1
# 测试 TLS 1.0
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -tls1
2. 指定兼容性更好的加密套件
尝试广泛支持的套件组合:
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -cipher 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256'
3. 检查服务器证书链完整性
手动验证证书链:
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -showcerts
检查输出中是否包含完整的证书链(至少2-3张证书)。如果只有1张证书,说明服务器配置有误。
4. 使用网络诊断工具
通过第三方工具验证服务器状态:
# 使用 testssl.sh 全面诊断
git clone https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh 36.150.42.236:443
5. 临时降低客户端安全级别(仅测试)
# 在 OpenSSL 配置中临时允许不安全算法
openssl s_client -connect 36.150.42.236:443 -servername djicdn.com -no_tls1_3 -no_tls1_2 -cipher 'ALL:@SECLEVEL=0'
6. 确认 IP 有效性
检查该 IP 是否为官方 CDN 节点:
nslookup djicdn.com
# 对比返回的 IP 列表是否包含 36.150.42.236
升级openssl
升级过程
下载:wget https://www.openssl.org/source/openssl-3.1.1.tar.gz,我下载到了/opt目录下
解压:tar -xzvf openssl-3.1.1.tar.gz
进入解压后目录:cd openssl-3.1.1
配置安装目录:./config --prefix=/usr/local/openssl311
编译安装:make && make install
本地查看是否成功:/usr/local/openssl311/bin/openssl version -a
出现问题,解决后可正常显示新版本,或无问题,继续下一步
软链接:进入/usr/bin目录,查询openssl的软链接,如果指定的是旧版本,使用unlink /usr/bin/openssl命令取消软链接
创建新软链接:ln -s /usr/local/openssl311/bin/openssl /usr/bin/openssl
刷新命令库:ldconfig
在任一目录直接验证:openssl version -a,可查看到新版本