Compare commits

...

2 Commits

Author SHA1 Message Date
622ad2ff20 3.18.0 2025-02-27 20:59:29 +00:00
dd23efd28d feat(PortProxy): Add SNI-based renegotiation handling in PortProxy 2025-02-27 20:59:29 +00:00
4 changed files with 24 additions and 2 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## 2025-02-27 - 3.18.0 - feat(PortProxy)
Add SNI-based renegotiation handling in PortProxy
- Introduced a new field 'lockedDomain' in IConnectionRecord to store initial SNI.
- Enhanced connection management by enforcing termination if rehandshake is detected with different SNI.
## 2025-02-27 - 3.17.1 - fix(PortProxy)
Fix handling of SNI re-negotiation in PortProxy

View File

@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartproxy",
"version": "3.17.1",
"version": "3.18.0",
"private": false,
"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.",
"main": "dist_ts/index.js",

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartproxy',
version: '3.17.1',
version: '3.18.0',
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.'
}

View File

@ -90,6 +90,7 @@ interface IConnectionRecord {
outgoing: plugins.net.Socket | null;
incomingStartTime: number;
outgoingStartTime?: number;
lockedDomain?: string; // New field to lock this connection to the initial SNI
connectionClosed: boolean;
cleanupTimer?: NodeJS.Timeout; // Timer to force cleanup after max lifetime/inactivity
}
@ -366,7 +367,22 @@ export class PortProxy {
socket.setTimeout(0);
initialDataReceived = true;
const serverName = extractSNI(chunk) || '';
// Lock the connection to the negotiated SNI.
connectionRecord.lockedDomain = serverName;
console.log(`Received connection from ${remoteIP} with SNI: ${serverName}`);
// Delay adding the renegotiation listener until the next tick,
// so the initial ClientHello is not reprocessed.
setImmediate(() => {
socket.on('data', (renegChunk: Buffer) => {
if (renegChunk.length > 0 && renegChunk.readUInt8(0) === 22) {
const newSNI = extractSNI(renegChunk);
if (newSNI && newSNI !== connectionRecord.lockedDomain) {
console.log(`Rehandshake detected with different SNI: ${newSNI} vs locked ${connectionRecord.lockedDomain}. Terminating connection.`);
cleanupOnce();
}
}
});
});
setupConnection(serverName, chunk);
});
} else {