fix(PortProxy): Improve TLS handshake buffering and enhance debug logging for SNI forwarding in PortProxy
This commit is contained in:
parent
0ea0f02428
commit
d6022c8f8a
@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-03-11 - 3.31.1 - fix(PortProxy)
|
||||||
|
Improve TLS handshake buffering and enhance debug logging for SNI forwarding in PortProxy
|
||||||
|
|
||||||
|
- Explicitly copy the initial TLS handshake data to prevent mutation before buffering
|
||||||
|
- Log buffered TLS handshake data with SNI information for better diagnostics
|
||||||
|
- Add detailed error logs on TLS connection failures, including server and domain config status
|
||||||
|
- Output additional debug messages during ClientHello forwarding to verify proper TLS handshake processing
|
||||||
|
|
||||||
## 2025-03-11 - 3.31.0 - feat(PortProxy)
|
## 2025-03-11 - 3.31.0 - feat(PortProxy)
|
||||||
Improve TLS handshake SNI extraction and add session resumption tracking in PortProxy
|
Improve TLS handshake SNI extraction and add session resumption tracking in PortProxy
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartproxy',
|
name: '@push.rocks/smartproxy',
|
||||||
version: '3.31.0',
|
version: '3.31.1',
|
||||||
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.'
|
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.'
|
||||||
}
|
}
|
||||||
|
@ -804,11 +804,22 @@ export class PortProxy {
|
|||||||
// Add the temp handler to capture all incoming data during connection setup
|
// Add the temp handler to capture all incoming data during connection setup
|
||||||
socket.on('data', tempDataHandler);
|
socket.on('data', tempDataHandler);
|
||||||
|
|
||||||
// Add initial chunk to pending data if present
|
// Add initial chunk to pending data if present - this is critical for SNI forwarding
|
||||||
if (initialChunk) {
|
if (initialChunk) {
|
||||||
record.bytesReceived += initialChunk.length;
|
// Make explicit copy of the buffer to ensure it doesn't get modified
|
||||||
record.pendingData.push(Buffer.from(initialChunk));
|
const initialDataCopy = Buffer.from(initialChunk);
|
||||||
record.pendingDataSize = initialChunk.length;
|
record.bytesReceived += initialDataCopy.length;
|
||||||
|
record.pendingData.push(initialDataCopy);
|
||||||
|
record.pendingDataSize = initialDataCopy.length;
|
||||||
|
|
||||||
|
// Log TLS handshake for debug purposes
|
||||||
|
if (isTlsHandshake(initialChunk)) {
|
||||||
|
record.isTLS = true;
|
||||||
|
console.log(`[${connectionId}] Buffered TLS handshake data: ${initialDataCopy.length} bytes, SNI: ${serverName || 'none'}`);
|
||||||
|
}
|
||||||
|
} else if (record.isTLS) {
|
||||||
|
// This shouldn't happen, but log a warning if we have a TLS connection with no initial data
|
||||||
|
console.log(`[${connectionId}] WARNING: TLS connection without initial handshake data`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the target socket but don't set up piping immediately
|
// Create the target socket but don't set up piping immediately
|
||||||
@ -874,6 +885,11 @@ export class PortProxy {
|
|||||||
// Log additional diagnostics
|
// Log additional diagnostics
|
||||||
console.log(`[${connectionId}] Connection details - SNI: ${serverName || 'none'}, HasChunk: ${!!initialChunk}, ChunkSize: ${initialChunk ? initialChunk.length : 0}`);
|
console.log(`[${connectionId}] Connection details - SNI: ${serverName || 'none'}, HasChunk: ${!!initialChunk}, ChunkSize: ${initialChunk ? initialChunk.length : 0}`);
|
||||||
|
|
||||||
|
// For TLS connections, provide even more detailed diagnostics
|
||||||
|
if (record.isTLS) {
|
||||||
|
console.log(`[${connectionId}] TLS connection failure details - TLS detected: ${record.isTLS}, Server: ${targetHost}:${connectionOptions.port}, Domain config: ${domainConfig ? 'Present' : 'Missing'}`);
|
||||||
|
}
|
||||||
|
|
||||||
// For connection refusal or timeouts, try a more aggressive error response
|
// For connection refusal or timeouts, try a more aggressive error response
|
||||||
// This helps browsers quickly realize there's an issue rather than waiting
|
// This helps browsers quickly realize there's an issue rather than waiting
|
||||||
if (code === 'ECONNREFUSED' || code === 'ETIMEDOUT' || code === 'EHOSTUNREACH') {
|
if (code === 'ECONNREFUSED' || code === 'ETIMEDOUT' || code === 'EHOSTUNREACH') {
|
||||||
@ -999,12 +1015,29 @@ export class PortProxy {
|
|||||||
// Flush all pending data to target
|
// Flush all pending data to target
|
||||||
if (record.pendingData.length > 0) {
|
if (record.pendingData.length > 0) {
|
||||||
const combinedData = Buffer.concat(record.pendingData);
|
const combinedData = Buffer.concat(record.pendingData);
|
||||||
|
|
||||||
|
// Add critical debugging for SNI forwarding issues
|
||||||
|
if (record.isTLS && this.settings.enableTlsDebugLogging) {
|
||||||
|
console.log(`[${connectionId}] Forwarding TLS handshake data: ${combinedData.length} bytes, SNI: ${serverName || 'none'}`);
|
||||||
|
|
||||||
|
// Additional check to verify we're forwarding the ClientHello properly
|
||||||
|
if (combinedData[0] === 22) { // TLS handshake
|
||||||
|
console.log(`[${connectionId}] Initial data is a TLS handshake record`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the combined data to the target
|
||||||
targetSocket.write(combinedData, (err) => {
|
targetSocket.write(combinedData, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(`[${connectionId}] Error writing pending data to target: ${err.message}`);
|
console.log(`[${connectionId}] Error writing pending data to target: ${err.message}`);
|
||||||
return this.initiateCleanupOnce(record, 'write_error');
|
return this.initiateCleanupOnce(record, 'write_error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record.isTLS) {
|
||||||
|
// Log successful forwarding of initial TLS data
|
||||||
|
console.log(`[${connectionId}] Successfully forwarded initial TLS data to backend`);
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the renegotiation listener *before* piping if this is a TLS connection with SNI
|
// Set up the renegotiation listener *before* piping if this is a TLS connection with SNI
|
||||||
if (serverName && record.isTLS) {
|
if (serverName && record.isTLS) {
|
||||||
// This listener handles TLS renegotiation detection
|
// This listener handles TLS renegotiation detection
|
||||||
@ -1956,6 +1989,15 @@ export class PortProxy {
|
|||||||
)
|
)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
// Enhanced logging to diagnose domain config selection issues
|
||||||
|
if (serverName && !domainConfig) {
|
||||||
|
console.log(`[${connectionId}] WARNING: No domain config found for SNI: ${serverName}`);
|
||||||
|
console.log(`[${connectionId}] Available domains:`,
|
||||||
|
this.settings.domainConfigs.map(config => config.domains.join(',')).join(' | '));
|
||||||
|
} else if (serverName && domainConfig) {
|
||||||
|
console.log(`[${connectionId}] Found domain config for SNI: ${serverName} -> ${domainConfig.domains.join(',')}`);
|
||||||
|
}
|
||||||
|
|
||||||
// For session resumption, ensure we use the domain config matching the resumed domain
|
// For session resumption, ensure we use the domain config matching the resumed domain
|
||||||
// The resumed domain will be in serverName if this is a session resumption
|
// The resumed domain will be in serverName if this is a session resumption
|
||||||
if (serverName && connectionRecord.lockedDomain === serverName && serverName !== '') {
|
if (serverName && connectionRecord.lockedDomain === serverName && serverName !== '') {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user