chore: Add support for manually specifying the IP address to listen on.
This commit is contained in:
parent
758c92ded8
commit
3b55ce1207
1 changed files with 74 additions and 52 deletions
|
@ -8,6 +8,13 @@ import type {
|
||||||
ParameterReturnedValue,
|
ParameterReturnedValue,
|
||||||
} from "./base.js";
|
} from "./base.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
TcpConnectionDetails,
|
||||||
|
AcceptConnection,
|
||||||
|
ClientChannel,
|
||||||
|
RejectConnection,
|
||||||
|
} from "ssh2";
|
||||||
|
|
||||||
type ForwardRuleExt = ForwardRule & {
|
type ForwardRuleExt = ForwardRule & {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +26,8 @@ type BackendParsedProviderString = {
|
||||||
|
|
||||||
username: string;
|
username: string;
|
||||||
privateKey: string;
|
privateKey: string;
|
||||||
|
|
||||||
|
listenOnIPs: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
function parseBackendProviderString(data: string): BackendParsedProviderString {
|
function parseBackendProviderString(data: string): BackendParsedProviderString {
|
||||||
|
@ -46,12 +55,22 @@ function parseBackendProviderString(data: string): BackendParsedProviderString {
|
||||||
throw new Error("Private key is not a string");
|
throw new Error("Private key is not a string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let listenOnIPs: string[] = [];
|
||||||
|
|
||||||
|
if (!Array.isArray(jsonData.listenOnIPs)) {
|
||||||
|
listenOnIPs.push("0.0.0.0");
|
||||||
|
} else {
|
||||||
|
listenOnIPs = jsonData.listenOnIPs;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ip: jsonData.ip,
|
ip: jsonData.ip,
|
||||||
port: jsonData.port,
|
port: jsonData.port,
|
||||||
|
|
||||||
username: jsonData.username,
|
username: jsonData.username,
|
||||||
privateKey: jsonData.privateKey,
|
privateKey: jsonData.privateKey,
|
||||||
|
|
||||||
|
listenOnIPs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +140,7 @@ export class SSHBackendProvider implements BackendBaseClass {
|
||||||
|
|
||||||
for (const proxy of proxies) {
|
for (const proxy of proxies) {
|
||||||
if (!proxy.enabled) continue;
|
if (!proxy.enabled) continue;
|
||||||
|
|
||||||
this.addConnection(
|
this.addConnection(
|
||||||
proxy.sourceIP,
|
proxy.sourceIP,
|
||||||
proxy.sourcePort,
|
proxy.sourcePort,
|
||||||
|
@ -178,59 +198,61 @@ export class SSHBackendProvider implements BackendBaseClass {
|
||||||
|
|
||||||
if (foundProxyEntry) return;
|
if (foundProxyEntry) return;
|
||||||
|
|
||||||
(async () => {
|
const connCallback = (
|
||||||
await this.sshInstance.forwardIn(
|
info: TcpConnectionDetails,
|
||||||
"0.0.0.0",
|
accept: AcceptConnection<ClientChannel>,
|
||||||
destPort,
|
reject: RejectConnection,
|
||||||
(info, accept, reject) => {
|
) => {
|
||||||
const foundProxyEntry = this.proxies.find(
|
const foundProxyEntry = this.proxies.find(
|
||||||
i =>
|
i =>
|
||||||
i.sourceIP == sourceIP &&
|
i.sourceIP == sourceIP &&
|
||||||
i.sourcePort == sourcePort &&
|
i.sourcePort == sourcePort &&
|
||||||
i.destPort == destPort,
|
i.destPort == destPort,
|
||||||
);
|
|
||||||
|
|
||||||
if (!foundProxyEntry || !foundProxyEntry.enabled) return reject();
|
|
||||||
|
|
||||||
const client: ConnectedClient = {
|
|
||||||
ip: info.srcIP,
|
|
||||||
port: info.srcPort,
|
|
||||||
|
|
||||||
connectionDetails: foundProxyEntry,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clients.push(client);
|
|
||||||
|
|
||||||
const srcConn = new Socket();
|
|
||||||
|
|
||||||
srcConn.connect({
|
|
||||||
host: sourceIP,
|
|
||||||
port: sourcePort,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Why is this so confusing
|
|
||||||
const destConn = accept();
|
|
||||||
|
|
||||||
destConn.addListener("data", (chunk: Uint8Array) => {
|
|
||||||
srcConn.write(chunk);
|
|
||||||
});
|
|
||||||
|
|
||||||
destConn.addListener("end", () => {
|
|
||||||
this.clients.splice(this.clients.indexOf(client), 1);
|
|
||||||
srcConn.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
srcConn.on("data", data => {
|
|
||||||
destConn.write(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
srcConn.on("end", () => {
|
|
||||||
this.clients.splice(this.clients.indexOf(client), 1);
|
|
||||||
destConn.end();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
})();
|
|
||||||
|
if (!foundProxyEntry || !foundProxyEntry.enabled) return reject();
|
||||||
|
|
||||||
|
const client: ConnectedClient = {
|
||||||
|
ip: info.srcIP,
|
||||||
|
port: info.srcPort,
|
||||||
|
|
||||||
|
connectionDetails: foundProxyEntry,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clients.push(client);
|
||||||
|
|
||||||
|
const srcConn = new Socket();
|
||||||
|
|
||||||
|
srcConn.connect({
|
||||||
|
host: sourceIP,
|
||||||
|
port: sourcePort,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Why is this so confusing
|
||||||
|
const destConn = accept();
|
||||||
|
|
||||||
|
destConn.addListener("data", (chunk: Uint8Array) => {
|
||||||
|
srcConn.write(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
destConn.addListener("end", () => {
|
||||||
|
this.clients.splice(this.clients.indexOf(client), 1);
|
||||||
|
srcConn.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
srcConn.on("data", data => {
|
||||||
|
destConn.write(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
srcConn.on("end", () => {
|
||||||
|
this.clients.splice(this.clients.indexOf(client), 1);
|
||||||
|
destConn.end();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const ip of this.options.listenOnIPs) {
|
||||||
|
this.sshInstance.forwardIn(ip, destPort, connCallback);
|
||||||
|
}
|
||||||
|
|
||||||
this.proxies.push({
|
this.proxies.push({
|
||||||
sourceIP,
|
sourceIP,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue