mirror of
https://github.com/wireadmin/wireadmin
synced 2025-02-26 05:48:44 +00:00
After restarting container, it will try to regenerate WireGuard
conf from Database
This commit is contained in:
parent
34050ed173
commit
734b0c8e02
@ -12,7 +12,7 @@ ulimit -c 0
|
||||
# Checking if there is /data folder
|
||||
if [ ! -d "/data" ]; then
|
||||
mkdir -p /data
|
||||
chmod 744 /data
|
||||
chmod 700 /data
|
||||
fi
|
||||
|
||||
# Starting Redis server in detached mode
|
||||
@ -26,4 +26,7 @@ if [ ! -z "$WG_HOST" ]; then
|
||||
export NEXT_PUBLIC_WG_HOST=$WG_HOST
|
||||
fi
|
||||
|
||||
# After 5 seconds, export the database to the WireGuard config file
|
||||
screen -dm bash -c "sleep 5; curl -s -o /dev/null http://127.0.0.1:3000/api/wireguard/regen"
|
||||
|
||||
exec "$@"
|
||||
|
@ -4,7 +4,7 @@ export default class Shell {
|
||||
|
||||
public static async exec(command: string, safe: boolean = false, ...args: string[]): Promise<string> {
|
||||
if (process.platform !== 'linux') {
|
||||
throw new Error('This program is not meant to run on UNIX systems');
|
||||
throw new Error('This program is not meant to run non UNIX systems');
|
||||
}
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const cmd = `${command}${args.length > 0 ? ` ${args.join(' ')}` : ''}`;
|
||||
|
@ -39,3 +39,7 @@ export function isPrivateIP(ip: string) {
|
||||
const ipRegex = /^(127\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(192\.168\.)/
|
||||
return ipRegex.test(ip)
|
||||
}
|
||||
|
||||
export function dynaJoin(lines: (string | 0 | null | undefined)[]): string[] {
|
||||
return lines.filter((d) => typeof d === 'string') as string[]
|
||||
}
|
@ -13,16 +13,16 @@ export function getServerConf(server: WgServer): string {
|
||||
`${server.postUp ? `PostUp = ${server.postUp}` : 'OMIT'}`,
|
||||
`${server.preDown ? `PreDown = ${server.preDown}` : 'OMIT'}`,
|
||||
`${server.postDown ? `PostDown = ${server.postDown}` : 'OMIT'}`,
|
||||
...server.peers.map((peer, index) => ([
|
||||
'',
|
||||
`## ${peer.name || `Peer #${index + 1}`}`,
|
||||
'[Peer]',
|
||||
`PublicKey = ${peer.publicKey}`,
|
||||
`${peer.preSharedKey ? `PresharedKey = ${peer.preSharedKey}` : 'OMIT'}`,
|
||||
`AllowedIPs = ${peer.allowedIps}/32`,
|
||||
`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`
|
||||
]))
|
||||
]
|
||||
server.peers.forEach((peer, index) => {
|
||||
lines.push('')
|
||||
lines.push(`## ${peer.name || `Peer #${index + 1}`}`)
|
||||
lines.push('[Peer]')
|
||||
lines.push(`PublicKey = ${peer.publicKey}`)
|
||||
lines.push(`${peer.preSharedKey ? `PresharedKey = ${peer.preSharedKey}` : 'OMIT'}`)
|
||||
lines.push(`AllowedIPs = ${peer.allowedIps}/32`)
|
||||
lines.push(`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`)
|
||||
})
|
||||
return lines
|
||||
.filter((l) => l !== 'OMIT')
|
||||
.join('\n')
|
||||
|
@ -4,7 +4,7 @@ import { WG_PATH } from "@lib/constants";
|
||||
import Shell from "@lib/shell";
|
||||
import { WgKey, WgServer } from "@lib/typings";
|
||||
import { client, WG_SEVER_PATH } from "@lib/redis";
|
||||
import { isJson } from "@lib/utils";
|
||||
import { dynaJoin, isJson } from "@lib/utils";
|
||||
import deepmerge from "deepmerge";
|
||||
import { getPeerConf, getServerConf } from "@lib/wireguard-utils";
|
||||
|
||||
@ -66,6 +66,7 @@ export class WGServer {
|
||||
}
|
||||
const res = await client.lset(WG_SEVER_PATH, index, JSON.stringify({
|
||||
...deepmerge(server, update),
|
||||
peers: update?.peers || server?.peers || [],
|
||||
updatedAt: new Date().toISOString()
|
||||
}))
|
||||
return res === 'OK'
|
||||
@ -82,27 +83,32 @@ export class WGServer {
|
||||
console.error('server could not be updated (reason: not exists)')
|
||||
return false
|
||||
}
|
||||
const peerLines = [
|
||||
`[Peer]`,
|
||||
`PublicKey = ${peer.publicKey}`,
|
||||
`AllowedIPs = ${peer.allowedIps}/32`
|
||||
]
|
||||
if (peer.persistentKeepalive) {
|
||||
peerLines.push(`PersistentKeepalive = ${peer.persistentKeepalive}`)
|
||||
}
|
||||
if (peer.preSharedKey) {
|
||||
peerLines.push(`PresharedKey = ${peer.preSharedKey}`)
|
||||
}
|
||||
|
||||
const confPath = path.join(WG_PATH, `wg${server.confId}.conf`)
|
||||
const conf = await fs.readFile(confPath, 'utf-8')
|
||||
const lines = conf.split('\n')
|
||||
lines.push(...peerLines)
|
||||
|
||||
lines.push(...dynaJoin([
|
||||
`[Peer]`,
|
||||
`PublicKey = ${peer.publicKey}`,
|
||||
peer.preSharedKey && `PresharedKey = ${peer.preSharedKey}`,
|
||||
`AllowedIPs = ${peer.allowedIps}/32`,
|
||||
peer.persistentKeepalive && `PersistentKeepalive = ${peer.persistentKeepalive}`
|
||||
]))
|
||||
await fs.writeFile(confPath, lines.join('\n'))
|
||||
await WGServer.update(server.id, {
|
||||
|
||||
const index = await findServerIndex(id)
|
||||
if (typeof index !== 'number') {
|
||||
console.warn('findServerIndex: index not found')
|
||||
return true
|
||||
}
|
||||
await client.lset(WG_SEVER_PATH, index, JSON.stringify({
|
||||
...server,
|
||||
peers: [ ...server.peers, peer ]
|
||||
})
|
||||
await WGServer.stop(server.id)
|
||||
await WGServer.start(server.id)
|
||||
}))
|
||||
|
||||
await this.stop(server.id)
|
||||
await this.start(server.id)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -327,6 +333,7 @@ export async function generateWgServer(config: {
|
||||
port: number
|
||||
dns?: string
|
||||
mtu?: number
|
||||
insertDb?: boolean
|
||||
}): Promise<string> {
|
||||
|
||||
const { privateKey, publicKey } = await generateWgKey();
|
||||
@ -369,7 +376,9 @@ export async function generateWgServer(config: {
|
||||
}
|
||||
|
||||
// save server config
|
||||
await client.lpush(WG_SEVER_PATH, JSON.stringify(server))
|
||||
if (false !== config.insertDb) {
|
||||
await client.lpush(WG_SEVER_PATH, JSON.stringify(server))
|
||||
}
|
||||
|
||||
const CONFIG_PATH = path.join(WG_PATH, `wg${confId}.conf`)
|
||||
|
||||
|
@ -252,11 +252,15 @@ function Client(props: ClientProps) {
|
||||
)
|
||||
|
||||
return (
|
||||
<List.Item className={'flex items-center justify-between p-4'}>
|
||||
<List.Item key={props.id} className={'flex items-center justify-between p-4'}>
|
||||
<QRCodeModal ref={qrcodeRef} content={conf?.trim() || 'null'} />
|
||||
<div className={'w-full grid grid-cols-12 items-center gap-x-2'}>
|
||||
<div className={'col-span-1 rounded-full bg-gray-200 aspect-square'} />
|
||||
<span className={'font-medium col-span-4'}> {props.name} </span>
|
||||
<div className={'col-span-12 md:col-span-4'}>
|
||||
<span className={'inline-block font-medium'}> {props.name} </span>
|
||||
</div>
|
||||
<div className={'col-span-12 md:col-span-4'}>
|
||||
<span className={'font-mono text-gray-400 text-sm'}> {props.allowedIps} </span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'flex items-center justify-center gap-x-3'}>
|
||||
{/* QRCode */}
|
||||
|
30
src/pages/api/wireguard/regen.ts
Normal file
30
src/pages/api/wireguard/regen.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import safeServe from "@lib/safe-serve";
|
||||
import { getServers } from "@lib/wireguard";
|
||||
import { getServerConf } from "@lib/wireguard-utils";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { WG_PATH } from "@lib/constants";
|
||||
|
||||
/**
|
||||
* This API Endpoint is for recreating WireGuard's configs from the database.
|
||||
*
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
return safeServe(res, async () => {
|
||||
|
||||
const servers = await getServers()
|
||||
|
||||
servers.forEach((s) => {
|
||||
const CONFIG_PATH = path.join(WG_PATH, `wg${s.confId}.conf`)
|
||||
fs.writeFileSync(CONFIG_PATH, getServerConf(s), { mode: 0o600 })
|
||||
})
|
||||
|
||||
return res
|
||||
.status(200)
|
||||
.end('OK')
|
||||
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user