diff --git a/src/lib/network.ts b/src/lib/network.ts index c2fa105..904ff4d 100644 --- a/src/lib/network.ts +++ b/src/lib/network.ts @@ -30,4 +30,9 @@ export default class Network { return await Shell.exec(`ip route list default | awk '{print $5}'`) } + public static async checkInterfaceExists(inet: string): Promise { + return await Shell.exec(`ip link show | grep ${inet}`, true) + .then((o) => o.trim() !== '') + } + }; diff --git a/src/lib/shell.ts b/src/lib/shell.ts index 3401f46..d3cd59f 100644 --- a/src/lib/shell.ts +++ b/src/lib/shell.ts @@ -13,14 +13,11 @@ export default class Shell { { shell: 'bash' }, (err, stdout, stderr) => { if (err) { - console.error('Shell Command Failed:'); - console.error({ - command: cmd, - code: err.code, - killed: err.killed, - stderr - }) - return safe ? resolve('') : reject(err); + console.error( + `${safe ? 'Ignored::' : 'CRITICAL::'} Shell Command Failed:`, + JSON.stringify({ cmd, code: err.code, killed: err.killed, stderr }) + ); + return safe ? resolve(stderr) : reject(err); } return resolve(String(stdout).trim()); } diff --git a/src/lib/wireguard.ts b/src/lib/wireguard.ts index 6221440..9c1ecdf 100644 --- a/src/lib/wireguard.ts +++ b/src/lib/wireguard.ts @@ -8,7 +8,7 @@ import { dynaJoin, isJson } from "@lib/utils"; import deepmerge from "deepmerge"; import { getPeerConf } from "@lib/wireguard-utils"; import Network from "@lib/network"; -import { SHA256 } from "crypto-js"; +import { enc, SHA256 } from "crypto-js"; export class WGServer { @@ -19,7 +19,9 @@ export class WGServer { return false } - await Shell.exec(`wg-quick down wg${server.confId}`, true) + if (await Network.checkInterfaceExists(`wg${server.confId}`)) { + await Shell.exec(`wg-quick down wg${server.confId}`, true) + } await this.update(id, { status: 'down' }) return true @@ -32,7 +34,16 @@ export class WGServer { return false } - await Shell.exec(`wg-quick down wg${server.confId}`, true) + const HASH = await getConfigHash(server.confId); + if (!HASH || server.confHash !== HASH) { + await writeConfigFile(server); + await WGServer.update(id, { confHash: await getConfigHash(server.confId) }); + } + + if (await Network.checkInterfaceExists(`wg${server.confId}`)) { + await Shell.exec(`wg-quick down wg${server.confId}`, true) + } + await Shell.exec(`wg-quick up wg${server.confId}`) await this.update(id, { status: 'up' }) @@ -484,9 +495,10 @@ export async function getConfigHash(confId: number): Promise if (!await wgConfExists(confId)) { return undefined } + const confPath = path.join(WG_PATH, `wg${confId}.conf`) const conf = await fs.readFile(confPath, 'utf-8') - return CryptoJS.enc.Hex.stringify(SHA256(conf)); + return enc.Hex.stringify(SHA256(conf)); } export async function writeConfigFile(wg: WgServer): Promise { diff --git a/src/pages/api/wireguard/healthcheck.ts b/src/pages/api/wireguard/healthcheck.ts index 970bf54..a005bb2 100644 --- a/src/pages/api/wireguard/healthcheck.ts +++ b/src/pages/api/wireguard/healthcheck.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from 'next' import safeServe from "@lib/safe-serve"; -import { getConfigHash, getServers, WGServer, writeConfigFile } from "@lib/wireguard"; +import { getConfigHash, getServers, WGServer } from "@lib/wireguard"; export default async function handler(req: NextApiRequest, res: NextApiResponse) { return safeServe(res, async () => { @@ -10,13 +10,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) for (const s of servers) { const HASH = await getConfigHash(s.confId); - if (s.confId && s.confHash === HASH) { + if (s.confId && HASH && s.confHash === HASH) { // Skip, due to no changes on the config continue; } - await writeConfigFile(s); - await WGServer.start(s.id) + // Start server + if (s.status === 'up') { + await WGServer.start(s.id); + } } return res