TLS verification fails for IPv6 IP subjectAltName in v22.23.0 and v24.17.0
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 52/100
- Issue 類型
- 缺陷
- 描述清晰度
- 基本清楚
- 活躍度
- 冷清
- 技術堆疊
- javascript, node.js
- 領域
- networking, security
研究方向
從 open-socket.js 的重現和 tls.connect() 的主機驗證路徑開始,將受影響的 Node.js 版本與正常運作的版本進行比較。追蹤數值形式的 IPv6 Subject Alternative Name 如何進行比對,然後為回報的憑證新增涵蓋範圍,並確認在將 authorized 設為 true 時連線能夠成功。
由索引模型根據 Issue 內容生成。
描述
Version
22.23.0, 24.17.0
Platform
Linux Debian 12 amd64, Linux Debian 12 arm64
Subsystem
SSL/TLS tls.connect()
What steps will reproduce the bug?
After update to 22.23.0, changes seem to have impacted TLS host verification for certificates created with IPv6 numeric address as the X509v3 Subject Alternative Name: IP Address field. This may be related recent changes "tls: normalize hostname for server identity checks" and "tls: fix case-sensitive SNI context matching"
- Create a TLS CA certificate for use to sign server certificates and use as client's CA certificate.
basicConstraints = critical,CA:true,pathlen:0
keyUsage = cRLSign, keyCertSign
- Create TLS server certificate with numeric IPv6 SAN.
extendedKeyUsage=serverAuth
subjectAltName=@alt_names
[alt_names]
IP.1=192.168.34.55
IP.2=fc00:34::55
- On one computer, start openssl s_server
openssl s_server -accept 8002 -cert my-server-cert.pem -key my-server-key.pem -cert_chain my-CA-cert.pem
- On second computer, run code to reproduce
// open-socket.js
'use strict';
const tls = require('tls');
const fs = require('fs');
const socket = tls.connect({
host: 'fc00:34::55',
port: 8002,
ca: fs.readFileSync('my-CA-cert.pem'),
// true: Certificate is only accepted if IP address matches certificate X509v3 Subject Alternative Name: "IP address" value.
rejectUnauthorized: true
// Do not include "servername" property. Server name for the SNI (Server Name Indication) must not an IP address (Node.js docs, tls.connect options)
}, () => {
console.log('TLS connected');
console.log('authorized:', socket.authorized);
console.log('authorizationError:', socket.authorizationError);
console.log('Sending: "This is a test message.\\n"');
socket.end('This is a test message.\n');
});
socket.on('error', (err) => {
console.error('TLS socket error:', err.message);
process.exitCode = 1;
});
socket.on('close', () => {
console.log('TLS socket closed');
});
How often does it reproduce? Is there a required condition?
Each time tls.connect( ... ) is called using certificate with numeric IPv6 IP SAN.
What is the expected behavior? Why is that the expected behavior?
Using previous version of Node v22.22.3 or v24.16.0, connect succeeds without error
- Client opens socket and sends test message to server
$ nvm use 22.22.3
Now using node v22.22.3 (npm v11.15.0)
$ node open-socket.js
TLS connected
authorized: true
authorizationError: null
Sending: "This is a test message.\n"
TLS socket closed
- Server shows test message "This is a test message", no errors
openssl s_server -accept 8002 -cert my-server-cert.pem -key my-server-key.pem -cert_chain my-CA-cert.pem
This is a test message.
DONE
shutting down SSL
CONNECTION CLOSED
What do you see instead?
Using current Node v22.23.0 or v24.17.0 TLS verification fails.
- Client
$ nvm use 22.23.0
Now using node v22.23.0 (npm v10.9.8)
$ node open-socket.js
TLS socket error: Hostname/IP does not match certificate's altnames: Host: fc00:34::55. is not cert's CN: my-server-CN
TLS socket closed
$ nvm use 24.17.0
Now using node v24.17.0 (npm v11.13.0)
$ node open-socket.js
TLS socket error: Hostname/IP does not match certificate's altnames: Host: fc00:34::55. is not cert's CN: my-server-CN
TLS socket closed
- Server
openssl s_server -accept 8002 -cert my-server-cert.pem -key my-server-key.pem -cert_chain my-CA-cert.pem
ERROR
20D0199D7F000000:error:0A000126:SSL routines::unexpected eof while reading:../ssl/record/rec_layer_s3.c:698:
shutting down SSL
CONNECTION CLOSED
ERROR
20D0199D7F000000:error:0A000126:SSL routines::unexpected eof while reading:../ssl/record/rec_layer_s3.c:698:
shutting down SSL
CONNECTION CLOSED
Additional information
The strongest clue is the period after IPv6 address in the error message, possible domain name syntax.
Only IPv6 is impacted. Certificates with numeric IPv4 IP SAN work as expected.
These are example decoded TLS certificates
$ openssl x509 -in my-CA-cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4f:65:a0:84:24:4a:ac:40:66:c5:fc:e3:19:4c:ae:7c:9f:73:ee:f5
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = my-org-name, CN = my_CA_CN
Validity
Not Before: Jun 20 14:22:52 2026 GMT
Not After : Jun 20 14:22:52 2027 GMT
Subject: O = my-org-name, CN = my_CA_CN
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e3:21: ...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
86:9F:90:CD:0F:45:3B:83:E2:00:64:A5:06:94:7D:0A:FD:00:E9:3E
X509v3 Authority Key Identifier:
86:9F:90:CD:0F:45:3B:83:E2:00:64:A5:06:94:7D:0A:FD:00:E9:3E
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Key Usage:
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
d4:f3:8c: ...
$ openssl x509 -in my-server-cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0a:52:54:3a:67:b7:46:f4:57:c8:03:e5:10:0d:38:4e:58:39:c3:b7
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = my-org-name, CN = my_CA_CN
Validity
Not Before: Jun 20 14:22:52 2026 GMT
Not After : Jun 20 14:22:52 2027 GMT
Subject: O = my-org-name, CN = my-server-CN
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e8:4c:be: ...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
86:9F:90:CD:0F:45:3B:83:E2:00:64:A5:06:94:7D:0A:FD:00:E9:3E
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
24:9A:3B:F6:DC:20:47:69:9C:AE:51:6F:E6:B5:1E:3D:45:E0:50:22
X509v3 Subject Alternative Name:
IP Address:192.168.34.55, IP Address:FC00:34:0:0:0:0:0:55
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
48:54:8a:85: ...
- 主要語言
- JavaScript
- 星號
- 122k
- 分支
- 38.4k
- 平均合併
- 4 天 10 小時
- 30 天內合併 PR
- 276
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
nodejs/node 的其他 Issue
-
doc
難度 1/5 1 小時以內 新手友好度 90/100
維護者通常 1 天內回覆
-
doc
難度 2/5 1-3 小時 新手友好度 65/100
維護者通常 1 天內回覆
-
build
難度 1/5 1 小時以內 新手友好度 88/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 84/100
nodejs/node#65994 · 2 則留言 · 2 個 reaction ·
維護者通常 1 天內回覆
-
feature request
難度 2/5 1-3 小時 新手友好度 68/100
維護者通常 1 天內回覆
相似的 Issue
-
external-issue to-triage
難度 2/5 1-3 小時 新手友好度 82/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 84/100
LearningCircuit/local-deep-research#7067 ·
維護者通常 1 天內回覆
-
automated issue report
難度 1/5 1 小時以內 新手友好度 65/100
lirantal/discoprint#32 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 86/100
維護者通常 1 天內回覆