我们curl无法连接到 HTTPS 服务器时遇到问题:
$ curl https://the-problem-site.com (not the real URL!)
curl: (35) error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)
Run Code Online (Sandbox Code Playgroud)
1112SSL_R_TLSV1_UNRECOGNIZED_NAME在ssl.h.
如果我openssl s_client -connect the-problem-site.com:443改为尝试,那么我会看到
CONNECTED(00000003)
depth=1 /C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
verify error:num=20:unable to get local issuer certificate
verify return:0
Certificate chain
0 s:/serialNumber=xx/C=xx/ST=xx/L=xxxx/O=xx/OU=xx/CN=the-problem-site.com
i:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
1 s:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Run Code Online (Sandbox Code Playgroud)
即看起来问题在于它不信任/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA. 但是,该证书已安装:它是/etc/ssl/certs/GeoTrust_Global_CA.pem,如果我运行
openssl s_client -connect the-problem-site.com:443 -CAfile /etc/ssl/certs/GeoTrust_Global_CA.pem
然后一切正常。证书也以哈希命名的文件形式存在b0f3e76e.0,它位于ca-certificates.crt. 但是,据我所知, curl 和 openssl 都没有尝试读取任何证书;如果我strace他们那么没有尝试读取/usr/lib/ssl/certs或/etc/ssl/certs根本没有,甚至没有错误。不过,它确实读取了 openssl.cnf。我们已经跑了update-ca-certificates。
这是带有 openssl 0.9.8k 的 Ubuntu 10.04。我们可以在两个单独的安装中重现这个问题(尽管一个可能是另一个的克隆)。如果我在带有 openssl 0.9.8e 的 CentOS VM 上尝试相同的测试,那么它工作正常,我可以看到它读取strace. 在 Ubuntu straces 的同一点上没有等效的文件访问。如果我将openssl.cnf文件从 CentOS 虚拟机复制到 Ubuntu 机器上,则没有任何区别。环境或 .rc 文件中没有任何明显的可能导致这种情况。
任何想法我做错了什么?这是否可行,即 openssl 和 curl 是否应该从命令行自动获取已安装的 CA?这是怎么配置的?谢谢!
另一个数据点:在全新安装的 13 服务器上,curl确实获取了证书文件并且工作正常。openssl s_client不过,仍然没有。为什么会这样?
您的系统上有几个加密库:
当然,它们都有相同点和不同点。使用它们的软件(用于加密目的,或使用 SSL/TLS)有时支持使用多个这些库(例如 Lynx,网络浏览器,通常与 OpenSSL 链接,但也支持 GnuTLS(只是不太好)为了安抚 GNU 人民)。
cURL 也是支持使用三个主要加密库之一的项目之一。这主要是因为 cURL 是一个主要的库,供其他程序使用 http、ftp 等连接下载(甚至上传)东西时使用。该curl命令行工具可以来自这些变种。
现在,我相当确定您在未全新安装的系统中看到的问题如下:
OpenSSL 和 GnuTLS 都支持使用/etc/ssl/certs/<hash>.<number>-style CA 目录。然而,OpenSSL 0.x 版和 GnuTLS 使用与 OpenSSL 1.x 版不同的算法来计算上述哈希。(两者都可以在系统上共存;如果不同的证书具有相同的哈希值,您只需为它们使用不同的数字。但出于某种原因,Debian/Ubuntu 的ca-certificates软件包似乎没有这样做。)此外,某些版本的 GnuTLS 没有支持使用目录,但只能使用文件/etc/ssl/certs/ca-certificates.crt(通常也由ca-certificates包的维护者脚本管理,但可以偏离);您似乎使用的是旧版本,所以这可能是您遇到的问题。
openssl s_client默认情况下(即没有-CApathor-CAfile选项)不会在任何地方寻找证书。
您curl从升级后的安装最有可能使用不同的密码库比curl从全新安装。
尝试openssl s_client -CAfile /etc/ssl/certs/ca-certificates.crt -connect the-problem-site.com:443除了openssl s_client -CApath /etc/ssl/certs -connect the-problem-site.com:443模仿年长的GnuTLS版本的行为。
仔细检查,如果有一个OpenSSL的1.x的任何地方你的系统(Ubuntu的是著名的潜入主要更新连入LTS版本),如果是,检查文件的哈希:
openssl x509 -noout -hash -in /etc/ssl/certs/GeoTrust_Global_CA.pem
openssl x509 -noout -subject_hash_old -in /etc/ssl/certs/GeoTrust_Global_CA.pem
openssl x509 -noout -subject_hash -in /etc/ssl/certs/GeoTrust_Global_CA.pem
Run Code Online (Sandbox Code Playgroud)
通常,第二个和第三个命令应该失败 (OpenSSL 0.x),或者第一个和第三个命令应该显示相同的哈希值,但第二个命令应该显示不同的哈希值 (OpenSSL 1.x)。GnuTLS 将使用第二个命令的输出(如果安装了 OpenSSL 1.x);如果安装了 OpenSSL 0.x,则是相同的哈希值。您可以手动创建此类符号链接。
一旦您提供调试反馈,我可以更新此帖子。
| 归档时间: |
|
| 查看次数: |
9334 次 |
| 最近记录: |