我正在编写一个节点应用程序,它需要我创建一个TLS客户端来连接到远程主机。我遇到了一个问题,当应用程序在Docker外部运行时,我的TLS连接将正常工作,但当在Docker内部运行时,它将在收到TLS服务器的第一条消息之前立即发送“关闭通知”消息。
我的TLS客户端TS如下所示:
const socket = tls.connect(
{
host: host,
port: port,
cert: certificate
key: key
},
() => {
logger.info('client connected', socket.authorized ? 'authorized' : 'unauthorized');
// Business logic to notify the user we're connected
process.stdin.pipe(socket);
process.stdin.resume();
}
);
socket.on('data', (data: Buffer) => {
// Processing the data received from the server here
});
socket.on('error', () => {
// Business logic to notify the user the connection had an error. This is not called when the
// connection is closed
});
socket.on('close', hadError => {
// Business logic to notify the user the connection has been closed. hadError is false
// when this callback is called.
});
我使用socket类中内置的socket.enableTrace()函数添加了额外的日志记录,除了gmt_unix_time、random_bytes和session_id之外,裸机应用程序和Docker应用程序的所有值都是相同的。
TLS 1: client _init handle? true
**I'm only using self-signed certs in the dev environment**
(node:1) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
TLS 1: client initRead handle? true buffered? false
TLS 1: client _start handle? true connecting? false requestOCSP? false
Client sends handshake
Client receives handshake
Client receives ChangeCipherSpec
Client receives ApplicationData (continuing handshake)
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 281
Inner Content Type = Handshake (22)
CertificateVerify, Length=260
Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
Signature (len=256): <snip>
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 69
Inner Content Type = Handshake (22)
Finished, Length=48
verify_data (len=48): <snip>
TLS 1: client onhandshakedone
TLS 1: client _finishInit handle? true alpn false servername false
**Sees the self-signed cert, but I'm ignoring this in my dev environment**
TLS 1: client emit secureConnect. rejectUnauthorized: false, authorizationError: SELF_SIGNED_CERT_IN_CHAIN
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 521
Inner Content Type = ApplicationData (23)
** Here is where the client is sending the close notify**
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 19
Inner Content Type = Alert (21)
Level=warning(1), description=close notify(0)
Received Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 453
Inner Content Type = ApplicationData (23)
** Here is where the server is acking the close notify**
Received Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ApplicationData (23)
Length = 19
Inner Content Type = Alert (21)
Level=warning(1), description=close notify(0)
我的Docker合成文件正在公开和发布用于此连接的TLS端口。
我的开发服务器运行Ubuntu 22.04,而官方的Node Docker镜像运行的是Debian环境,所以我从头开始开发了自己的Dockerfile,但这并没有改变行为。我注意到的另一件事是openssl的版本在裸机和Docker之间是不同的(v3 vs v1),但使用openssl v3定制Dockerfile也没有改变任何东西。
我可以在裸机和Docker环境中使用代码中的类似模式建立通用TCP连接。
1条答案
按热度按时间eni9jsuy1#
据我所知,发送close_notify的原因是因为我的TLS客户端需要访问stdin。当我在Docker中运行应用程序时,我没有使用--interactive标志,因此它没有访问stdin。设置此标志允许连接持续。