UNPKG

@push.rocks/smartproxy

Version:

A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.

132 lines 9.85 kB
import * as plugins from '../plugins.js'; import { SniHandler } from './classes.pp.snihandler.js'; /** * Manages TLS-related operations including SNI extraction and validation */ export class TlsManager { constructor(settings) { this.settings = settings; } /** * Check if a data chunk appears to be a TLS handshake */ isTlsHandshake(chunk) { return SniHandler.isTlsHandshake(chunk); } /** * Check if a data chunk appears to be a TLS ClientHello */ isClientHello(chunk) { return SniHandler.isClientHello(chunk); } /** * Extract Server Name Indication (SNI) from TLS handshake */ extractSNI(chunk, connInfo, previousDomain) { // Use the SniHandler to process the TLS packet return SniHandler.processTlsPacket(chunk, connInfo, this.settings.enableTlsDebugLogging || false, previousDomain); } /** * Handle session resumption attempts */ handleSessionResumption(chunk, connectionId, hasSNI) { // Skip if session tickets are allowed if (this.settings.allowSessionTicket !== false) { return { shouldBlock: false }; } // Check for session resumption attempt const resumptionInfo = SniHandler.hasSessionResumption(chunk, this.settings.enableTlsDebugLogging || false); // If this is a resumption attempt without SNI, block it if (resumptionInfo.isResumption && !hasSNI && !resumptionInfo.hasSNI) { if (this.settings.enableTlsDebugLogging) { console.log(`[${connectionId}] Session resumption detected without SNI and allowSessionTicket=false. ` + `Terminating connection to force new TLS handshake.`); } return { shouldBlock: true, reason: 'session_ticket_blocked' }; } return { shouldBlock: false }; } /** * Check for SNI mismatch during renegotiation */ checkRenegotiationSNI(chunk, connInfo, expectedDomain, connectionId) { // Only process if this looks like a TLS ClientHello if (!this.isClientHello(chunk)) { return { hasMismatch: false }; } try { // Extract SNI with renegotiation support const newSNI = SniHandler.extractSNIWithResumptionSupport(chunk, connInfo, this.settings.enableTlsDebugLogging || false); // Skip if no SNI was found if (!newSNI) return { hasMismatch: false }; // Check for SNI mismatch if (newSNI !== expectedDomain) { if (this.settings.enableTlsDebugLogging) { console.log(`[${connectionId}] Renegotiation with different SNI: ${expectedDomain} -> ${newSNI}. ` + `Terminating connection - SNI domain switching is not allowed.`); } return { hasMismatch: true, extractedSNI: newSNI }; } else if (this.settings.enableTlsDebugLogging) { console.log(`[${connectionId}] Renegotiation detected with same SNI: ${newSNI}. Allowing.`); } } catch (err) { console.log(`[${connectionId}] Error processing ClientHello: ${err}. Allowing connection to continue.`); } return { hasMismatch: false }; } /** * Create a renegotiation handler function for a connection */ createRenegotiationHandler(connectionId, lockedDomain, connInfo, onMismatch) { return (chunk) => { const result = this.checkRenegotiationSNI(chunk, connInfo, lockedDomain, connectionId); if (result.hasMismatch) { onMismatch(connectionId, 'sni_mismatch'); } }; } /** * Analyze TLS connection for browser fingerprinting * This helps identify browser vs non-browser connections */ analyzeClientHello(chunk) { // Default result const result = { isBrowserConnection: false, isRenewal: false, hasSNI: false }; try { // Check if it's a ClientHello if (!this.isClientHello(chunk)) { return result; } // Check for session resumption const resumptionInfo = SniHandler.hasSessionResumption(chunk, this.settings.enableTlsDebugLogging || false); // Extract SNI const sni = SniHandler.extractSNI(chunk, this.settings.enableTlsDebugLogging || false); // Update result result.isRenewal = resumptionInfo.isResumption; result.hasSNI = !!sni; // Browsers typically: // 1. Send SNI extension // 2. Have a variety of extensions (ALPN, etc.) // 3. Use standard cipher suites // ...more complex heuristics could be implemented here // Simple heuristic: presence of SNI suggests browser result.isBrowserConnection = !!sni; return result; } catch (err) { console.log(`Error analyzing ClientHello: ${err}`); return result; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcC50bHNtYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRwcm94eS9jbGFzc2VzLnBwLnRsc21hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBWXhEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDckIsWUFBb0IsUUFBNEI7UUFBNUIsYUFBUSxHQUFSLFFBQVEsQ0FBb0I7SUFBRyxDQUFDO0lBRXBEOztPQUVHO0lBQ0ksY0FBYyxDQUFDLEtBQWE7UUFDakMsT0FBTyxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWEsQ0FBQyxLQUFhO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVLENBQ2YsS0FBYSxFQUNiLFFBQXlCLEVBQ3pCLGNBQXVCO1FBRXZCLCtDQUErQztRQUMvQyxPQUFPLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FDaEMsS0FBSyxFQUNMLFFBQVEsRUFDUixJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixJQUFJLEtBQUssRUFDNUMsY0FBYyxDQUNmLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSSx1QkFBdUIsQ0FDNUIsS0FBYSxFQUNiLFlBQW9CLEVBQ3BCLE1BQWU7UUFFZixzQ0FBc0M7UUFDdEMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixLQUFLLEtBQUssRUFBRSxDQUFDO1lBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDaEMsQ0FBQztRQUVELHVDQUF1QztRQUN2QyxNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUMsb0JB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