使用cURL调用API时出现wrong version number错误的排查解决咨询
解决Docker环境中curl调用OpenShift自签名HTTPS API的TLS版本错误问题
环境与问题概况
本地环境
- OpenSSL 1.1.1n (15 Mar 2022)
- curl 7.74.0
目标API信息
- 部署于OpenShift的内网HTTPS服务,自签名证书
- 支持TLS v1.3、TLS v1.2协议
- 调用需绕过代理
问题现象
执行curl命令(参数--data '' --verbose --insecure)时触发错误:
Note: Unnecessary use of -X or --request, POST is already inferred. * Trying xx.xx.xx.xx:443... * Connected to servername (xx.xx.xx.xx) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt * CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * error:1408F10B:SSL routines:ssl3_get_record:wrong version number * Closing connection 0 curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
已确认的正常场景
- Postman直接调用API正常响应
- IIS环境运行Postman生成的C# RestSharp/PowerShell RestMethod代码可成功调用
- 调用其他内网服务器的API无异常
- OpenShift集群内的另一个Docker容器可正常调用该API
Docker环境验证项
- 可ping通目标服务器
- 主机名可正常解析为对应IP
排查与解决思路
强制指定TLS版本进行握手
尽管API声明支持TLS1.3/1.2,但curl默认的版本协商逻辑可能出现异常,尝试强制指定TLS版本:- 强制使用TLS1.2:
curl --data '' --verbose --insecure --tlsv1.2 https://servername/your-api-path --noproxy * - 强制使用TLS1.3:
curl --data '' --verbose --insecure --tlsv1.3 https://servername/your-api-path --noproxy *
注:
--noproxy *确保完全绕过代理,避免代理干扰TLS握手流程。- 强制使用TLS1.2:
清理容器内代理环境变量残留
Docker容器可能存在HTTP_PROXY/HTTPS_PROXY环境变量残留,导致curl间接走代理。执行以下命令检查并清除:echo $HTTP_PROXY $HTTPS_PROXY unset HTTP_PROXY HTTPS_PROXY NO_PROXY清除后重新执行curl命令测试。
强制curl使用HTTP/1.1协议
报错日志显示curl提供了h2(HTTP/2)协商,若API对HTTP/2支持存在兼容性问题,可强制使用HTTP/1.1:curl --data '' --verbose --insecure --http1.1 https://servername/your-api-path --noproxy *手动指定自签名证书路径
即使使用--insecure跳过验证,容器内CA证书存储可能存在异常,尝试直接指定API的自签名证书:curl --data '' --verbose --cacert /path/to/your-selfsigned-cert.pem https://servername/your-api-path --noproxy *对比正常容器的配置差异
参考OpenShift集群内可正常调用的Docker容器,对比以下配置项:- curl编译参数(即使版本相同,编译选项可能不同)
- OpenSSL配置文件(
/etc/ssl/openssl.cnf) - 容器环境变量
可尝试将正常容器的openssl.cnf复制到当前容器测试。
用openssl s_client测试TLS握手细节
使用openssl s_client工具直接测试TLS握手,获取更详细的交互日志:openssl s_client -connect servername:443 -tls1_2 openssl s_client -connect servername:443 -tls1_3通过输出信息确认握手过程中是否存在异常中断或协议不匹配问题。
内容的提问来源于stack exchange,提问作者Moni
相关产品推荐
相关产品推荐

