相关文章推荐
长情的台灯  ·  年假小 Plan - ZhuGaochao ...·  1 周前    · 
小眼睛的米饭  ·  dotnet WinUI 3 ...·  4 天前    · 
任性的香瓜  ·  react-infinite-scroll- ...·  3 天前    · 
任性的海龟  ·  android ...·  1 年前    · 

CURL HTTPS 返回 ERRNO 35(SSL CONNECT ERROR) 错误

微信支付获取 prepay id 偶尔失败问题总结。
微信支付会要求先从微信服务器获取 prepay id (https://api.mch.weixin.qq.com/pay/unifiedorder)。我们开发完成后(语言是PHP,使用微信的支付SDK,请求时使用curl),在测试环境的机器上,基本没有发现请求失败的情况,上线后,却发现经常出现错误,概率1/5甚至更高。开始没有深究原因,采用重试的方式,不过发现,只要失败了,重试也会失败。

记录下 curl 的错误是:errno:35, error: SSL Connect Error。

网上查相关资料,没有找到解决方案。联系微信技术支持,他们没有任何建议,觉得是我们的问题,让我们自己查。

在我们服务器上通过 tcpdump 抓包:tcpdump -i eth1 ip host 140.207.69.102 -w wxpay.cap,对比成功和失败的包(使用wireshark分析):

成功的数据包:
在这里插入图片描述
失败的数据包:
在这里插入图片描述
可以看到,失败的时候,TCP 3次握手后马上进行4次挥手操作 没有任何内容交互,而且 close 是客户端(我们这边)发起的。

推论:与remote服务端应该无关,还没开始https内容部分的交换,应该是本地在进行某些工作的时候发现异常,close了连接(但程序如果让我写会考虑先本地工作结束后再connect,不清楚为什么先connect然后再获取本地资源)。

可以通过 strace curl -X POST https://api.mch.weixin.qq.com/pay/unifiedorder 查看整个系统调用过程,是先 connect,然后从 系统本地etc目录下加载一些CA相关文件。

也可以通过 curl -v -X POST https://api.mch.weixin.qq.com/pay/unifiedorder 查看相关信息。对于 PHP 中,可以设置:curl_setopt($ch, CURLOPT_VERBOSE, true)。

失败时是类似这样的输出:

  • About to connect() to api.mch.weixin.qq.com port 443 (#0)
  • Trying 140.207.69.102… connected
  • Connected to api.mch.weixin.qq.com (140.207.69.102) port 443 (#0)
  • Initializing NSS with certpath: sql:/etc/pki/nssdb
  • CAfile: /etc/pki/tls/certs/ca-bundle.crt
    CApath: none
  • NSS error -5990
  • Closing connection #0
  • SSL connect error
    curl: (35) SSL connect error

成功时输出如下(省略了response):

  • About to connect() to api.mch.weixin.qq.com port 443 (#0)
  • Trying 140.207.69.102… connected
  • Connected to api.mch.weixin.qq.com (140.207.69.102) port 443 (#0)
  • Initializing NSS with certpath: sql:/etc/pki/nssdb
  • CAfile: /etc/pki/tls/certs/ca-bundle.crt
    CApath: none
  • NSS: client certificate not found (nickname not specified)
  • SSL connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA
  • Server certificate:
  • subject: CN=payapp.weixin.qq.com,OU=R&D,O=Tencent Technology (Shenzhen) Company Limited,L=shenzhen,ST=guangdong,C=CN
  • start date: 4月 28 00:00:00 2015 GMT
  • expire date: 4月 27 23:59:59 2016 GMT
  • common name: payapp.weixin.qq.com
  • issuer: CN=GeoTrust SSL CA – G2,O=GeoTrust Inc.,C=US

POST /pay/unifiedorder HTTP/1.1
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host: api.mch.weixin.qq.com
Accept: /

在网上找到了一个帖子: http://serverfault.com/questions/606135/curl-35-ssl-connect-error, 问题和我们遇到的一样,虽然操作系统版本和NSS版本不一样。按上面的提示,升级 nss(Mozilla Network Security Services 网络安全服务):yum update nss, 然后重启 php,问题解决。

总结:
1、从现象:有些机器有问题,有些没有问题;有些概率大,有些概率小;可大体上推断,跟机器有关系,可能机器环境不一样导致的;
2、抓包分析原因,进一步确认不是服务端(微信支付)的问题;
3、根据错误描述在网络上寻求帮助;
4、学习 curl 相关选项的使用;strace 的使用;

转载自:http://blog.studygolang.com/2015/10/curl-35-ssl-connect-error/

CURL HTTPS 返回 ERRNO 35(SSL CONNECT ERROR) 错误微信支付获取 prepay id 偶尔失败问题总结。微信支付会要求先从微信服务器获取 prepay id (https://api.mch.weixin.qq.com/pay/unifiedorder)。我们开发完成后(语言是PHP,使用微信的支付SDK,请求时使用curl),在测试环境的机器上,基本没有发...
症状:php curl 调用 https 出错 排查方法:在命令行中使用 curl 调用试试。 原因:服务器所在机房无法验证 SSL 证书。 解决办法:跳过 SSL 证书检查。 curl _setopt($ch, CURL OPT_ SSL _VERIFYPEER, false); 症状:php curl 调用 curl _exec 返回 bool(false),命令行 curl 调用正常。 排查方法: var_dump( curl _ error ($ch)); 返回 : string(23) “Empty reply from server” 再排查: curl _setopt($ch, CURL OPT_HEADER, true); cur
由于业务需要,需要增加一台web服务器,配置好web环境后,研发测试发现 curl https 报错: curl : ( 35 ) SSL connect error ; 看了下线上在跑的服务器的 curl 版本:新增的在台 curl 版本:对比发现,新增这台服务器 curl 默认支持 https 是nss,而不是open ssl ,需要换成open ssl .源码编译 curl cd /usr/local/src/ wge...
name=CentOS-6.10 - Base - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos-vault/6.10/os/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-6 #released updates 都是连的自家的服务器,就直接把 curl SSL 选项,设置为不检查了,代码如下: curl _easy_setopt( curl , CURL OPT_ SSL _OPTIONS, CURL SSL OPT_ALLOW_BEAST | CURL SSL OPT_NO_REVOKE);
curl : ( 35 ) libre ssl ssl _ connect : ssl _ error _syscall in connect ion to raw.githubusercontent.com:443