【发布时间】:2021-07-04 04:04:52
【问题描述】:
我已经设置了一个 HTTPS 服务器(nodejs v14.16.0)和来自letsEncrypt 的证书(在使用https.createServer 的应用程序的当前版本中工作)。不幸的是,curl 无法成功连接到我的 HTTPS 服务器。我收到以下错误
routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
这是我的服务器的最低可复制版本
const https = require('https')
const tls = require('tls');
const fs = require('fs');
const constants = require('constants');
tls.DEFAULT_ECDH_CURVE = "auto"
require('dotenv').config()
const certOpts = {
key: `${process.env.KEY_PATH}/privkey.pem`,
cert: `${process.env.KEY_PATH}/cert.pem`,
ca: `${process.env.KEY_PATH}/chain.pem`,
};
/**
*
* @param {Record<string, string>} filePathMap
* @returns {Record<string, Buffer>}
*/
function getBuffersFromFilePathMap(filePathMap) {
const bufferMap = {}
for (const path in filePathMap) {
if (Object.hasOwnProperty.call(filePathMap, path)) {
bufferMap[path] = fs.readFileSync(filePathMap[path]);
}
}
return bufferMap;
}
const buffers = getBuffersFromFilePathMap(certOpts);
function createContext() {
return tls.createSecureContext({
...buffers,
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1,
maxVersion:'TLSv1.2'
});
}
const server = https.createServer({ secureContext: createContext() }, (req, res) => {
// eslint-disable-next-line no-console
console.log('connect');
res.writeHead(200);
res.write('Hello World!\n');
res.end('Goodbye World!\n');
});
server.listen(9999, () => console.log('Server up: ', server.address()));
这是curl --version的输出
curl 7.61.1 (x86_64-redhat-linux-gnu) libcurl/7.61.1 OpenSSL/1.0.2k zlib/1.2.8 libidn2/2.3.0 libpsl/0.6.2 (+libicu/50.1.2) libssh2/1.4.2 nghttp2/1.31.1
Release-Date: 2018-09-05
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy PSL
据我所知,可能不支持 ssl3。
卷曲的输出
$ curl -k https://localhost:9999
curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
卷曲痕迹
== Info: Rebuilt URL to: https://localhost:9999/
== Info: Trying 127.0.0.1...
== Info: TCP_NODELAY set
== Info: Connected to localhost (127.0.0.1) port 9999 (#0)
== Info: ALPN, offering h2
== Info: ALPN, offering http/1.1
== Info: Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
== Info: successfully set certificate verify locations:
== Info: CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
== Info: TLSv1.2 (OUT), TLS header, Certificate Status (22):
=> Send SSL data, 5 bytes (0x5)
0000: .....
== Info: TLSv1.2 (OUT), TLS handshake, Client hello (1):
=> Send SSL data, 512 bytes (0x200)
0000: .......*.c....}.5.H>^..e\;)}.zEW.....d....0.,.(.$.............k.
0040: j.i.h.9.8.7.6.........2...*.&.......=.5.../.+.'.#.............g.
0080: @.?.>.3.2.1.0.........E.D.C.B.1.-.).%.......<./...A.............
00c0: ............3.........localhost......................... .......
0100: ..............................3t.........h2.http/1.1............
0140: ................................................................
0180: ................................................................
01c0: ................................................................
== Info: TLSv1.2 (IN), TLS header, Unknown (21):
<= Recv SSL data, 5 bytes (0x5)
0000: .....
== Info: TLSv1.2 (IN), TLS alert, handshake failure (552):
<= Recv SSL data, 2 bytes (0x2)
0000: .(
== Info: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
【问题讨论】:
-
您设置了
requestCert:true, rejectUnauthorizhed:true,它告诉服务器拒绝任何未使用有效证书和密钥进行身份验证的客户端。您的curl命令没有进行身份验证(根本没有验证),因此它被拒绝了——正如你所说的那样 -
即使这些选项设置为 false,我也有同样的握手问题
-
curl --trace-ascii blahblah.log将转储 lot 的调试消息,包括。 TLS握手的细节。 -
我看到它使用 tls v1.2 但遇到错误。我将使用 curl 跟踪来编辑问题,因为它太长了,我无法将它发布到 cmets 中