Major updates

This commit is contained in:
2026-09-14 07:56:13 +01:00
parent 42224c94d3
commit e0d105beb9
17 changed files with 405 additions and 277 deletions
@@ -11,31 +11,50 @@ import path from "node:path";
import grabHostNetworkInterface from "./grab-host-network-interface";
import type { APIResponseObject } from "@moduletrace/bunext/types";
import BunSQLite from "@moduletrace/bun-sqlite";
import type { TableType } from "@/src/types";
import type { TableType, User } from "@/src/types";
import checkPrivateIPAvailability from "./check-private-ip-availability";
import manageWireguardHost from "./manage-wireguard-host";
const {
WGUI_LIB_IP_TABLES_DIR,
WGUI_LIB_HOSTS_CONFIGS_DIR,
WGUI_WG_QUICK_SYSTEMD_SCRIPT,
WIREGUARD_PRIVATE_KEY_FILE_NAME,
WIREGUARD_PUBLIC_KEY_FILE_NAME,
WGUI_LIB_HOST_CLIENTS_DIR_NAME,
WGUI_LIB_HOST_IPTABLES_DIR_NAME,
} = grabDirNames();
type Params = {
host?: BUN_SQLITE_WGUI_HOSTS;
wg_subnet_ip?: string;
user: User;
};
export default async function setupWireguardHost({
host,
wg_subnet_ip,
user,
}: Params): Promise<APIResponseObject> {
const host_id = host?.id || AppData["WireguardHostID"];
const INTERFACE_NAME = deriveWireguardInterfaceName({ host_id });
const HOST_CONFIG_PATH = path.join(
const HOST_CONFIG_DIR = path.join(
WGUI_LIB_HOSTS_CONFIGS_DIR,
String(host_id),
);
const HOST_CLIENTS_DIR = path.join(
WGUI_LIB_HOSTS_CONFIGS_DIR,
WGUI_LIB_HOST_CLIENTS_DIR_NAME,
);
const HOST_IPTABLES_DIR = path.join(
WGUI_LIB_HOSTS_CONFIGS_DIR,
WGUI_LIB_HOST_IPTABLES_DIR_NAME,
);
const HOST_CONFIG_FILE = path.join(
HOST_CONFIG_DIR,
`${INTERFACE_NAME}.conf`,
);
@@ -91,16 +110,14 @@ export default async function setupWireguardHost({
let pre_sh = ``;
pre_sh += `set -e\n`;
pre_sh += `mkdir -p ${WGUI_LIB_HOSTS_CONFIGS_DIR}\n`;
pre_sh += `cd ${WGUI_LIB_HOSTS_CONFIGS_DIR}\n`;
pre_sh += `mkdir -p ${HOST_CONFIG_DIR}\n`;
pre_sh += `cd ${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" });
console.log("exec_pre_setup", exec_pre_setup);
} catch (error: any) {
return {
success: false,
@@ -109,31 +126,66 @@ export default async function setupWireguardHost({
}
try {
const HOST_PUBLIC_KEY = host?.id
? host.public_key
: execSync(
`cat ${path.join(WGUI_LIB_HOSTS_CONFIGS_DIR, WIREGUARD_PUBLIC_KEY_FILE_NAME)}`,
);
const HOST_PRIVATE_KEY = host?.private_key
? host.private_key
: execSync(
`cat ${path.join(WGUI_LIB_HOSTS_CONFIGS_DIR, WIREGUARD_PRIVATE_KEY_FILE_NAME)}`,
);
const HOST_PUBLIC_KEY = execSync(
`cat ${path.join(HOST_CONFIG_DIR, WIREGUARD_PUBLIC_KEY_FILE_NAME)}`,
{ encoding: "utf-8" },
).trim();
const HOST_PRIVATE_KEY = execSync(
`cat ${path.join(HOST_CONFIG_DIR, WIREGUARD_PRIVATE_KEY_FILE_NAME)}`,
{ encoding: "utf-8" },
).trim();
if (host_id == 0) {
const update_variables = await BunSQLite.insert<
BUN_SQLITE_WGUI_VARIABLES,
TableType
>({
table: "variables",
data: [
{
key: "main_host_wg_ip_address",
value: HOST_WG_IP,
},
{
key: "main_host_wg_public_key",
value: HOST_PUBLIC_KEY,
},
],
update_on_duplicate: true,
});
console.log("update_variables", update_variables);
if (!update_variables.success) {
throw new Error(`Couldn't update host variables`);
}
} else if (host_id) {
const update_host = await BunSQLite.insert<
BUN_SQLITE_WGUI_HOSTS,
TableType
>({
table: "hosts",
data: [
{
id: host_id,
user_id: user.id,
wg_ip_address: HOST_WG_IP,
public_key: HOST_PUBLIC_KEY,
},
],
update_on_duplicate: true,
});
}
let sh = ``;
sh += `set -e\n`;
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`,
);
const POST_UP_PATH = path.join(HOST_IPTABLES_DIR, `up.sh`);
const POST_DOWN_PATH = path.join(HOST_IPTABLES_DIR, `down.sh`);
sh += `cd ${WGUI_LIB_HOSTS_CONFIGS_DIR}\n`;
sh += `cd ${HOST_CONFIG_DIR}\n`;
sh += `cat > ${POST_UP_PATH} << EOF\n`;
sh += `#!/bin/bash\n\n`;
@@ -147,6 +199,7 @@ export default async function setupWireguardHost({
sh += `\n`;
sh += `iptables -t nat -A POSTROUTING -o ${TARGET_INTERFACE} -j MASQUERADE\n`;
sh += `EOF\n`;
sh += `chmod +x ${POST_UP_PATH}\n`;
sh += `\n`;
@@ -162,6 +215,7 @@ export default async function setupWireguardHost({
sh += `\n`;
sh += `iptables -t nat -D POSTROUTING -o ${TARGET_INTERFACE} -j MASQUERADE\n`;
sh += `EOF\n`;
sh += `chmod +x ${POST_DOWN_PATH}\n`;
sh += `\n`;
@@ -192,36 +246,26 @@ export default async function setupWireguardHost({
const exec = execSync(sh, { encoding: "utf-8" });
const IS_ROOT =
typeof process.getuid === "function" && process.getuid() === 0;
const SUDO_PREFIX = IS_ROOT ? "" : "sudo -n ";
const MANAGE_WG_QUICK_CMD = `${SUDO_PREFIX}${WGUI_WG_QUICK_SYSTEMD_SCRIPT} ${INTERFACE_NAME} ${HOST_CONFIG_PATH}`;
const manage_res = manageWireguardHost({
host_id,
action: "restart",
});
let exec_systemd = ``;
try {
exec_systemd = execSync(MANAGE_WG_QUICK_CMD, {
encoding: "utf-8",
});
return {
success: true,
msg: [exec.trim(), exec_systemd.trim()].join("\n\n"),
};
} catch (error: any) {
if (!manage_res.success) {
return {
success: false,
msg: `Host config written to ${HOST_CONFIG_PATH}, but could not manage the tunnel via systemd (wg-quick@${INTERFACE_NAME}.service): ${error.message}`,
msg: `Host config written to ${HOST_CONFIG_FILE}, but the tunnel could not be restarted: ${manage_res.msg}`,
};
}
return {
success: true,
msg: [exec.trim(), manage_res.msg].join("\n\n"),
};
} catch (error: any) {
return {
success: false,
msg: error.message,
};
}
return {
success: true,
};
}