Browse Source

improve migration

pull/1363/head
Bernd Storath 2 years ago
parent
commit
4eaefa68bc
  1. 47
      src/server/utils/WireGuard.ts
  2. 11
      src/server/utils/config.ts
  3. 47
      src/server/utils/ip.ts

47
src/server/utils/WireGuard.ts

@ -6,8 +6,6 @@ import QRCode from 'qrcode';
import CRC32 from 'crc-32'; import CRC32 from 'crc-32';
import type { NewClient } from '~~/services/database/repositories/client'; import type { NewClient } from '~~/services/database/repositories/client';
import { parseCidr } from 'cidr-tools';
import { stringifyIp } from 'ip-bigint';
import { isIPv4 } from 'is-ip'; import { isIPv4 } from 'is-ip';
const DEBUG = debug('WireGuard'); const DEBUG = debug('WireGuard');
@ -134,50 +132,9 @@ class WireGuard {
const publicKey = await wg.getPublicKey(privateKey); const publicKey = await wg.getPublicKey(privateKey);
const preSharedKey = await wg.generatePresharedKey(); const preSharedKey = await wg.generatePresharedKey();
// Calculate next IP const address4 = nextIPv4(system, clients);
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 cidr6 = parseCidr(system.userConfig.address6Range); const address6 = nextIPv6(system, clients);
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' },
});
}
// Create Client // Create Client
const id = crypto.randomUUID(); const id = crypto.randomUUID();

11
src/server/utils/config.ts

@ -2,6 +2,8 @@ import debug from 'debug';
import packageJson from '@@/package.json'; import packageJson from '@@/package.json';
import { z } from 'zod'; import { z } from 'zod';
import type { Database } from '~~/services/database/repositories/database'; 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/'; 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 system = await Database.getSystem();
const oldConfig = res.data; const oldConfig = res.data;
const oldCidr = parseCidr(oldConfig.server.address + '/24');
const db = { const db = {
system: { system: {
...system, ...system,
@ -47,12 +50,14 @@ export async function migrateConfig(input: unknown) {
}, },
userConfig: { userConfig: {
...system.userConfig, ...system.userConfig,
address4Range: 'TODO', address4Range:
stringifyIp({ number: oldCidr.start, version: 4 }) + '/24',
}, },
} satisfies Partial<Database['system']>, } satisfies Partial<Database['system']>,
clients: {} as Database['clients'], clients: {} as Database['clients'],
}; };
for (const [oldId, oldClient] of Object.entries(oldConfig.clients)) { for (const [oldId, oldClient] of Object.entries(oldConfig.clients)) {
const address6 = nextIPv6(db.system, db.clients);
db.clients[oldId] = { db.clients[oldId] = {
id: oldId, id: oldId,
address4: oldClient.address, address4: oldClient.address,
@ -66,10 +71,10 @@ export async function migrateConfig(input: unknown) {
endpoint: null, endpoint: null,
expiresAt: null, expiresAt: null,
oneTimeLink: null, oneTimeLink: null,
allowedIPs: ['0.0.0.0/0', '::/0'], allowedIPs: db.system.userConfig.allowedIps,
serverAllowedIPs: [], serverAllowedIPs: [],
persistentKeepalive: 0, persistentKeepalive: 0,
address6: 'TODO', address6: address6,
}; };
} }
} }

47
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;
}
Loading…
Cancel
Save