我正在运行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
迟做总比不做好 :) 为了子孙后代:
我刚刚遇到(并解决了)类似的问题。就我而言,我没有使用自签名证书,但我想你也没有。
在密码学和计算机安全中,自签名证书是一种安全证书未经证书颁发机构签名 (加拿大)
我认为你的意思是通过私人 CA 签名,任何公共操作系统都不会尊重它。
就我而言,问题是服务器仅返回中级证书而不是完整链(未包含 RootCA),而使用相同认证但包含 rootCA 的其他服务器都curl
httpie
运行良好。
我的问题是这样的:
设为my.private.api.net
仅返回的主机域证书 my_api.pem
签署人中级证书 SubCA.pem
而后者又由 签署RootCA.pem
。
我正在使用“原始” ubuntu,我的意思是没有对 CA_BUNDLE 等进行任何操作。
我同时拥有SubCA.pem
和RootCA.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.