我使用Let's Encrypt 推荐使用这个 Makefile为 foo.localhost 创建了一个自签名证书:
include ../.env
configuration = csr.cnf
certificate = self-signed.crt
key = self-signed.key
.PHONY: all
all: $(certificate)
$(certificate): $(configuration)
openssl req -x509 -out $@ -keyout $(key) -newkey rsa:2048 -nodes -sha256 -subj '/CN=$(HOSTNAME)' -extensions EXT -config $(configuration)
$(configuration):
printf "[dn]\nCN=$(HOSTNAME)\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:$(HOSTNAME)\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth" > $@
.PHONY: clean
clean:
$(RM) $(configuration)
然后,我将其分配给 Web 服务器。我已验证服务器返回相关证书:
$ openssl s_client -showcerts -connect foo.localhost:8443 < /dev/null
CONNECTED(00000003)
depth=0 CN = foo.localhost
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = foo.localhost
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=foo.localhost
i:/CN=foo.localhost
-----BEGIN CERTIFICATE-----
[…]
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=foo.localhost
issuer=/CN=foo.localhost
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1330 bytes and written 269 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: […]
Session-ID-ctx:
Master-Key: […]
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket:
[…]
Start Time: 1529622990
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
Extended master secret: no
---
DONE
如何在不修改 /etc 中的任何内容的情况下让 cURL 信任它? --cacert
不起作用,大概是因为没有CA :
$ curl --cacert tls/foo.localhost.crt 'https://foo.localhost:8443/'
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
目标是在开发过程中启用 HTTPS:
- 如果没有在所有开发环境中启用 DNS 验证的大量工作,我就无法拥有完全类似于生产的证书。因此我必须使用自签名证书。
- 我显然仍然想让我的开发环境尽可能地类似于生产环境,所以我不能简单地忽略任何和所有证书问题。
curl -k
就像catch (Exception e) {}
在这种情况下一样 - 完全不像浏览器与 Web 服务器通信。
换句话说,当我跑步时,curl [something] https://project.local/api/foo
我想确信
- 如果 TLS 配置正确,除了具有自签名证书,该命令将成功并且
- 如果我的 TLS 配置有任何问题,除了拥有自签名证书,该命令将失败。
使用 HTTP 或--insecure
不符合第二个标准。
尝试
-k
:它应该“接受”自签名证书
遵循这些步骤应该可以解决您的问题:
echo quit | openssl s_client -showcerts -servername "${API_HOST}" -connect "${API_HOST}":443 > cacert.pem
curl
客户:curl --cacert cacert.pem --location --silent https://${API_HOST}
也可以使用 wget 并忽略以下证书:
wget --no-check-certificate https://${API_HOST}
我有这个问题,完全相同的问题和错误消息,但我使用 GNUTLS 的 certtool 来生成我的证书而不是 openssl。
我的问题是我没有将我的自签名证书设为 CA。它仅配置为充当 Web 服务器证书。这就是我想要用它做的所有事情,我不打算将它用作 CA 来签署其他证书。
但是当你想将一个证书作为其他证书的颁发者添加到信任链中时,该证书必须是 CA,否则会被 openssl 拒绝!
有了
certtool -i < mycert.crt
,人们需要看到这一点:尝试添加
-addext basicConstraints=critical,CA:TRUE,pathlen:1
到您的 openssl 命令或修改您的 cnf 文件以达到相同的效果。或者,使用 certtool,一次性生成证书要容易得多:
然后回答提示以提供证书的 CN 等。当被问及它是否适用于证书颁发机构时,说是的!
trustme
,由urllib3使用,看起来是个不错的选择。根据他们的自述文件:拥有包含自签名证书的信任链是无效的。如果是这样的话,任何人都可以提供(组成)有效的信任链。如果自签名证书出现在信任链中,则必须忽略它。自签名证书只能在本地目录(由计算机所有者控制)中有效。提供给任何服务器的证书必须链接到自签名证书。
没有大部分小细节的一般指南。
您的
openssl s_client
命令输出显示两个错误:这意味着您机器中的默认证书存储缺少一个验证您使用的网站给出的链的证书。您需要一个带有自签名证书的目录和一个链接到该 Web 服务器的证书。
脚步:
您可以构建一个新目录(在任何地方),使用
c_rehash
脚本处理它并告诉 openssl 使用它来验证带有选项的证书-CApath Directory
。-CApath
进行更改,直到您在使用该选项时消除这两个错误。为 Web 服务器生成链式证书。
然后,告诉 curl 证书目录:
以及所需的所有其他选项。
这将清除这两个错误。
using 提供的解决方案
trustme
完美运行,但如果有人有兴趣为学习目的创建证书,这些步骤对我有用:创建根 CA:
创建服务器私钥:
创建证书签名请求:
创建
localhost.ext
具有以下内容的文件:此文件具有证书的 DNS 配置。这很重要,因为如果 URL 中的名称与证书中的 DNS 不匹配,TLS 检查将不会通过。
使用之前创建的根 CA 签署服务器证书:
将
crt
文件转换为以下pem
格式:现在您应该可以在服务器中使用 the
localhost.pem
和 the了。localhost.key
客户端应该使用rootCA.pem
连接到服务器。就我而言,我必须使用
jks
文件。该pem
文件可以转换jks
为如下:可以使用以下命令查看密钥库中的条目:
localhost.jks
应该在服务器中使用,并且可以使用以下方法测试连接:参考:
如果您从服务器保存 self-signed.crt,您可以通过“--cacert self-signed.crt”将其传递给 curl,curl 将使用给定的 CA Cert 验证您的服务器的证书。