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 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();

11
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<Database['system']>,
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,
};
}
}

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