This commit is contained in:
2026-09-13 06:53:33 +01:00
parent 75670e4d5c
commit e7e63bc491
45 changed files with 2117 additions and 22 deletions
@@ -0,0 +1,9 @@
/**
* Function to grab the host's network interface
* eg `eth0`
* @param param0
*/
export default async function grabHostNetworkInterface() {
// Placeholder
return `eth0`;
}
@@ -0,0 +1,9 @@
/**
* Function to grab the host's public
* IP address
* @param param0
*/
export default async function grabHostPublicIPAddress() {
// Placeholder
return `102.34.765.43`;
}
@@ -0,0 +1,147 @@
import type {
BUN_SQLITE_WGUI_CLIENTS,
BUN_SQLITE_WGUI_HOSTS,
BUN_SQLITE_WGUI_VARIABLES,
} from "@/db/types/db";
import { AppData } from "@/src/data/app-data";
import grabDirNames from "@/src/utils/grab-dir-names";
import { execSync } from "node:child_process";
import path from "node:path";
import grabHostNetworkInterface from "./grab-host-network-interface";
import type { APIResponseObject } from "@moduletrace/bunext/types";
const {
WGUI_LIB_IP_TABLES_DIR,
WIREGUARD_HOST_CONFIG_DIR,
WIREGUARD_PRIVATE_KEY_FILE_NAME,
WIREGUARD_PUBLIC_KEY_FILE_NAME,
} = grabDirNames();
type Params = {
clients: BUN_SQLITE_WGUI_CLIENTS[];
host?: BUN_SQLITE_WGUI_HOSTS;
variables?: BUN_SQLITE_WGUI_VARIABLES[];
};
export default async function setupWireguardHost({
clients,
host,
variables,
}: Params): Promise<APIResponseObject> {
const host_id = host?.id || AppData["WireguardHostID"];
const TARGET_INTERFACE = await grabHostNetworkInterface();
const HOST_WG_IP =
host?.wg_ip_address ||
variables?.find((v) => v.key == "main_host_wg_ip_address")?.value;
if (!HOST_WG_IP) {
return {
success: false,
msg: `No Host Private IP address provided`,
};
}
let pre_sh = ``;
pre_sh += `cd ${WIREGUARD_HOST_CONFIG_DIR}\n`;
pre_sh += `if [ ! -f ${WIREGUARD_PRIVATE_KEY_FILE_NAME} ]; then\n`;
pre_sh += ` wg genkey | tee ${WIREGUARD_PRIVATE_KEY_FILE_NAME} | wg pubkey > ${WIREGUARD_PUBLIC_KEY_FILE_NAME}\n`;
pre_sh += `fi\n`;
try {
const exec_pre_setup = execSync(pre_sh, { encoding: "utf-8" });
} catch (error: any) {
return {
success: false,
msg: error.message,
};
}
const HOST_PUBLIC_KEY = host?.id
? host.public_key
: execSync(
`cat ${path.join(WIREGUARD_HOST_CONFIG_DIR, WIREGUARD_PUBLIC_KEY_FILE_NAME)}`,
);
const HOST_PRIVATE_KEY = host?.id
? host.public_key
: execSync(
`cat ${path.join(WIREGUARD_HOST_CONFIG_DIR, WIREGUARD_PRIVATE_KEY_FILE_NAME)}`,
);
let sh = ``;
const POST_UP_PATH = path.join(WGUI_LIB_IP_TABLES_DIR, `${host_id}-up.sh`);
const POST_DOWN_PATH = path.join(
WGUI_LIB_IP_TABLES_DIR,
`${host_id}-down.sh`,
);
sh += `cat > ${POST_UP_PATH} << EOF\n`;
sh += `#!/bin/bash\n\n`;
sh += `# Allow WireGuard traffic to/from the server itself\n`;
sh += `iptables -I INPUT 1 -i wg${host_id} -j ACCEPT\n`;
sh += `iptables -I OUTPUT 1 -o wg${host_id} -j ACCEPT\n`;
sh += `\n`;
sh += `# Allow WireGuard traffic to be forwarded (insert above Docker rules)\n`;
sh += `iptables -I FORWARD 1 -i wg${host_id} -j ACCEPT\n`;
sh += `iptables -I FORWARD 1 -o wg${host_id} -j ACCEPT\n`;
sh += `\n`;
sh += `iptables -t nat -A POSTROUTING -o ${TARGET_INTERFACE} -j MASQUERADE\n`;
sh += `EOF\n`;
sh += `\n`;
sh += `cat > ${POST_DOWN_PATH} << EOF\n`;
sh += `#!/bin/bash\n\n`;
sh += `# Remove WireGuard INPUT/OUTPUT rules\n`;
sh += `iptables -D INPUT -i wg${host_id} -j ACCEPT\n`;
sh += `iptables -D OUTPUT -o wg${host_id} -j ACCEPT\n`;
sh += `\n`;
sh += `# Remove FORWARD rules\n`;
sh += `iptables -D FORWARD -i wg${host_id} -j ACCEPT\n`;
sh += `iptables -D FORWARD -o wg${host_id} -j ACCEPT\n`;
sh += `\n`;
sh += `iptables -t nat -D POSTROUTING -o ${TARGET_INTERFACE} -j MASQUERADE\n`;
sh += `EOF\n`;
sh += `\n`;
sh += `cat > wg${host_id}.conf << EOF\n`;
sh += `[Interface]\n`;
sh += `Address = ${HOST_WG_IP}/24\n`;
sh += `ListenPort = 51820\n`;
sh += `PrivateKey = ${HOST_PRIVATE_KEY}\n`;
sh += `PostUp = ${POST_UP_PATH}\n`;
sh += `PostDown = ${POST_DOWN_PATH}\n`;
sh += `\n`;
if (clients[0]) {
for (let i = 0; i < clients.length; i++) {
const client = clients[i];
if (!client?.id || !client.public_key || !client.private_key)
continue;
sh += `[Peer]\n`;
sh += `PublicKey = ${client.public_key}\n`;
sh += `\n`;
}
}
sh += `EOF\n`;
sh += `\n`;
try {
const exec = execSync(sh, { encoding: "utf-8" });
} catch (error: any) {
return {
success: false,
msg: error.message,
};
}
return {
success: true,
};
}