@push.rocks/smartproxy 3.4.1 → 3.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '3.4.
|
|
6
|
+
version: '3.4.4',
|
|
7
7
|
description: 'a proxy for handling high workloads of proxying'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLGlEQUFpRDtDQUMvRCxDQUFBIn0=
|
|
@@ -39,31 +39,50 @@ export class PortProxy {
|
|
|
39
39
|
return this.settings.domains.find(config => plugins.minimatch(serverName, config.domain));
|
|
40
40
|
};
|
|
41
41
|
const server = this.settings.sniEnabled
|
|
42
|
-
? plugins.tls.createServer(
|
|
42
|
+
? plugins.tls.createServer({
|
|
43
|
+
...this.settings,
|
|
44
|
+
SNICallback: (serverName, cb) => {
|
|
45
|
+
console.log(`SNI request for domain: ${serverName}`);
|
|
46
|
+
const domainConfig = findMatchingDomain(serverName);
|
|
47
|
+
if (!domainConfig) {
|
|
48
|
+
// Always allow SNI for default IPs, even if domain doesn't match
|
|
49
|
+
console.log(`SNI domain ${serverName} not found, will check IP during connection`);
|
|
50
|
+
}
|
|
51
|
+
// Create context with the provided TLS settings
|
|
52
|
+
const ctx = plugins.tls.createSecureContext(this.settings);
|
|
53
|
+
cb(null, ctx);
|
|
54
|
+
}
|
|
55
|
+
})
|
|
43
56
|
: plugins.net.createServer();
|
|
44
|
-
|
|
57
|
+
const handleConnection = (from) => {
|
|
45
58
|
const remoteIP = from.remoteAddress || '';
|
|
59
|
+
let serverName = '';
|
|
60
|
+
// First check if this IP is in the default allowed list
|
|
61
|
+
const isDefaultAllowed = this.settings.defaultAllowedIPs && isAllowed(remoteIP, this.settings.defaultAllowedIPs);
|
|
46
62
|
if (this.settings.sniEnabled && from instanceof plugins.tls.TLSSocket) {
|
|
47
|
-
|
|
63
|
+
serverName = from.servername || '';
|
|
64
|
+
console.log(`TLS Connection from ${remoteIP} for domain: ${serverName}`);
|
|
65
|
+
}
|
|
66
|
+
// If IP is in defaultAllowedIPs, allow the connection regardless of SNI
|
|
67
|
+
if (isDefaultAllowed) {
|
|
68
|
+
console.log(`Connection allowed: IP ${remoteIP} is in default allowed list`);
|
|
69
|
+
}
|
|
70
|
+
else if (this.settings.sniEnabled && serverName) {
|
|
71
|
+
// For SNI connections that aren't in default list, check domain-specific rules
|
|
48
72
|
const domainConfig = findMatchingDomain(serverName);
|
|
49
73
|
if (!domainConfig) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
from.end();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
74
|
+
console.log(`Connection rejected: No matching domain config for ${serverName} from IP ${remoteIP}`);
|
|
75
|
+
from.end();
|
|
76
|
+
return;
|
|
56
77
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
from.end();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
78
|
+
if (!isAllowed(remoteIP, domainConfig.allowedIPs)) {
|
|
79
|
+
console.log(`Connection rejected: IP ${remoteIP} not allowed for domain ${serverName}`);
|
|
80
|
+
from.end();
|
|
81
|
+
return;
|
|
64
82
|
}
|
|
65
83
|
}
|
|
66
|
-
else
|
|
84
|
+
else {
|
|
85
|
+
// Non-SNI connection and not in default list
|
|
67
86
|
console.log(`Connection rejected: IP ${remoteIP} not allowed for non-SNI connection`);
|
|
68
87
|
from.end();
|
|
69
88
|
return;
|
|
@@ -72,7 +91,7 @@ export class PortProxy {
|
|
|
72
91
|
host: this.settings.toHost,
|
|
73
92
|
port: this.settings.toPort,
|
|
74
93
|
});
|
|
75
|
-
console.log(`Connection established: ${remoteIP} -> ${this.settings.toHost}:${this.settings.toPort}${
|
|
94
|
+
console.log(`Connection established: ${remoteIP} -> ${this.settings.toHost}:${this.settings.toPort}${serverName ? ` (SNI: ${serverName})` : ''}`);
|
|
76
95
|
from.setTimeout(120000);
|
|
77
96
|
from.pipe(to);
|
|
78
97
|
to.pipe(from);
|
|
@@ -100,9 +119,18 @@ export class PortProxy {
|
|
|
100
119
|
to.on('end', () => {
|
|
101
120
|
cleanUpSockets(from, to);
|
|
102
121
|
});
|
|
122
|
+
};
|
|
123
|
+
this.netServer = server
|
|
124
|
+
.on('connection', handleConnection)
|
|
125
|
+
.on('secureConnection', handleConnection)
|
|
126
|
+
.on('tlsClientError', (err, tlsSocket) => {
|
|
127
|
+
console.log(`TLS Client Error: ${err.message}`);
|
|
128
|
+
})
|
|
129
|
+
.on('error', (err) => {
|
|
130
|
+
console.log(`Server Error: ${err.message}`);
|
|
103
131
|
})
|
|
104
132
|
.listen(this.settings.fromPort);
|
|
105
|
-
console.log(`PortProxy -> OK: Now listening on port ${this.settings.fromPort}`);
|
|
133
|
+
console.log(`PortProxy -> OK: Now listening on port ${this.settings.fromPort}${this.settings.sniEnabled ? ' (SNI enabled)' : ''}`);
|
|
106
134
|
}
|
|
107
135
|
async stop() {
|
|
108
136
|
const done = plugins.smartpromise.defer();
|
|
@@ -112,4 +140,4 @@ export class PortProxy {
|
|
|
112
140
|
await done.promise;
|
|
113
141
|
}
|
|
114
142
|
}
|
|
115
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
143
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRwcm94eS5wb3J0cHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHByb3h5LnBvcnRwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHlCQUF5QixDQUFDO0FBb0JuRCxNQUFNLE9BQU8sU0FBUztJQUlwQixZQUFZLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUc7WUFDZCxHQUFHLFFBQVE7WUFDWCxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU0sSUFBSSxXQUFXO1NBQ3ZDLENBQUM7SUFDSixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUs7UUFDaEIsTUFBTSxjQUFjLEdBQUcsQ0FBQyxJQUF3QixFQUFFLEVBQXNCLEVBQUUsRUFBRTtZQUMxRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDWCxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixDQUFDLENBQUM7UUFDRixNQUFNLFdBQVcsR0FBRyxDQUFDLEVBQVUsRUFBWSxFQUFFO1lBQzNDLG9DQUFvQztZQUNwQyxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDN0IsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLDBCQUEwQjtnQkFDcEQsT0FBTyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNwQixDQUFDO1lBQ0QsMkRBQTJEO1lBQzNELElBQUksRUFBRSxDQUFD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Q0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2xKLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNkLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDZCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3RCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3BCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ2hCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU07YUFDcEIsRUFBRSxDQUFDLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQzthQUNsQyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUM7YUFDeEMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQ3ZDLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQzthQUNELEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUM7YUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDckksQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDeEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3JCLENBQUM7Q0FDRiJ9
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -67,71 +67,102 @@ export class PortProxy {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const server = this.settings.sniEnabled
|
|
70
|
-
? plugins.tls.createServer(
|
|
70
|
+
? plugins.tls.createServer({
|
|
71
|
+
...this.settings,
|
|
72
|
+
SNICallback: (serverName: string, cb: (err: Error | null, ctx?: plugins.tls.SecureContext) => void) => {
|
|
73
|
+
console.log(`SNI request for domain: ${serverName}`);
|
|
74
|
+
const domainConfig = findMatchingDomain(serverName);
|
|
75
|
+
if (!domainConfig) {
|
|
76
|
+
// Always allow SNI for default IPs, even if domain doesn't match
|
|
77
|
+
console.log(`SNI domain ${serverName} not found, will check IP during connection`);
|
|
78
|
+
}
|
|
79
|
+
// Create context with the provided TLS settings
|
|
80
|
+
const ctx = plugins.tls.createSecureContext(this.settings);
|
|
81
|
+
cb(null, ctx);
|
|
82
|
+
}
|
|
83
|
+
})
|
|
71
84
|
: plugins.net.createServer();
|
|
72
85
|
|
|
73
|
-
|
|
86
|
+
const handleConnection = (from: plugins.net.Socket | plugins.tls.TLSSocket) => {
|
|
74
87
|
const remoteIP = from.remoteAddress || '';
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
let serverName = '';
|
|
89
|
+
|
|
90
|
+
// First check if this IP is in the default allowed list
|
|
91
|
+
const isDefaultAllowed = this.settings.defaultAllowedIPs && isAllowed(remoteIP, this.settings.defaultAllowedIPs);
|
|
92
|
+
|
|
93
|
+
if (this.settings.sniEnabled && from instanceof plugins.tls.TLSSocket) {
|
|
94
|
+
serverName = (from as any).servername || '';
|
|
95
|
+
console.log(`TLS Connection from ${remoteIP} for domain: ${serverName}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// If IP is in defaultAllowedIPs, allow the connection regardless of SNI
|
|
99
|
+
if (isDefaultAllowed) {
|
|
100
|
+
console.log(`Connection allowed: IP ${remoteIP} is in default allowed list`);
|
|
101
|
+
} else if (this.settings.sniEnabled && serverName) {
|
|
102
|
+
// For SNI connections that aren't in default list, check domain-specific rules
|
|
103
|
+
const domainConfig = findMatchingDomain(serverName);
|
|
104
|
+
if (!domainConfig) {
|
|
105
|
+
console.log(`Connection rejected: No matching domain config for ${serverName} from IP ${remoteIP}`);
|
|
106
|
+
from.end();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!isAllowed(remoteIP, domainConfig.allowedIPs)) {
|
|
110
|
+
console.log(`Connection rejected: IP ${remoteIP} not allowed for domain ${serverName}`);
|
|
96
111
|
from.end();
|
|
97
112
|
return;
|
|
98
113
|
}
|
|
114
|
+
} else {
|
|
115
|
+
// Non-SNI connection and not in default list
|
|
116
|
+
console.log(`Connection rejected: IP ${remoteIP} not allowed for non-SNI connection`);
|
|
117
|
+
from.end();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const to = plugins.net.createConnection({
|
|
122
|
+
host: this.settings.toHost!,
|
|
123
|
+
port: this.settings.toPort,
|
|
124
|
+
});
|
|
125
|
+
console.log(`Connection established: ${remoteIP} -> ${this.settings.toHost}:${this.settings.toPort}${serverName ? ` (SNI: ${serverName})` : ''}`);
|
|
126
|
+
from.setTimeout(120000);
|
|
127
|
+
from.pipe(to);
|
|
128
|
+
to.pipe(from);
|
|
129
|
+
from.on('error', () => {
|
|
130
|
+
cleanUpSockets(from, to);
|
|
131
|
+
});
|
|
132
|
+
to.on('error', () => {
|
|
133
|
+
cleanUpSockets(from, to);
|
|
134
|
+
});
|
|
135
|
+
from.on('close', () => {
|
|
136
|
+
cleanUpSockets(from, to);
|
|
137
|
+
});
|
|
138
|
+
to.on('close', () => {
|
|
139
|
+
cleanUpSockets(from, to);
|
|
140
|
+
});
|
|
141
|
+
from.on('timeout', () => {
|
|
142
|
+
cleanUpSockets(from, to);
|
|
143
|
+
});
|
|
144
|
+
to.on('timeout', () => {
|
|
145
|
+
cleanUpSockets(from, to);
|
|
146
|
+
});
|
|
147
|
+
from.on('end', () => {
|
|
148
|
+
cleanUpSockets(from, to);
|
|
149
|
+
});
|
|
150
|
+
to.on('end', () => {
|
|
151
|
+
cleanUpSockets(from, to);
|
|
152
|
+
});
|
|
153
|
+
};
|
|
99
154
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
console.log(`
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
from.on('error', () => {
|
|
109
|
-
cleanUpSockets(from, to);
|
|
110
|
-
});
|
|
111
|
-
to.on('error', () => {
|
|
112
|
-
cleanUpSockets(from, to);
|
|
113
|
-
});
|
|
114
|
-
from.on('close', () => {
|
|
115
|
-
cleanUpSockets(from, to);
|
|
116
|
-
});
|
|
117
|
-
to.on('close', () => {
|
|
118
|
-
cleanUpSockets(from, to);
|
|
119
|
-
});
|
|
120
|
-
from.on('timeout', () => {
|
|
121
|
-
cleanUpSockets(from, to);
|
|
122
|
-
});
|
|
123
|
-
to.on('timeout', () => {
|
|
124
|
-
cleanUpSockets(from, to);
|
|
125
|
-
});
|
|
126
|
-
from.on('end', () => {
|
|
127
|
-
cleanUpSockets(from, to);
|
|
128
|
-
});
|
|
129
|
-
to.on('end', () => {
|
|
130
|
-
cleanUpSockets(from, to);
|
|
131
|
-
});
|
|
155
|
+
this.netServer = server
|
|
156
|
+
.on('connection', handleConnection)
|
|
157
|
+
.on('secureConnection', handleConnection)
|
|
158
|
+
.on('tlsClientError', (err, tlsSocket) => {
|
|
159
|
+
console.log(`TLS Client Error: ${err.message}`);
|
|
160
|
+
})
|
|
161
|
+
.on('error', (err) => {
|
|
162
|
+
console.log(`Server Error: ${err.message}`);
|
|
132
163
|
})
|
|
133
164
|
.listen(this.settings.fromPort);
|
|
134
|
-
console.log(`PortProxy -> OK: Now listening on port ${this.settings.fromPort}`);
|
|
165
|
+
console.log(`PortProxy -> OK: Now listening on port ${this.settings.fromPort}${this.settings.sniEnabled ? ' (SNI enabled)' : ''}`);
|
|
135
166
|
}
|
|
136
167
|
|
|
137
168
|
public async stop() {
|