querysub 0.85.0 → 0.87.0
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/package.json
CHANGED
|
@@ -2,6 +2,8 @@ import debugbreak from "debugbreak";
|
|
|
2
2
|
import * as net from "net";
|
|
3
3
|
import ws from "ws";
|
|
4
4
|
import child_process from "child_process";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
5
7
|
|
|
6
8
|
// Expose the internal port, via a tcp connection that we forward to internal port, for the first time
|
|
7
9
|
// externalIP connects to us.
|
|
@@ -18,20 +20,35 @@ export async function hackDevtoolsWebsocketForward(config: {
|
|
|
18
20
|
cancel: () => void;
|
|
19
21
|
}> {
|
|
20
22
|
const forwardCode = ((configInner: typeof config) => {
|
|
21
|
-
const net = require("net");
|
|
23
|
+
const net = require("net") as typeof import("net");
|
|
24
|
+
const fs = require("fs") as typeof import("fs");
|
|
25
|
+
const path = require("path") as typeof import("path");
|
|
22
26
|
const server = net.createServer();
|
|
23
27
|
|
|
28
|
+
const debugFile = path.join(process.env.USERPROFILE || process.env.HOME || "", "debug.temp");
|
|
29
|
+
//fs.writeFileSync(debugFile, "");
|
|
30
|
+
const logPacket = (message: string, data?: Buffer) => {
|
|
31
|
+
// const timestamp = new Date().toISOString();
|
|
32
|
+
// fs.appendFileSync(
|
|
33
|
+
// debugFile,
|
|
34
|
+
// `${timestamp} ${message} ${data?.length}\n`
|
|
35
|
+
// );
|
|
36
|
+
};
|
|
37
|
+
|
|
24
38
|
// Start listening on a random available port, binding to all interfaces (0.0.0.0)
|
|
25
39
|
server.listen(0, "0.0.0.0");
|
|
26
40
|
|
|
27
|
-
server.on("connection", (socket
|
|
41
|
+
server.on("connection", (socket) => {
|
|
28
42
|
const clientIP = socket.remoteAddress;
|
|
29
43
|
|
|
44
|
+
|
|
30
45
|
if (clientIP !== configInner.externalIP) {
|
|
46
|
+
logPacket(`Rejected connection attempt from unauthorized IP: ${clientIP}`);
|
|
31
47
|
console.error(`Rejected connection attempt from unauthorized IP: ${clientIP}`);
|
|
32
48
|
socket.destroy();
|
|
33
49
|
return;
|
|
34
50
|
}
|
|
51
|
+
logPacket(`Accepted connection from ${clientIP}`);
|
|
35
52
|
|
|
36
53
|
const address = server.address();
|
|
37
54
|
if (!address || typeof address === "string") {
|
|
@@ -46,6 +63,7 @@ export async function hackDevtoolsWebsocketForward(config: {
|
|
|
46
63
|
port: configInner.internalPort,
|
|
47
64
|
});
|
|
48
65
|
internalConnection.on("data", (data: Buffer) => {
|
|
66
|
+
logPacket("SENT", data);
|
|
49
67
|
socket.write(data);
|
|
50
68
|
});
|
|
51
69
|
let first = true;
|
|
@@ -57,12 +75,14 @@ export async function hackDevtoolsWebsocketForward(config: {
|
|
|
57
75
|
lines[1] = `Host: 127.0.0.1:${configInner.internalPort}`;
|
|
58
76
|
data = Buffer.from(lines.join("\r\n"));
|
|
59
77
|
}
|
|
78
|
+
logPacket("RECEIVED", data);
|
|
60
79
|
internalConnection.write(data);
|
|
61
80
|
});
|
|
62
81
|
|
|
63
82
|
// Handle socket closure
|
|
64
83
|
socket.on("close", () => {
|
|
65
84
|
internalConnection.destroy();
|
|
85
|
+
logPacket("SENT");
|
|
66
86
|
// IMPORTANT! We terminate when the connection is closed, which is what makes this safe.
|
|
67
87
|
process.exit();
|
|
68
88
|
});
|
|
@@ -37,6 +37,7 @@ import { SocketRegistered } from "socket-function/SocketFunctionTypes";
|
|
|
37
37
|
import { ATag } from "../library-components/ATag";
|
|
38
38
|
import { filterURL, selectedNodeId } from "./logs/DiskLoggerPage";
|
|
39
39
|
import { getSyncedController } from "../library-components/SyncedController";
|
|
40
|
+
import child_process from "child_process";
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
type NodeData = {
|
|
@@ -348,60 +349,117 @@ class NodeViewerControllerBase {
|
|
|
348
349
|
let ourIP = await getExternalIP();
|
|
349
350
|
let { externalPort, internalPort, internalInspectURL } = await NodeCapabilitiesController.nodes[nodeId].exposeExternalDebugPortOnce(ourIP);
|
|
350
351
|
|
|
351
|
-
|
|
352
|
-
|
|
352
|
+
const forwardCode = ((config: {
|
|
353
|
+
callerIP: string;
|
|
354
|
+
ourIP: string;
|
|
355
|
+
externalPort: number;
|
|
356
|
+
internalPort: number;
|
|
357
|
+
baseNodeIP: string;
|
|
358
|
+
cert: { key: string; cert: string; };
|
|
359
|
+
}) => {
|
|
360
|
+
const tls = require("tls") as typeof import("tls");
|
|
361
|
+
const net = require("net") as typeof import("net");
|
|
362
|
+
const dns = require("dns") as typeof import("dns");
|
|
363
|
+
|
|
364
|
+
(async () => {
|
|
365
|
+
let baseNodeIPResolved = (await dns.promises.lookup(config.baseNodeIP)).address;
|
|
366
|
+
|
|
367
|
+
let tlsServer = new tls.Server({
|
|
368
|
+
key: config.cert.key,
|
|
369
|
+
cert: config.cert.cert,
|
|
370
|
+
});
|
|
371
|
+
tlsServer.listen(0, "0.0.0.0");
|
|
372
|
+
await new Promise((resolve, reject) => {
|
|
373
|
+
tlsServer.once("listening", resolve);
|
|
374
|
+
tlsServer.once("error", reject);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
let finalPort = (tlsServer.address() as any).port;
|
|
378
|
+
console.log(`EXTERNAL_PORT:${finalPort}`);
|
|
379
|
+
|
|
380
|
+
tlsServer.on("secureConnection", (socket) => {
|
|
381
|
+
let matchedIP = (
|
|
382
|
+
socket.remoteAddress === config.callerIP ||
|
|
383
|
+
config.callerIP === "127.0.0.1" && socket.remoteAddress === config.ourIP
|
|
384
|
+
);
|
|
385
|
+
if (!matchedIP) {
|
|
386
|
+
console.error(`Rejecting connection from ${socket.remoteAddress}, expected ${config.callerIP} ${config.callerIP === "127.0.0.1" && `or ${config.ourIP}` || ""}`);
|
|
387
|
+
socket.end();
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
353
390
|
|
|
354
|
-
|
|
355
|
-
|
|
391
|
+
let internalConnection = net.createConnection({
|
|
392
|
+
host: baseNodeIPResolved,
|
|
393
|
+
port: config.externalPort,
|
|
394
|
+
});
|
|
395
|
+
socket.pipe(internalConnection);
|
|
396
|
+
internalConnection.pipe(socket);
|
|
356
397
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
398
|
+
socket.on("close", () => {
|
|
399
|
+
console.log("Inspect closing forward (socket closed)");
|
|
400
|
+
tlsServer.close();
|
|
401
|
+
process.exit();
|
|
402
|
+
});
|
|
403
|
+
internalConnection.on("close", () => {
|
|
404
|
+
console.log("Inspect closing forward (internal connection closed)");
|
|
405
|
+
tlsServer.close();
|
|
406
|
+
process.exit();
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
})().catch(e => {
|
|
410
|
+
console.error(e);
|
|
411
|
+
process.exit(1);
|
|
412
|
+
});
|
|
365
413
|
});
|
|
366
414
|
|
|
367
|
-
let
|
|
415
|
+
let baseNodeIP = getNodeIdIP(nodeId);
|
|
416
|
+
let cert = await debugGetRawEdgeCert();
|
|
368
417
|
|
|
369
|
-
|
|
370
|
-
|
|
418
|
+
const child = child_process.spawn("node", [
|
|
419
|
+
"-e",
|
|
420
|
+
`(${forwardCode.toString()})(${JSON.stringify({
|
|
421
|
+
callerIP,
|
|
422
|
+
ourIP,
|
|
423
|
+
externalPort,
|
|
424
|
+
internalPort,
|
|
425
|
+
baseNodeIP,
|
|
426
|
+
cert,
|
|
427
|
+
})})`,
|
|
428
|
+
]);
|
|
429
|
+
|
|
430
|
+
let portPromiseResolve: ((port: number) => void) | undefined;
|
|
431
|
+
const portPromise = new Promise<number>((resolve) => {
|
|
432
|
+
portPromiseResolve = resolve;
|
|
433
|
+
});
|
|
371
434
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
);
|
|
377
|
-
if (
|
|
378
|
-
|
|
379
|
-
socket.end();
|
|
380
|
-
return;
|
|
435
|
+
let curData = "";
|
|
436
|
+
child.stdout.on("data", (data) => {
|
|
437
|
+
console.log(data.toString());
|
|
438
|
+
curData += data.toString();
|
|
439
|
+
const match = curData.match(/EXTERNAL_PORT:(\d+)/);
|
|
440
|
+
if (match && portPromiseResolve) {
|
|
441
|
+
portPromiseResolve(parseInt(match[1], 10));
|
|
381
442
|
}
|
|
443
|
+
});
|
|
382
444
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
});
|
|
387
|
-
socket.pipe(internalConnection);
|
|
388
|
-
internalConnection.pipe(socket);
|
|
445
|
+
child.stderr.on("data", (data) => {
|
|
446
|
+
console.error(data.toString());
|
|
447
|
+
});
|
|
389
448
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
});
|
|
394
|
-
internalConnection.on("close", () => {
|
|
395
|
-
console.log(`Inspect closing forward (internal connection closed) ${ourDomain}:${finalPort} => ${baseNodeIPResolved}:${externalPort} => 127.0.0.1:${internalPort}, for ${callerIP}`);
|
|
396
|
-
tlsServer.close();
|
|
397
|
-
});
|
|
449
|
+
child.on("error", (err) => {
|
|
450
|
+
console.error("Failed to start child process:", err);
|
|
451
|
+
throw err;
|
|
398
452
|
});
|
|
399
453
|
|
|
454
|
+
let finalPort = await portPromise;
|
|
455
|
+
await forwardPort({ internalPort: finalPort, externalPort: finalPort });
|
|
456
|
+
await forwardPort({ internalPort: externalPort, externalPort: externalPort });
|
|
457
|
+
|
|
400
458
|
// Ugh... what a nightmare...
|
|
401
459
|
let ourDomain = ourIP.replaceAll(".", "-") + "." + getDomain();
|
|
402
460
|
await setRecord("A", ourDomain, ourIP);
|
|
403
461
|
|
|
404
|
-
console.log(`Inspect forward ${ourDomain}:${finalPort} => ${
|
|
462
|
+
console.log(`Inspect forward ${ourDomain}:${finalPort} => ${baseNodeIP}:${externalPort} => 127.0.0.1:${internalPort}, for ${callerIP}`);
|
|
405
463
|
|
|
406
464
|
return internalInspectURL.replace(`ws=127.0.0.1:${internalPort}`, `wss=${ourDomain}:${finalPort}`);
|
|
407
465
|
}
|