Node TLS 客户端连接会自动发送"关闭通知"消息(但仅在 Docker 中)



我正在编写一个Node应用程序,它需要我创建一个TLS客户端来连接到远程主机。我遇到了一个问题,当应用程序在Docker外部运行时,我的TLS连接将正常工作,但是当在内部运行时,它会在收到来自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. enabletrace()函数添加了额外的日志记录,内置到socket类中,除了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连接。

从我已经能够发现的,close_notify被发送的原因是因为我的TLS客户端需要访问stdin。当我在Docker中运行应用程序时,我没有使用——interactive标志,所以它没有访问stdin。设置此标志允许连接保持。

相关内容

  • 没有找到相关文章

最新更新