fix(PortProxy): Fixed handling of SNI domain connections and IP allowance checks

This commit is contained in:
Philipp Kunz 2025-02-21 18:54:40 +00:00
parent 4747462cff
commit 32d875aed9
3 changed files with 29 additions and 22 deletions

View File

@ -1,5 +1,12 @@
# Changelog # Changelog
## 2025-02-21 - 3.4.4 - fix(PortProxy)
Fixed handling of SNI domain connections and IP allowance checks
- Improved logic for handling SNI domain checks, ensuring IPs are correctly verified.
- Fixed issue where default allowed IPs were not being checked correctly for non-SNI connections.
- Revised the SNICallback behavior to handle connections more gracefully when domain configurations are unavailable.
## 2025-02-21 - 3.4.3 - fix(PortProxy) ## 2025-02-21 - 3.4.3 - fix(PortProxy)
Fixed indentation issue and ensured proper cleanup of sockets in PortProxy Fixed indentation issue and ensured proper cleanup of sockets in PortProxy

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartproxy', name: '@push.rocks/smartproxy',
version: '3.4.3', version: '3.4.4',
description: 'a proxy for handling high workloads of proxying' description: 'a proxy for handling high workloads of proxying'
} }

View File

@ -73,9 +73,8 @@ export class PortProxy {
console.log(`SNI request for domain: ${serverName}`); console.log(`SNI request for domain: ${serverName}`);
const domainConfig = findMatchingDomain(serverName); const domainConfig = findMatchingDomain(serverName);
if (!domainConfig) { if (!domainConfig) {
console.log(`SNI rejected: No matching domain config for ${serverName}`); // Always allow SNI for default IPs, even if domain doesn't match
cb(new Error(`No configuration for domain: ${serverName}`)); console.log(`SNI domain ${serverName} not found, will check IP during connection`);
return;
} }
// Create context with the provided TLS settings // Create context with the provided TLS settings
const ctx = plugins.tls.createSecureContext(this.settings); const ctx = plugins.tls.createSecureContext(this.settings);
@ -88,31 +87,32 @@ export class PortProxy {
const remoteIP = from.remoteAddress || ''; const remoteIP = from.remoteAddress || '';
let serverName = ''; let serverName = '';
// First check if this IP is in the default allowed list
const isDefaultAllowed = this.settings.defaultAllowedIPs && isAllowed(remoteIP, this.settings.defaultAllowedIPs);
if (this.settings.sniEnabled && from instanceof plugins.tls.TLSSocket) { if (this.settings.sniEnabled && from instanceof plugins.tls.TLSSocket) {
serverName = (from as any).servername || ''; serverName = (from as any).servername || '';
console.log(`TLS Connection from ${remoteIP} for domain: ${serverName}`); console.log(`TLS Connection from ${remoteIP} for domain: ${serverName}`);
} }
// For TLS connections, we've already validated the domain in SNICallback // If IP is in defaultAllowedIPs, allow the connection regardless of SNI
if (!this.settings.sniEnabled || from instanceof plugins.tls.TLSSocket) { if (isDefaultAllowed) {
const domainConfig = serverName ? findMatchingDomain(serverName) : undefined; console.log(`Connection allowed: IP ${remoteIP} is in default allowed list`);
} else if (this.settings.sniEnabled && serverName) {
// For SNI connections that aren't in default list, check domain-specific rules
const domainConfig = findMatchingDomain(serverName);
if (!domainConfig) { if (!domainConfig) {
// If no matching domain config found, check default IPs if available console.log(`Connection rejected: No matching domain config for ${serverName} from IP ${remoteIP}`);
if (!this.settings.defaultAllowedIPs || !isAllowed(remoteIP, this.settings.defaultAllowedIPs)) { from.end();
console.log(`Connection rejected: No matching domain config for ${serverName || 'non-SNI'} from IP ${remoteIP}`); return;
from.end();
return;
}
} else {
// Check if IP is allowed for this domain
if (!isAllowed(remoteIP, domainConfig.allowedIPs)) {
console.log(`Connection rejected: IP ${remoteIP} not allowed for domain ${serverName}`);
from.end();
return;
}
} }
} else if (!this.settings.defaultAllowedIPs || !isAllowed(remoteIP, this.settings.defaultAllowedIPs)) { if (!isAllowed(remoteIP, domainConfig.allowedIPs)) {
console.log(`Connection rejected: IP ${remoteIP} not allowed for domain ${serverName}`);
from.end();
return;
}
} else {
// Non-SNI connection and not in default list
console.log(`Connection rejected: IP ${remoteIP} not allowed for non-SNI connection`); console.log(`Connection rejected: IP ${remoteIP} not allowed for non-SNI connection`);
from.end(); from.end();
return; return;