CouchDB 无法通过 SSL 工作
CouchDB won't work over SSL
我是运行 CouchDB Docker container, V.2.1.1. Everything is working at this point except for SSL. I am following the CouchDB documentation on SSL setup。容器有 OpenSSL 1.0.1t。
如文档中所示,我使用的是自签名证书。当我尝试连接到端口 6984 上的 SSL 页面时:
Chrome告诉我
"ERR_CONNECTION_CLOSED".
curl 给我
curl -k https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
在服务器日志中,我得到了很多这样的东西。
hello terminated with reason: no function clause matching ssl_cipher:hash_algorithm
搜索最后一个错误会找到表明 Erlang 版本有问题的信息。但是,我相信 CouchDB 容器有一个已经打过补丁的版本。我确实尝试过升级:
apt-get install Erlang
这没有区别。搜索结果也指出 OpenSSL 的版本有问题。我从源代码升级到 OpenSSL 1.1.1,重新创建了证书,问题仍然存在。
根据要求,这是更多命令的输出。
openssl s_client-连接localhost:6984
CONNECTED(00000005)
140736008328136:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/s23_lib.c:124:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 318 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
curl --version
curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy
curl -k -v https://localhost:6984
* Rebuilt URL to: https://localhost:6984/
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 6984 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
* stopped the pause stream!
* Closing connection 0
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
curl -k --ciphers 默认 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
curl -k --ciphers ECDHE-RSA-AES256-GCM-SHA384 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
以下三个命令的输出非常相似。我只会展示差异。但是,似乎所有这些命令现在都在进行握手。
$ openssl s_client -tls1 -connect localhost:6984
CONNECTED(00000005)
SSL handshake has read 1762 bytes and written 400 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 18C5DF9DCA1B8AA0DBD33258BCD253053F8D1D91B524B0561A1C0FAB8CFB5146
Master-Key: FD0C57E4E8FB992C0323D43930C104D82B69C4200F42E03EDB51E38A47448D62FDCB6E813583E2177A339B74B4D0CC4A
Start Time: 1525593658
Timeout : 7200 (sec)
$ path/to/brew/version/of/openssl s_client -connect localhost:6984
CONNECTED(00000003)
Peer signing digest: SHA512
Server Temp Key: DH, 1024 bits
SSL handshake has read 1796 bytes and written 537 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA256
SSL-Session:
Protocol : TLSv1.2
Cipher : DHE-RSA-AES256-SHA256
Session-ID: A19D67CBE634843181859DB2C3C4D1A3416C9F7DAA85CF470D412FE723AD49B4
Master-Key: 61B711B9BEDB651868607527439D01B421780C7D584FCE68C4754A7A7F3563923409C03F4B68BB7914397B48A92FC756
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1525593604
Timeout : 300 (sec)
$ path/to/brew/version/of/openssl s_client -tls1 -connect localhost:6984
SSL handshake has read 1762 bytes and written 397 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 6CC7FFE1C7CE258F105C7ADD5D8A9C0DFFB26A5A9555EB218EE48E519D361208
Master-Key: 2D6DFAC01544F6FF5F4138D877A4105485D5A2F77B58B4796822625E2E602455C38E3EEB2CBACE07FA03D207B07C715E
Start Time: 1525593717
Timeout : 7200 (sec)
$ curl -k --tlsv1 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
$ curl -k --tlsv1.0 https://localhost:6984
{"couchdb":"Welcome","version":"2.1.1","features":["scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
所以我猜 LibreSSL 的内置版本有问题?下一个问题是可以做些什么?
如果您的 SSL 证书是自签名的:
你没有显示你的 curl
命令,但我猜你 不是 使用 -k
选项,但你应该:
-k, --insecure
(TLS) By default, every SSL connection curl makes is verified to be secure. This option allows curl to proceed and operate even for
server connections otherwise considered insecure.
为了更深入地挖掘,你能post以下命令的输出吗?
$ openssl s_client -connect localhost:6984
$ curl --version
$ curl -k -v https://localhost:6984
$ curl -k --ciphers DEFAULT https://localhost:6984
$ curl -k --ciphers ECDHE-RSA-AES256-GCM-SHA384 https://localhost:6984
顺便说一下,我注意到您的 curl
使用的是 LibreSSL 而不是 OpenSSL,如您收到的错误消息所示:
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to
localhost:6984
当您尝试 openssl 时:
$ openssl s_client -connect localhost:6984
您遇到此错误:
CONNECTED(00000005) 140736008328136:error:140790E5:SSL
routines:SSL23_WRITE:ssl handshake
failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/s23_lib.c:124:
能否报告此命令的输出:
$ openssl s_client -tls1 -connect localhost:6984
此外,可以推断问题的原因是您的 macOS 默认版本 LibreSSL/OpenSSL。要解决此问题,请尝试再次安装 brew
版本的 OpenSSL 和 运行 此命令,并报告输出:
$ path/to/brew/version/of/openssl s_client -connect localhost:6984
也请post输出这个太:
$ path/to/brew/version/of/openssl s_client -tls1 -connect localhost:6984
根据您报告的输出,请尝试以下命令,看看它是否有效:
$ curl -k --tlsv1 https://localhost:6984
我不能肯定地说这是对 OP 在大约三年前遇到的特定问题的实际答案,并且还在增加,但这是一个答案 — 至少是对我在调试相同错误时遇到的问题的答案。
就我而言,我正在从 macOS 转移到 Linux Mint,进而从 MacPorts 和 Homebrew 转移到更恰当且不那么以用户为中心的处理软件的方式。
我说少了以用户为中心,因为问题的根源就出在这里。特别是,我已经将我所有的开发和配置文件从我的 macOS 系统同步到这个新的 Mint 系统,而且我的 Mac 上的方法是 运行 nginx,php-fpm , couchdb, 等等——也就是说,作为 daniel:staff
,那么我在 ~/Projects/SSL
中找到的 SSL 证书也归我所有。
而且,因为最佳做法是使用 0600
umask 锁定您的证书,并且一些应用程序拒绝 运行 如果不是,我的证书除了我以外任何人都无法读取,包括 couchdb
用户,在 Linux.
等“正确配置”的系统上默认使用 couchdb 运行
SSL_ERROR_SYSCALL
确实暗示了这一点——至少,它暗示了与系统调用相关的错误,而不是证书结构本身的错误。
此外,我们还看到 No client certificate CA names sent
、read 0 bytes
、New, (NONE), Cipher is (NONE)
以及更多 NONE
,所有这些都暗示实际上没有任何内容被读取。
同样,OP 的问题可能有所不同,但就我而言,SSL 文件上的一个简单 chmod
允许 couchdb 实际读取它们而不是在此处抛出。
我正在继续生成一个新的自签名证书并将其显式提供给 couchdb,但无论如何,这就是我特定盒子上这些错误背后的问题。
我是运行 CouchDB Docker container, V.2.1.1. Everything is working at this point except for SSL. I am following the CouchDB documentation on SSL setup。容器有 OpenSSL 1.0.1t。
如文档中所示,我使用的是自签名证书。当我尝试连接到端口 6984 上的 SSL 页面时:
Chrome告诉我
"ERR_CONNECTION_CLOSED".
curl 给我
curl -k https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
在服务器日志中,我得到了很多这样的东西。
hello terminated with reason: no function clause matching ssl_cipher:hash_algorithm
搜索最后一个错误会找到表明 Erlang 版本有问题的信息。但是,我相信 CouchDB 容器有一个已经打过补丁的版本。我确实尝试过升级:
apt-get install Erlang
这没有区别。搜索结果也指出 OpenSSL 的版本有问题。我从源代码升级到 OpenSSL 1.1.1,重新创建了证书,问题仍然存在。
根据要求,这是更多命令的输出。
openssl s_client-连接localhost:6984
CONNECTED(00000005)
140736008328136:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/s23_lib.c:124:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 318 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
curl --version
curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy
curl -k -v https://localhost:6984
* Rebuilt URL to: https://localhost:6984/
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 6984 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
* stopped the pause stream!
* Closing connection 0
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
curl -k --ciphers 默认 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
curl -k --ciphers ECDHE-RSA-AES256-GCM-SHA384 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
以下三个命令的输出非常相似。我只会展示差异。但是,似乎所有这些命令现在都在进行握手。
$ openssl s_client -tls1 -connect localhost:6984
CONNECTED(00000005)
SSL handshake has read 1762 bytes and written 400 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 18C5DF9DCA1B8AA0DBD33258BCD253053F8D1D91B524B0561A1C0FAB8CFB5146
Master-Key: FD0C57E4E8FB992C0323D43930C104D82B69C4200F42E03EDB51E38A47448D62FDCB6E813583E2177A339B74B4D0CC4A
Start Time: 1525593658
Timeout : 7200 (sec)
$ path/to/brew/version/of/openssl s_client -connect localhost:6984
CONNECTED(00000003)
Peer signing digest: SHA512
Server Temp Key: DH, 1024 bits
SSL handshake has read 1796 bytes and written 537 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA256
SSL-Session:
Protocol : TLSv1.2
Cipher : DHE-RSA-AES256-SHA256
Session-ID: A19D67CBE634843181859DB2C3C4D1A3416C9F7DAA85CF470D412FE723AD49B4
Master-Key: 61B711B9BEDB651868607527439D01B421780C7D584FCE68C4754A7A7F3563923409C03F4B68BB7914397B48A92FC756
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1525593604
Timeout : 300 (sec)
$ path/to/brew/version/of/openssl s_client -tls1 -connect localhost:6984
SSL handshake has read 1762 bytes and written 397 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 6CC7FFE1C7CE258F105C7ADD5D8A9C0DFFB26A5A9555EB218EE48E519D361208
Master-Key: 2D6DFAC01544F6FF5F4138D877A4105485D5A2F77B58B4796822625E2E602455C38E3EEB2CBACE07FA03D207B07C715E
Start Time: 1525593717
Timeout : 7200 (sec)
$ curl -k --tlsv1 https://localhost:6984
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
$ curl -k --tlsv1.0 https://localhost:6984
{"couchdb":"Welcome","version":"2.1.1","features":["scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
所以我猜 LibreSSL 的内置版本有问题?下一个问题是可以做些什么?
如果您的 SSL 证书是自签名的:
你没有显示你的 curl
命令,但我猜你 不是 使用 -k
选项,但你应该:
-k, --insecure
(TLS) By default, every SSL connection curl makes is verified to be secure. This option allows curl to proceed and operate even for
server connections otherwise considered insecure.
为了更深入地挖掘,你能post以下命令的输出吗?
$ openssl s_client -connect localhost:6984
$ curl --version
$ curl -k -v https://localhost:6984
$ curl -k --ciphers DEFAULT https://localhost:6984
$ curl -k --ciphers ECDHE-RSA-AES256-GCM-SHA384 https://localhost:6984
顺便说一下,我注意到您的 curl
使用的是 LibreSSL 而不是 OpenSSL,如您收到的错误消息所示:
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:6984
当您尝试 openssl 时:
$ openssl s_client -connect localhost:6984
您遇到此错误:
CONNECTED(00000005) 140736008328136:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/s23_lib.c:124:
能否报告此命令的输出:
$ openssl s_client -tls1 -connect localhost:6984
此外,可以推断问题的原因是您的 macOS 默认版本 LibreSSL/OpenSSL。要解决此问题,请尝试再次安装 brew
版本的 OpenSSL 和 运行 此命令,并报告输出:
$ path/to/brew/version/of/openssl s_client -connect localhost:6984
也请post输出这个太:
$ path/to/brew/version/of/openssl s_client -tls1 -connect localhost:6984
根据您报告的输出,请尝试以下命令,看看它是否有效:
$ curl -k --tlsv1 https://localhost:6984
我不能肯定地说这是对 OP 在大约三年前遇到的特定问题的实际答案,并且还在增加,但这是一个答案 — 至少是对我在调试相同错误时遇到的问题的答案。
就我而言,我正在从 macOS 转移到 Linux Mint,进而从 MacPorts 和 Homebrew 转移到更恰当且不那么以用户为中心的处理软件的方式。
我说少了以用户为中心,因为问题的根源就出在这里。特别是,我已经将我所有的开发和配置文件从我的 macOS 系统同步到这个新的 Mint 系统,而且我的 Mac 上的方法是 运行 nginx,php-fpm , couchdb, 等等——也就是说,作为 daniel:staff
,那么我在 ~/Projects/SSL
中找到的 SSL 证书也归我所有。
而且,因为最佳做法是使用 0600
umask 锁定您的证书,并且一些应用程序拒绝 运行 如果不是,我的证书除了我以外任何人都无法读取,包括 couchdb
用户,在 Linux.
SSL_ERROR_SYSCALL
确实暗示了这一点——至少,它暗示了与系统调用相关的错误,而不是证书结构本身的错误。
此外,我们还看到 No client certificate CA names sent
、read 0 bytes
、New, (NONE), Cipher is (NONE)
以及更多 NONE
,所有这些都暗示实际上没有任何内容被读取。
同样,OP 的问题可能有所不同,但就我而言,SSL 文件上的一个简单 chmod
允许 couchdb 实际读取它们而不是在此处抛出。
我正在继续生成一个新的自签名证书并将其显式提供给 couchdb,但无论如何,这就是我特定盒子上这些错误背后的问题。