bdy 1.11.0-dev → 1.12.0-dev
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.
- package/distTs/package.json +16 -5
- package/distTs/src/agent/agent.js +62 -36
- package/distTs/src/agent/linux.js +9 -4
- package/distTs/src/agent/manager.js +61 -42
- package/distTs/src/agent/osx.js +12 -5
- package/distTs/src/agent/socket/client.js +26 -7
- package/distTs/src/agent/socket/tunnel.js +56 -32
- package/distTs/src/agent/socket.js +83 -63
- package/distTs/src/agent/system.js +3 -1
- package/distTs/src/agent/windows.js +6 -6
- package/distTs/src/command/agent/install.js +4 -4
- package/distTs/src/command/agent/run.js +2 -2
- package/distTs/src/command/agent/status.js +6 -7
- package/distTs/src/command/agent/tunnel/http.js +4 -5
- package/distTs/src/command/agent/tunnel/tcp.js +3 -3
- package/distTs/src/command/agent/tunnel/tls.js +3 -3
- package/distTs/src/command/config/add/http.js +3 -3
- package/distTs/src/command/config/add/tcp.js +3 -3
- package/distTs/src/command/config/add/tls.js +3 -3
- package/distTs/src/command/config/get/region.js +1 -1
- package/distTs/src/command/pre.js +1 -1
- package/distTs/src/command/tunnel/http.js +2 -1
- package/distTs/src/command/tunnel/tcp.js +3 -3
- package/distTs/src/command/tunnel/tls.js +4 -4
- package/distTs/src/format.js +14 -15
- package/distTs/src/index.js +1 -1
- package/distTs/src/input.js +13 -12
- package/distTs/src/logger.js +12 -13
- package/distTs/src/tunnel/agent.js +3 -1
- package/distTs/src/tunnel/api/agent.js +1 -0
- package/distTs/src/tunnel/api/buddy.js +2 -0
- package/distTs/src/tunnel/cfg.js +6 -2
- package/distTs/src/tunnel/compression.js +17 -14
- package/distTs/src/tunnel/dns.js +20 -29
- package/distTs/src/tunnel/html.js +2 -0
- package/distTs/src/tunnel/http/log.js +30 -8
- package/distTs/src/tunnel/http/serve.js +3 -2
- package/distTs/src/tunnel/http/stream.js +5 -1
- package/distTs/src/tunnel/http.js +67 -26
- package/distTs/src/tunnel/identification.js +21 -14
- package/distTs/src/tunnel/latency.js +19 -11
- package/distTs/src/tunnel/output/interactive/tunnel.js +16 -9
- package/distTs/src/tunnel/output/noninteractive/agent/tunnels.js +4 -2
- package/distTs/src/tunnel/output/noninteractive/config/tunnel.js +6 -4
- package/distTs/src/tunnel/output/noninteractive/config/tunnels.js +2 -0
- package/distTs/src/tunnel/output/noninteractive/tunnel.js +13 -11
- package/distTs/src/tunnel/server/cert.js +2 -0
- package/distTs/src/tunnel/server/http1.js +15 -10
- package/distTs/src/tunnel/server/http2.js +18 -12
- package/distTs/src/tunnel/server/sftp.js +32 -15
- package/distTs/src/tunnel/server/ssh.js +49 -31
- package/distTs/src/tunnel/server/tls.js +11 -5
- package/distTs/src/tunnel/ssh/client.js +45 -31
- package/distTs/src/tunnel/tcp.js +61 -42
- package/distTs/src/tunnel/tunnel.js +196 -112
- package/distTs/src/types/tunnel.js +135 -0
- package/distTs/src/utils.js +2 -87
- package/package.json +16 -5
|
@@ -20,8 +20,62 @@ const log_1 = __importDefault(require("./http/log"));
|
|
|
20
20
|
const format_1 = __importDefault(require("../format"));
|
|
21
21
|
const texts_1 = require("../texts");
|
|
22
22
|
const dns_1 = __importDefault(require("./dns"));
|
|
23
|
+
const tunnel_1 = require("../types/tunnel");
|
|
23
24
|
class Tunnel extends events_1.default {
|
|
24
|
-
|
|
25
|
+
agent;
|
|
26
|
+
id;
|
|
27
|
+
sshHostKey;
|
|
28
|
+
type;
|
|
29
|
+
region;
|
|
30
|
+
target;
|
|
31
|
+
whitelist;
|
|
32
|
+
domain;
|
|
33
|
+
subdomain;
|
|
34
|
+
name;
|
|
35
|
+
timeout;
|
|
36
|
+
useragents;
|
|
37
|
+
headers;
|
|
38
|
+
responseHeaders;
|
|
39
|
+
terminate;
|
|
40
|
+
key;
|
|
41
|
+
cert;
|
|
42
|
+
ca;
|
|
43
|
+
host;
|
|
44
|
+
login;
|
|
45
|
+
password;
|
|
46
|
+
serve;
|
|
47
|
+
circuitBreaker;
|
|
48
|
+
log;
|
|
49
|
+
verify;
|
|
50
|
+
compression;
|
|
51
|
+
http2;
|
|
52
|
+
sshIp;
|
|
53
|
+
sshId;
|
|
54
|
+
sshPort;
|
|
55
|
+
sshUser;
|
|
56
|
+
sshPassword;
|
|
57
|
+
sshForwardPort;
|
|
58
|
+
sshClientUser;
|
|
59
|
+
sshClientPassword;
|
|
60
|
+
targetProto;
|
|
61
|
+
targetHost;
|
|
62
|
+
targetPort;
|
|
63
|
+
targetAuth;
|
|
64
|
+
totalConnections;
|
|
65
|
+
status;
|
|
66
|
+
connections;
|
|
67
|
+
dns;
|
|
68
|
+
regionLatency;
|
|
69
|
+
targetLatency;
|
|
70
|
+
tls;
|
|
71
|
+
httpLog;
|
|
72
|
+
identify;
|
|
73
|
+
http2server;
|
|
74
|
+
http1server;
|
|
75
|
+
sshServer;
|
|
76
|
+
ssh;
|
|
77
|
+
started;
|
|
78
|
+
constructor({ agent, id, type, target, region, timeout, domain, name, subdomain, whitelist, tlsSettings, httpSettings, sshSettings, sshHostKey, }) {
|
|
25
79
|
super();
|
|
26
80
|
if (!sshHostKey)
|
|
27
81
|
sshHostKey = (0, utils_1.createSshHostKey)();
|
|
@@ -34,7 +88,6 @@ class Tunnel extends events_1.default {
|
|
|
34
88
|
region,
|
|
35
89
|
timeout,
|
|
36
90
|
domain,
|
|
37
|
-
customDomain,
|
|
38
91
|
subdomain,
|
|
39
92
|
name,
|
|
40
93
|
whitelist,
|
|
@@ -43,13 +96,12 @@ class Tunnel extends events_1.default {
|
|
|
43
96
|
sshSettings,
|
|
44
97
|
});
|
|
45
98
|
}
|
|
46
|
-
create({ type, target, region, timeout, domain,
|
|
99
|
+
create({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, }) {
|
|
47
100
|
this.type = type;
|
|
48
101
|
this.region = region;
|
|
49
102
|
this.target = target;
|
|
50
103
|
this.whitelist = whitelist || [];
|
|
51
104
|
this.domain = domain;
|
|
52
|
-
this.customDomain = !!customDomain;
|
|
53
105
|
this.subdomain = subdomain;
|
|
54
106
|
this.name = name;
|
|
55
107
|
this.timeout = timeout || utils_1.DEFAULT_TIMEOUT;
|
|
@@ -91,7 +143,7 @@ class Tunnel extends events_1.default {
|
|
|
91
143
|
this.targetHost = 'localhost';
|
|
92
144
|
this.targetPort = 80;
|
|
93
145
|
this.targetAuth = null;
|
|
94
|
-
if (this.type ===
|
|
146
|
+
if (this.type === tunnel_1.TUNNEL_TYPE.HTTP) {
|
|
95
147
|
let m = this.target.match(utils_1.TARGET_ONLY_PORT_REGEX);
|
|
96
148
|
if (m) {
|
|
97
149
|
this.targetPort = parseInt(m[0], 10);
|
|
@@ -112,7 +164,7 @@ class Tunnel extends events_1.default {
|
|
|
112
164
|
}
|
|
113
165
|
}
|
|
114
166
|
}
|
|
115
|
-
else if (this.type ===
|
|
167
|
+
else if (this.type === tunnel_1.TUNNEL_TYPE.SSH) {
|
|
116
168
|
this.targetHost = 'localhost';
|
|
117
169
|
this.targetProto = 'ssh://';
|
|
118
170
|
this.targetPort = 22;
|
|
@@ -127,7 +179,7 @@ class Tunnel extends events_1.default {
|
|
|
127
179
|
}
|
|
128
180
|
this.connections = {};
|
|
129
181
|
this.totalConnections = 0;
|
|
130
|
-
this.status =
|
|
182
|
+
this.status = tunnel_1.TUNNEL_STATUS.CLOSED;
|
|
131
183
|
this.dns = null;
|
|
132
184
|
this.regionLatency = null;
|
|
133
185
|
this.targetLatency = null;
|
|
@@ -140,7 +192,7 @@ class Tunnel extends events_1.default {
|
|
|
140
192
|
this.ssh = null;
|
|
141
193
|
this.started = false;
|
|
142
194
|
}
|
|
143
|
-
recreate({ type, target, region, timeout, domain,
|
|
195
|
+
recreate({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, }) {
|
|
144
196
|
const started = this.started;
|
|
145
197
|
this.stop(false);
|
|
146
198
|
this.create({
|
|
@@ -149,7 +201,6 @@ class Tunnel extends events_1.default {
|
|
|
149
201
|
region,
|
|
150
202
|
timeout,
|
|
151
203
|
domain,
|
|
152
|
-
customDomain,
|
|
153
204
|
subdomain,
|
|
154
205
|
name,
|
|
155
206
|
whitelist,
|
|
@@ -219,94 +270,116 @@ class Tunnel extends events_1.default {
|
|
|
219
270
|
return true;
|
|
220
271
|
if (this.sshClientUser !== tunnel.sshClientUser)
|
|
221
272
|
return true;
|
|
222
|
-
if (this.whitelist
|
|
273
|
+
if (this.whitelist?.length !== tunnel.whitelist?.length)
|
|
223
274
|
return true;
|
|
224
|
-
this.whitelist.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
275
|
+
if (this.whitelist && tunnel.whitelist) {
|
|
276
|
+
this.whitelist.sort();
|
|
277
|
+
tunnel.whitelist.sort();
|
|
278
|
+
for (let i = 0; i < this.whitelist.length; i += 1) {
|
|
279
|
+
if (this.whitelist[i] !== tunnel.whitelist[i])
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
229
282
|
}
|
|
230
|
-
if (this.useragents
|
|
283
|
+
if (this.useragents?.length !== tunnel.useragents?.length)
|
|
231
284
|
return true;
|
|
232
|
-
this.useragents.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
285
|
+
if (this.useragents && tunnel.useragents) {
|
|
286
|
+
this.useragents.sort();
|
|
287
|
+
tunnel.useragents.sort();
|
|
288
|
+
for (let i = 0; i < this.useragents.length; i += 1) {
|
|
289
|
+
if (this.useragents[i] !== tunnel.useragents[i])
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
237
292
|
}
|
|
238
293
|
const sortHeaders = (a, b) => a.name.localeCompare(b.name);
|
|
239
|
-
if (this.headers
|
|
240
|
-
return true;
|
|
241
|
-
this.headers.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.responseHeaders.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
294
|
+
if (this.headers?.length !== tunnel.headers?.length)
|
|
295
|
+
return true;
|
|
296
|
+
if (this.headers && tunnel.headers) {
|
|
297
|
+
this.headers.sort(sortHeaders);
|
|
298
|
+
tunnel.headers.sort(sortHeaders);
|
|
299
|
+
for (let i = 0; i < this.headers.length; i += 1) {
|
|
300
|
+
const thisH = this.headers[i];
|
|
301
|
+
const tunnelH = tunnel.headers[i];
|
|
302
|
+
if (thisH.name !== tunnelH.name)
|
|
303
|
+
return true;
|
|
304
|
+
if (thisH.value !== tunnelH.value)
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (this.responseHeaders?.length !== tunnel.responseHeaders?.length)
|
|
309
|
+
return true;
|
|
310
|
+
if (this.responseHeaders && tunnel.responseHeaders) {
|
|
311
|
+
this.responseHeaders.sort(sortHeaders);
|
|
312
|
+
tunnel.responseHeaders.sort(sortHeaders);
|
|
313
|
+
for (let i = 0; i < this.responseHeaders.length; i += 1) {
|
|
314
|
+
const thisRH = this.responseHeaders[i];
|
|
315
|
+
const tunnelRH = tunnel.responseHeaders[i];
|
|
316
|
+
if (thisRH.name !== tunnelRH.name)
|
|
317
|
+
return true;
|
|
318
|
+
if (thisRH.value !== tunnelRH.value)
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
262
321
|
}
|
|
263
322
|
return false;
|
|
264
323
|
}
|
|
265
324
|
async sshConnected() {
|
|
266
325
|
try {
|
|
267
326
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_CONNECTED)(this.id, this.sshForwardPort));
|
|
268
|
-
|
|
269
|
-
|
|
327
|
+
if (this.ssh && this.sshForwardPort)
|
|
328
|
+
await this.ssh.forwardIn(this.sshForwardPort);
|
|
329
|
+
this.status = tunnel_1.TUNNEL_STATUS.OPEN;
|
|
270
330
|
}
|
|
271
331
|
catch (err) {
|
|
272
332
|
// reconnect
|
|
273
333
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_FAILED)(this.id));
|
|
274
334
|
logger_1.default.debug(err);
|
|
275
|
-
this.ssh
|
|
335
|
+
if (this.ssh)
|
|
336
|
+
this.ssh.close();
|
|
276
337
|
return;
|
|
277
338
|
}
|
|
278
|
-
this.emit(
|
|
339
|
+
this.emit(tunnel_1.TUNNEL_EVENT.OPEN, this);
|
|
279
340
|
}
|
|
280
341
|
sshDisconnected() {
|
|
281
|
-
if (this.status !==
|
|
342
|
+
if (this.status !== tunnel_1.TUNNEL_STATUS.CLOSED) {
|
|
282
343
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_DISCONNECTED)(this.id));
|
|
283
|
-
this.status =
|
|
284
|
-
this.emit(
|
|
344
|
+
this.status = tunnel_1.TUNNEL_STATUS.CLOSED;
|
|
345
|
+
this.emit(tunnel_1.TUNNEL_EVENT.CLOSED, this);
|
|
285
346
|
}
|
|
286
347
|
}
|
|
287
348
|
tunnelToTarget(stream, onClose) {
|
|
349
|
+
if (!this.totalConnections)
|
|
350
|
+
this.totalConnections = 0;
|
|
288
351
|
this.totalConnections += 1;
|
|
289
|
-
const tcp = new tcp_1.default(this.targetHost, this.targetPort, stream);
|
|
352
|
+
const tcp = new tcp_1.default(this.targetHost || '', this.targetPort || 0, stream);
|
|
353
|
+
if (!this.connections)
|
|
354
|
+
this.connections = {};
|
|
290
355
|
this.connections[tcp.id] = tcp;
|
|
291
|
-
tcp.on(
|
|
292
|
-
this.connections[tcp.id]
|
|
293
|
-
|
|
356
|
+
tcp.on(tunnel_1.TUNNEL_EVENT_TCP.CLOSED, () => {
|
|
357
|
+
if (this.connections && this.connections[tcp.id]) {
|
|
358
|
+
this.connections[tcp.id].removeAllListeners();
|
|
359
|
+
delete this.connections[tcp.id];
|
|
360
|
+
}
|
|
294
361
|
onClose();
|
|
295
362
|
});
|
|
296
363
|
tcp.pipe();
|
|
297
364
|
}
|
|
298
365
|
httpIdentified(type) {
|
|
299
366
|
logger_1.default.info((0, texts_1.LOG_TUNNEL_IDENTIFIED)(this.id, type));
|
|
300
|
-
this.emit(
|
|
367
|
+
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_IDENTIFIED, this, type);
|
|
301
368
|
}
|
|
302
369
|
httpConnectionOpen(s) {
|
|
370
|
+
if (!this.totalConnections)
|
|
371
|
+
this.totalConnections = 0;
|
|
372
|
+
if (!this.connections)
|
|
373
|
+
this.connections = {};
|
|
303
374
|
this.totalConnections += 1;
|
|
304
375
|
this.connections[s.id] = s;
|
|
305
|
-
this.emit(
|
|
376
|
+
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_OPEN, this);
|
|
306
377
|
}
|
|
307
378
|
httpConnectionClosed(s) {
|
|
308
|
-
|
|
309
|
-
|
|
379
|
+
if (this.connections && this.connections[s.id]) {
|
|
380
|
+
delete this.connections[s.id];
|
|
381
|
+
}
|
|
382
|
+
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_CLOSED, this);
|
|
310
383
|
}
|
|
311
384
|
httpBasicAuth(req, res) {
|
|
312
385
|
if (this.login || this.password) {
|
|
@@ -322,9 +395,13 @@ class Tunnel extends events_1.default {
|
|
|
322
395
|
return true;
|
|
323
396
|
}
|
|
324
397
|
httpEndFast(req, res, statusCode, msg, headers = {}) {
|
|
325
|
-
|
|
398
|
+
let log;
|
|
399
|
+
if (this.httpLog) {
|
|
400
|
+
log = this.httpLog.newRequest(req.method, req.headers, req.url, req.httpVersion, req);
|
|
401
|
+
}
|
|
326
402
|
if (!log) {
|
|
327
|
-
this.httpLog
|
|
403
|
+
if (this.httpLog)
|
|
404
|
+
this.httpLog.newResponse(statusCode, headers);
|
|
328
405
|
res.statusCode = statusCode;
|
|
329
406
|
Object.keys(headers).forEach((k) => {
|
|
330
407
|
res.setHeader(k, headers[k]);
|
|
@@ -334,7 +411,8 @@ class Tunnel extends events_1.default {
|
|
|
334
411
|
else {
|
|
335
412
|
req.pipe(log.requestBody);
|
|
336
413
|
log.requestBody.pipeToNothing(() => {
|
|
337
|
-
this.httpLog
|
|
414
|
+
if (this.httpLog)
|
|
415
|
+
this.httpLog.newResponse(statusCode, headers, log);
|
|
338
416
|
res.statusCode = statusCode;
|
|
339
417
|
Object.keys(headers).forEach((k) => {
|
|
340
418
|
res.setHeader(k, headers[k]);
|
|
@@ -344,7 +422,7 @@ class Tunnel extends events_1.default {
|
|
|
344
422
|
}
|
|
345
423
|
}
|
|
346
424
|
httpRateLimit(req, res) {
|
|
347
|
-
const isRateLimited = this.httpLog.isRateLimited(req);
|
|
425
|
+
const isRateLimited = !!this.httpLog && this.httpLog.isRateLimited(req);
|
|
348
426
|
if (isRateLimited) {
|
|
349
427
|
logger_1.default.debug(texts_1.LOG_TUNNEL_HTTP_RATE_LIMIT);
|
|
350
428
|
this.httpEndFast(req, res, 429, 'Too Many Requests', {
|
|
@@ -355,7 +433,7 @@ class Tunnel extends events_1.default {
|
|
|
355
433
|
return true;
|
|
356
434
|
}
|
|
357
435
|
httpCircuitBreaker(req, res) {
|
|
358
|
-
const isOpen = this.httpLog.isCircuitBreakerOpen();
|
|
436
|
+
const isOpen = !!this.httpLog && this.httpLog.isCircuitBreakerOpen();
|
|
359
437
|
if (isOpen) {
|
|
360
438
|
logger_1.default.debug(texts_1.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN);
|
|
361
439
|
this.httpEndFast(req, res, 504, 'Service Unavailable', {});
|
|
@@ -393,17 +471,21 @@ class Tunnel extends events_1.default {
|
|
|
393
471
|
this.identify.identify();
|
|
394
472
|
}
|
|
395
473
|
httpLogRequest(logRequest) {
|
|
396
|
-
this.emit(
|
|
474
|
+
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, this, logRequest);
|
|
397
475
|
}
|
|
398
476
|
httpLogResponse(logRequest) {
|
|
399
|
-
this.emit(
|
|
477
|
+
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_RESPONSE, this, logRequest);
|
|
400
478
|
}
|
|
401
479
|
retryHttpLogRequest(logRequest) {
|
|
402
480
|
if (logRequest.requestBody.tooLarge)
|
|
403
481
|
return;
|
|
404
|
-
if (logRequest.httpVersion === '2.0')
|
|
405
|
-
|
|
406
|
-
|
|
482
|
+
if (logRequest.httpVersion === '2.0') {
|
|
483
|
+
if (this.http2server)
|
|
484
|
+
return this.http2server.retryRequest(logRequest);
|
|
485
|
+
}
|
|
486
|
+
if (this.http1server) {
|
|
487
|
+
return this.http1server.retryRequest(logRequest);
|
|
488
|
+
}
|
|
407
489
|
}
|
|
408
490
|
httpRequest(req, res) {
|
|
409
491
|
const isAuth = this.httpBasicAuth(req, res) &&
|
|
@@ -426,32 +508,33 @@ class Tunnel extends events_1.default {
|
|
|
426
508
|
headers: this.headers,
|
|
427
509
|
serve: this.serve,
|
|
428
510
|
responseHeaders: this.responseHeaders,
|
|
429
|
-
httpIdentify: this.identify
|
|
511
|
+
httpIdentify: this.identify?.type,
|
|
430
512
|
httpLog: this.httpLog,
|
|
431
513
|
});
|
|
432
|
-
http.once(
|
|
514
|
+
http.once(tunnel_1.TUNNEL_HTTP_SOCKET.CLOSED, (socket) => this.httpConnectionClosed(socket));
|
|
433
515
|
http.pipe().then();
|
|
434
516
|
}
|
|
435
517
|
tlsSocket(tlsSocket) {
|
|
436
518
|
this.tunnelToTarget(tlsSocket, () => {
|
|
437
|
-
this.emit(
|
|
519
|
+
this.emit(tunnel_1.TUNNEL_EVENT.TLS_CLOSED, this);
|
|
438
520
|
});
|
|
439
|
-
this.emit(
|
|
521
|
+
this.emit(tunnel_1.TUNNEL_EVENT.TLS_OPEN, this);
|
|
440
522
|
}
|
|
441
523
|
canStreamTcp() {
|
|
442
|
-
if (this.type ===
|
|
524
|
+
if (this.type === tunnel_1.TUNNEL_TYPE.TCP)
|
|
443
525
|
return true;
|
|
444
|
-
return (this.type ===
|
|
445
|
-
|
|
526
|
+
return (this.type === tunnel_1.TUNNEL_TYPE.TLS &&
|
|
527
|
+
this.terminate &&
|
|
528
|
+
[tunnel_1.TUNNEL_TERMINATE_AT.REGION, tunnel_1.TUNNEL_TERMINATE_AT.TARGET].includes(this.terminate));
|
|
446
529
|
}
|
|
447
530
|
canStreamTls() {
|
|
448
|
-
return this.type ===
|
|
531
|
+
return this.type === tunnel_1.TUNNEL_TYPE.TLS;
|
|
449
532
|
}
|
|
450
533
|
canStreamSsh() {
|
|
451
|
-
return this.type ===
|
|
534
|
+
return this.type === tunnel_1.TUNNEL_TYPE.SSH;
|
|
452
535
|
}
|
|
453
536
|
canStreamHttp() {
|
|
454
|
-
return this.type ===
|
|
537
|
+
return this.type === tunnel_1.TUNNEL_TYPE.HTTP;
|
|
455
538
|
}
|
|
456
539
|
safeEndStream(stream) {
|
|
457
540
|
try {
|
|
@@ -478,9 +561,9 @@ class Tunnel extends events_1.default {
|
|
|
478
561
|
}
|
|
479
562
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_TCP_STREAM)(this.id));
|
|
480
563
|
this.tunnelToTarget(stream, () => {
|
|
481
|
-
this.emit(
|
|
564
|
+
this.emit(tunnel_1.TUNNEL_EVENT.TCP_CLOSED, this);
|
|
482
565
|
});
|
|
483
|
-
this.emit(
|
|
566
|
+
this.emit(tunnel_1.TUNNEL_EVENT.TCP_OPEN, this);
|
|
484
567
|
}
|
|
485
568
|
sshStreamHttp1(stream, info, ip) {
|
|
486
569
|
if (!this.canStreamHttp()) {
|
|
@@ -523,12 +606,12 @@ class Tunnel extends events_1.default {
|
|
|
523
606
|
this.safeEndStream(stream);
|
|
524
607
|
return;
|
|
525
608
|
}
|
|
526
|
-
if (this.terminate ===
|
|
609
|
+
if (this.terminate === tunnel_1.TUNNEL_TERMINATE_AT.TARGET) {
|
|
527
610
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_TLS_TARGET_STREAM)(this.id));
|
|
528
611
|
this.sshStreamTcp(stream);
|
|
529
612
|
return;
|
|
530
613
|
}
|
|
531
|
-
if (this.terminate ===
|
|
614
|
+
if (this.terminate === tunnel_1.TUNNEL_TERMINATE_AT.REGION) {
|
|
532
615
|
logger_1.default.debug((0, texts_1.LOG_TUNNEL_TLS_REGION_STREAM)(this.id));
|
|
533
616
|
this.sshStreamTcp(stream);
|
|
534
617
|
return;
|
|
@@ -541,7 +624,7 @@ class Tunnel extends events_1.default {
|
|
|
541
624
|
this.safeEndStream(stream);
|
|
542
625
|
}
|
|
543
626
|
start() {
|
|
544
|
-
if (this.started)
|
|
627
|
+
if (this.started || !this.sshIp || !this.sshPort || !this.domain || !this.subdomain || !this.region || !this.sshId || !this.sshUser || !this.sshPassword)
|
|
545
628
|
return;
|
|
546
629
|
this.started = true;
|
|
547
630
|
logger_1.default.info((0, texts_1.LOG_STARTING_TUNNEL)(this.id));
|
|
@@ -549,49 +632,50 @@ class Tunnel extends events_1.default {
|
|
|
549
632
|
this.regionLatency = new latency_1.default(this.sshIp, this.sshPort);
|
|
550
633
|
this.regionLatency.startChecking();
|
|
551
634
|
// target latency
|
|
552
|
-
if (!this.serve && this.type !==
|
|
553
|
-
this.targetLatency = new latency_1.default(this.targetHost, this.targetPort);
|
|
554
|
-
this.targetLatency.on(
|
|
635
|
+
if (!this.serve && this.type !== tunnel_1.TUNNEL_TYPE.SSH) {
|
|
636
|
+
this.targetLatency = new latency_1.default(this.targetHost || '', this.targetPort || 0);
|
|
637
|
+
this.targetLatency.on(tunnel_1.TUNNEL_EVENT_LATENCY.RECONNECTED, () => this.targetReconnected());
|
|
555
638
|
this.targetLatency.startChecking();
|
|
556
639
|
}
|
|
557
640
|
// dns health
|
|
558
|
-
this.dns = new dns_1.default(this.sshIp, this.domain, this.
|
|
641
|
+
this.dns = new dns_1.default(this.sshIp, this.domain, this.subdomain, this.region, this.sshId);
|
|
559
642
|
this.dns.startChecking();
|
|
560
|
-
if (this.type ===
|
|
643
|
+
if (this.type === tunnel_1.TUNNEL_TYPE.TLS &&
|
|
644
|
+
this.terminate === tunnel_1.TUNNEL_TERMINATE_AT.AGENT) {
|
|
561
645
|
// tls
|
|
562
646
|
this.tls = new tls_1.default(this.key, this.cert, this.ca);
|
|
563
|
-
this.tls.on(
|
|
647
|
+
this.tls.on(tunnel_1.TUNNEL_EVENT.TLS_SOCKET, (socket) => this.tlsSocket(socket));
|
|
564
648
|
}
|
|
565
|
-
else if (this.type ===
|
|
649
|
+
else if (this.type === tunnel_1.TUNNEL_TYPE.HTTP) {
|
|
566
650
|
// http
|
|
567
651
|
this.httpLog = new log_1.default(this.log, this.circuitBreaker);
|
|
568
|
-
this.httpLog.on(
|
|
569
|
-
this.httpLog.on(
|
|
570
|
-
this.identify = new identification_1.default(this.targetProto, this.targetHost, this.targetPort, this.http2 || !!this.serve);
|
|
571
|
-
this.identify.on(
|
|
652
|
+
this.httpLog.on(tunnel_1.TUNNEL_EVENT_HTTP.NEW_REQUEST, (logRequest) => this.httpLogRequest(logRequest));
|
|
653
|
+
this.httpLog.on(tunnel_1.TUNNEL_EVENT_HTTP.NEW_RESPONSE, (logRequest) => this.httpLogResponse(logRequest));
|
|
654
|
+
this.identify = new identification_1.default(this.targetProto || '', this.targetHost || '', this.targetPort || 0, this.http2 || !!this.serve);
|
|
655
|
+
this.identify.on(tunnel_1.TUNNEL_EVENT.IDENTIFIED, (type) => this.httpIdentified(type));
|
|
572
656
|
const host = format_1.default.entryHostEncoded(this);
|
|
573
657
|
this.http2server = new http2_1.default(host);
|
|
574
|
-
this.http2server.on(
|
|
575
|
-
this.http2server.on(
|
|
576
|
-
this.http2server.on(
|
|
658
|
+
this.http2server.on(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_OPEN, (session) => this.httpConnectionOpen(session));
|
|
659
|
+
this.http2server.on(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_CLOSED, (session) => this.httpConnectionClosed(session));
|
|
660
|
+
this.http2server.on(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, (req, res) => this.httpRequest(req, res));
|
|
577
661
|
this.http1server = new http1_1.default(host);
|
|
578
|
-
this.http1server.on(
|
|
579
|
-
this.http1server.on(
|
|
580
|
-
this.http1server.on(
|
|
662
|
+
this.http1server.on(tunnel_1.TUNNEL_HTTP_SOCKET.OPEN, (socket) => this.httpConnectionOpen(socket));
|
|
663
|
+
this.http1server.on(tunnel_1.TUNNEL_HTTP_SOCKET.CLOSED, (socket) => this.httpConnectionClosed(socket));
|
|
664
|
+
this.http1server.on(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, (req, res) => this.httpRequest(req, res));
|
|
581
665
|
}
|
|
582
|
-
else if (this.type ===
|
|
666
|
+
else if (this.type === tunnel_1.TUNNEL_TYPE.SSH) {
|
|
583
667
|
// ssh server
|
|
584
|
-
this.sshServer = new ssh_1.default(this.agent, this.sshClientUser, this.sshClientPassword, this.sshHostKey);
|
|
668
|
+
this.sshServer = new ssh_1.default(this.agent, this.sshClientUser || '', this.sshClientPassword || '', this.sshHostKey);
|
|
585
669
|
}
|
|
586
670
|
// ssh
|
|
587
671
|
this.ssh = new client_1.default(this.sshIp, this.sshPort, this.sshUser, this.sshPassword);
|
|
588
|
-
this.ssh.on(
|
|
589
|
-
this.ssh.on(
|
|
590
|
-
this.ssh.on(
|
|
591
|
-
this.ssh.on(
|
|
592
|
-
this.ssh.on(
|
|
593
|
-
this.ssh.on(
|
|
594
|
-
this.ssh.on(
|
|
672
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.CONNECTED, () => this.sshConnected());
|
|
673
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.DISCONNECTED, () => this.sshDisconnected());
|
|
674
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.STREAM_TCP, (stream) => this.sshStreamTcp(stream));
|
|
675
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.STREAM_TLS, (stream) => this.sshStreamTls(stream));
|
|
676
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP1, (stream, info, ip) => this.sshStreamHttp1(stream, info, ip));
|
|
677
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP2, (stream, info, ip) => this.sshStreamHttp2(stream, info, ip));
|
|
678
|
+
this.ssh.on(tunnel_1.TUNNEL_SSH_EVENT.STREAM_SSH, (stream) => this.sshStreamSsh(stream));
|
|
595
679
|
this.ssh.openKeepAlive();
|
|
596
680
|
}
|
|
597
681
|
stop(emitEvent = true) {
|
|
@@ -600,7 +684,7 @@ class Tunnel extends events_1.default {
|
|
|
600
684
|
this.started = false;
|
|
601
685
|
logger_1.default.info((0, texts_1.LOG_STOPPING_TUNNEL)(this.id));
|
|
602
686
|
if (emitEvent)
|
|
603
|
-
this.emit(
|
|
687
|
+
this.emit(tunnel_1.TUNNEL_EVENT.STOPPED, this);
|
|
604
688
|
if (this.regionLatency) {
|
|
605
689
|
this.regionLatency.removeAllListeners();
|
|
606
690
|
this.regionLatency.stopChecking();
|
|
@@ -650,7 +734,7 @@ class Tunnel extends events_1.default {
|
|
|
650
734
|
this.ssh.closeKeepAlive();
|
|
651
735
|
this.ssh = null;
|
|
652
736
|
}
|
|
653
|
-
this.status =
|
|
737
|
+
this.status = tunnel_1.TUNNEL_STATUS.CLOSED;
|
|
654
738
|
}
|
|
655
739
|
}
|
|
656
740
|
exports.default = Tunnel;
|