diff --git a/src/server/utils/WireGuard.ts b/src/server/utils/WireGuard.ts index 55e56b0e..bbf77ddf 100644 --- a/src/server/utils/WireGuard.ts +++ b/src/server/utils/WireGuard.ts @@ -6,8 +6,6 @@ import QRCode from 'qrcode'; import CRC32 from 'crc-32'; import type { NewClient } from '~~/services/database/repositories/client'; -import { parseCidr } from 'cidr-tools'; -import { stringifyIp } from 'ip-bigint'; import { isIPv4 } from 'is-ip'; const DEBUG = debug('WireGuard'); @@ -134,50 +132,9 @@ class WireGuard { const publicKey = await wg.getPublicKey(privateKey); const preSharedKey = await wg.generatePresharedKey(); - // Calculate next IP - const cidr4 = parseCidr(system.userConfig.address4Range); - let address4; - for (let i = cidr4.start + 2n; i <= cidr4.end - 1n; i++) { - const currentIp4 = stringifyIp({ number: i, version: 4 }); - const client = Object.values(clients).find((client) => { - return client.address4 === currentIp4; - }); - - if (!client) { - address4 = currentIp4; - break; - } - } - - if (!address4) { - throw createError({ - statusCode: 409, - statusMessage: 'Maximum number of clients reached.', - data: { cause: 'IPv4 Address Pool exhausted' }, - }); - } + const address4 = nextIPv4(system, clients); - const cidr6 = parseCidr(system.userConfig.address6Range); - let address6; - for (let i = cidr6.start + 2n; i <= cidr6.end - 1n; i++) { - const currentIp6 = stringifyIp({ number: i, version: 6 }); - const client = Object.values(clients).find((client) => { - return client.address6 === currentIp6; - }); - - if (!client) { - address6 = currentIp6; - break; - } - } - - if (!address6) { - throw createError({ - statusCode: 409, - statusMessage: 'Maximum number of clients reached.', - data: { cause: 'IPv6 Address Pool exhausted' }, - }); - } + const address6 = nextIPv6(system, clients); // Create Client const id = crypto.randomUUID(); diff --git a/src/server/utils/config.ts b/src/server/utils/config.ts index b26e60f0..87f8363d 100644 --- a/src/server/utils/config.ts +++ b/src/server/utils/config.ts @@ -2,6 +2,8 @@ import debug from 'debug'; import packageJson from '@@/package.json'; import { z } from 'zod'; import type { Database } from '~~/services/database/repositories/database'; +import { parseCidr } from 'cidr-tools'; +import { stringifyIp } from 'ip-bigint'; export const WG_PATH = process.env.WG_PATH || '/etc/wireguard/'; @@ -36,6 +38,7 @@ export async function migrateConfig(input: unknown) { } const system = await Database.getSystem(); const oldConfig = res.data; + const oldCidr = parseCidr(oldConfig.server.address + '/24'); const db = { system: { ...system, @@ -47,12 +50,14 @@ export async function migrateConfig(input: unknown) { }, userConfig: { ...system.userConfig, - address4Range: 'TODO', + address4Range: + stringifyIp({ number: oldCidr.start, version: 4 }) + '/24', }, } satisfies Partial, clients: {} as Database['clients'], }; for (const [oldId, oldClient] of Object.entries(oldConfig.clients)) { + const address6 = nextIPv6(db.system, db.clients); db.clients[oldId] = { id: oldId, address4: oldClient.address, @@ -66,10 +71,10 @@ export async function migrateConfig(input: unknown) { endpoint: null, expiresAt: null, oneTimeLink: null, - allowedIPs: ['0.0.0.0/0', '::/0'], + allowedIPs: db.system.userConfig.allowedIps, serverAllowedIPs: [], persistentKeepalive: 0, - address6: 'TODO', + address6: address6, }; } } diff --git a/src/server/utils/ip.ts b/src/server/utils/ip.ts new file mode 100644 index 00000000..3f2fb5e3 --- /dev/null +++ b/src/server/utils/ip.ts @@ -0,0 +1,47 @@ +import { parseCidr } from 'cidr-tools'; +import { stringifyIp } from 'ip-bigint'; +import type { Database } from '~~/services/database/repositories/database'; + +export function nextIPv4( + system: Database['system'], + clients: Database['clients'] +) { + return nextIP(4, system, clients); +} + +export function nextIPv6( + system: Database['system'], + clients: Database['clients'] +) { + return nextIP(6, system, clients); +} + +function nextIP( + version: 4 | 6, + system: Database['system'], + clients: Database['clients'] +) { + const cidr = parseCidr(system.userConfig[`address${version}Range`]); + let address; + for (let i = cidr.start + 2n; i <= cidr.end - 1n; i++) { + const currentIp = stringifyIp({ number: i, version: version }); + const client = Object.values(clients).find((client) => { + return client[`address${version}`] === currentIp; + }); + + if (!client) { + address = currentIp; + break; + } + } + + if (!address) { + throw createError({ + statusCode: 409, + statusMessage: 'Maximum number of clients reached.', + data: { cause: `IPv${version} Address Pool exhausted` }, + }); + } + + return address; +}