SSL:curl 有效,httpie 失败

SSL:curl 有效,httpie 失败

我正在运行Ubuntu 16.04.4 LTS。我有以下版本:

root@e816b85d954d:/# http --debug
HTTPie 0.9.9
Requests 2.9.1
Pygments 2.1
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609]
/usr/bin/python
Linux 4.4.0-116-generic

root@e816b85d954d:/# curl --version
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets 

curl工作正常:

$ curl https://mysite

httpie失败了:

root@e816b85d954d:/# http https://mysite

http: error: SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590) while doing GET request to URL: https://mysite

为什么会这样呢?

答案1

错误消息非常直观。它告诉您 Web 服务器包含的 SSL 证书存在一些问题(很可能是因为它是自签名的、已过期等)。

您应该可以使用以下选项停止检查证书有效性--verify

--验证 验证

设置为“yes”以检查主机的 SSL 证书。您还可以将路径传递给 CA_BUNDLE 文件以获取私有证书。您还可以设置 REQUESTS_CA_BUNDLE 环境变量。

所以,设置--verify no就足够了。

# http --verify no https://...
/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py:794: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
[...]

不过,最好始终建议使用有效的 SSL 证书。

答案2

迟做总比不做好 :) 为了子孙后代:

我刚刚遇到(并解决了)类似的问题。就我而言,我没有使用自签名证书,但我想你也没有。

在密码学和计算机安全中,自签名证书是一种安全证书未经证书颁发机构签名 (加拿大)

来源:https://en.wikipedia.org/wiki/Self-signed_certificate

我认为你的意思是通过私人 CA 签名,任何公共操作系统都不会尊重它。

就我而言,问题是服务器仅返回中级证书而不是完整链(未包含 RootCA),而使用相同认证但包含 rootCA 的其他服务器都curl httpie运行良好。

我的问题是这样的:

设为my.private.api.net仅返回的主机域证书 my_api.pem签署人中级证书 SubCA.pem而后者又由 签署RootCA.pem

我正在使用“原始” ubuntu,我的意思是没有对 CA_BUNDLE 等进行任何操作。

我同时拥有SubCA.pemRootCA.pem文件,但无法按预期对 RootCA 进行验证,这是我使用 SubCA.pem 时遇到的情况

~> curl https://my.private.api.net --cacert SubCA.pem
OK.

 ~> http https://my.private.api.net --verify SubCA.pem

http: error: SSLError: HTTPSConnectionPool(host='my.private.api.net', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate
verify failed')])"))) while doing a GET request to URL: https://my.private.api.net/

所以这看起来确实像是 op 的情况。

正如我之前提到的,如果管理员更改服务器设置(在握手期间返回所有证书),它将解决问题。

不过,我找到了一种无需他帮助就能解决这个问题的方法。验证任何证书都行不通,但验证两个都将要!

我们需要的是所谓的“捆绑”证书,它只是一个将两个证书堆叠在一起的文件,因此我们创建一个新文件,将其命名Bundled.pem为如下所示:

-----BEGIN CERTIFICATE-----
<<content from SubCA.pem>>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<<content from RootCA.pem>>
-----END CERTIFICATE-----

顺序很重要!

现在httpie工作正常。

~> http https://my.private.api.net --verify Bundled.pem
HTTP/1.1 200 See Other
...

OK.

curl 也一样:

~> curl https://my.private.api.net --cacert Bundled.pem
OK.

相关内容