您知道为什么在TLS中使用Let's Encrypt证书会导致客户端在SSL握手点失败并出现错误19(链中的自签名证书)吗?我正在开发一个使用Mosquitto库来打开连接的应用程序(并且在握手时失败)但是为了简化这个问题,我将使用mosquitto_sub命令(我们知道它可以工作)来演示问题。
我在我的网站上使用带有Let的加密证书的Centos 6.2没有任何问题(因为它们是免费的,自动的,并且是开放的)。我现在想使用Let's Encrypt发出的相同证书来保护我的服务器和任何远程客户端之间的TLS连接。实际上,在端口8881上,TLS用于连接Mosquitto MQTT代理。我服务器上的mosquitto.conf文件包含:
...
user mosquitto
listener 8883 example.com
cafile /etc/mosquitto/certs/chain-ca.pem # These 3 from Let's Encrypt
certfile /etc/mosquitto/certs/cert.pem
keyfile /etc/mosquitto/certs/privkey.pem
require_certificate false
...
我的CentOS服务器上有几个网络接口,我的域名“example.com”用dig命令解析为接口eth0:1的IP:
[root@spiff mosquitto]# dig example.com
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6_8.2 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 804
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 300 IN A 158.234.234.24
;; AUTHORITY SECTION:
example.com. 300 IN NS dns0.ns.co.uk.
example.com. 300 IN NS dns1.ns.co.uk.
;; Query time: 41 msec
;; SERVER: 151.236.220.5#535(11.226.220.5)
;; WHEN: Sun Oct 30 19:21:07 2016
;; MSG SIZE rcvd: 101
我认为这很重要,因为我用Let's Encrypt创建的'example.com'证书有一个CN,必须用DNS解析Mosquitto侦听器绑定的NIC的IP地址,否则从OpenSSL的角度来看,我向任何客户提供错误的证书。
服务器在启动时没有任何问题。
经过大量谷歌搜索后,我理解(可能是错误的)客户端需要作为参数传递给CA(证书颁发机构)的证书,该证书在连接到'example.com'时签署了'example.com'的证书服务器,因为它将检查用于签署example.com证书的CA是否可信,因此我们使用 - cafile [certificate-authority-cert.crt] 参数来传递此信息。我感谢这是特定于TLS连接的,并且Web客户端不使用此功能。
当client on the same Centos 6.2 server(可能是我的程序,但为了简化事情是开箱即用的 mosquitto_sub 命令)连接这些参数时,我看到这个错误:
mosquitto_sub -h example.com -p 8883 -t test -u mr-user -P P@55W0rD --cafile /etc/pki/tls/certs/lets-encrypt-x3-cross-signed.pem -d
Error: A TLS error occurred
因为Mosquitto代理对故障时errno的值不是很具体,所以我再次尝试使用openSSL的s_client功能:
[root@spiff certs]# openssl s_client -connect example.com:8883 -CAfile lets-encrypt-x3-cross-signed.pem
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/CN=www.example.com
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
2 s:/O=Digital Signature Trust Co./CN=DST Root CA X3
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgISA12o6mO9oS364BF5UVgSAD7TMA0GCSqGSIb3DQEBCwUA
[... lines removed for brevity ...]
A+q6hf00nJJsEvGmhVzQG5zAn6ojcWgT3EhurPien7Y16+kIS5tdz9xbeCgLTOrJ
BXA=
-----END CERTIFICATE-----
subject=/CN=www.example.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 3999 bytes and written 373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: E8D32590BAB26FF5811D39D775B3F455CAC3E8747866FA251DDA2032FA88E349
Session-ID-ctx:
Master-Key: 1B45DF54D11BC44D96AEAC940291B4D3BBAE56D6431E746873DC4F15DC1219F02019F4D903CAA6E8B23AF83CE291F4A6
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - d9 fb 28 9f c9 7c ba b3-26 ff dd 75 53 d1 12 65 ..(..|..&..uS..e
0010 - 91 76 91 2b f8 a2 b4 4b-0a e2 97 eb ce 8e a1 af .v.+...K........
[ ... lines ommitted for brevity ... ]
00a0 - 71 c3 a9 f3 16 c4 04 17-d1 e8 b0 75 e8 80 e9 fb q..........u....
Start Time: 1477857075
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
为什么验证我认为我使用的是自签名证书?还有其他我需要做的事情,例如OpenSSL检查 / etc / pki / tls 中的证书存储区是否有签署Let的加密证书的根权限的证书,而不是在找到它时你在OpenSSL库中链接? / etc / pki下的信任存储是否可能不知道Let的加密已经使用的根权限?在阅读Let's Encrypt Chain Of Trust page上的说明后,我得到 lets-encrypt-x3-cross-signed.pem ,这是完全错误的文件吗?