系统:Ubuntu 14.04,apt-upgrade
d到最新。 openssl、ca 证书、wget 安装
症状:
wget https://api.xxx.io
会导致这个错误:
ERROR: cannot verify api.xxx.io's certificate, issued by '/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2':
Unable to locally verify the issuer's authority.
To connect to api.xxx.io insecurely, use `--no-check-certificate'.
哪里wget https://google.com
工作正常。
openssl s_client -connect api.xxx.io:443
结果是这样的:
CONNECTED(00000003)
depth=3 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
我尝试重新安装 godaddy 的根证书:
- 下载他们的 ca cert crt 包到
/usr/share/ca-certificates/extra
- 运行
dpkg-reconfigure ca-certificates
并按照提示进行操作。
没有运气。
也尝试过c_rehash
但没有运气。
该站点已在 ubuntu 16 系统上成功验证。还有什么我应该尝试的吗?
编辑:运行strace -e open openssl s_client -connect api.xxx.io:443
表明它甚至没有打开 ca-certificates.crt:
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libssl.so.1.0.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libcrypto.so.1.0.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
open("/proc/meminfo", O_RDONLY|O_CLOEXEC) = 3
open("/dev/urandom", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
编辑2:如果我将CApath传递给openssl,它就可以工作。
openssl s_client -connect api.xxx.io:443 -showcerts -CApath /etc/ssl/certs
我尝试编辑 openssl.cnf 并使用环境变量覆盖,否则它仍然无法工作。
edit3:使用单个主机而不是具有 2 个不同证书的 2 个不同主机更新了问题。
答案1
正如编辑你的问题的大部分可能是交叉重复https://superuser.com/questions/903247/ssl-root-ca-certificate-is-not-recognized-although-present-in-the-trust-store和https://serverfault.com/questions/607233/how-to-make-openssl-s-client-using-default-c。
我还没有确认 Ubuntu 来源,但 Ubuntu 14.04 名义上使用 OpenSSL 1.0.1f,上游有一个错误,导致s_client
(和其他一些)在不指定任何-CA{path,file}
选项时不使用默认信任库,而 16.04 使用 1.0.2g这已经解决了。 (显然 16.10 也是如此,但这不是 LTS,并且不再受支持。)
配置文件无关紧要;s_client
不使用除“library-global”之外的任何配置文件设置用于 ENGINE 和 addedOID,这两者都与此问题无关。
但请注意www.tcell.io
(您wget
被重定向的位置)和api.tcell.io
(您告诉openssl s_client
连接的位置)是不同的机器。根据 www.ssllabs.com/ssltest:
api.tcell.io
52.8.231.1 正确提供具有必要链证书的 GoDaddy-SecureG2 证书(序列号 00c8c641d43c76286c)(确切地说,#2 和 #3 是必需的;#4 是根,不是必需的,但可以接受)www.tcell.io
13.57.73.170 提供相同的证书,但不提供链证书,这违反了 RFC(这会降低其等级,但它还使用 DH-1024,该 DH-1024 已将其上限限制为 B)。如果没有链证书,wget
则无法验证证书。如果您安装的“捆绑包”将链证书添加到您的信任库中(这不是 web-PKI 的预期操作方式),则wget
使用 OpenSSL是能够构建链并验证它。