chore: Add support for manually specifying the IP address to listen on.

This commit is contained in:
imterah 2024-09-20 14:15:47 -04:00
parent 758c92ded8
commit 3b55ce1207
Signed by: imterah
GPG key ID: 8FA7DD57BA6CEA37

View file

@ -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,