Browse Source

- Add AmneziaWG 2.0 support;

- buildAmneziaQrPack is async (zlib deflate);
- ClientQrSchema now has 'wireguard' as fallback
pull/2423/head^2
ne0x 6 months ago
parent
commit
9a335ffaeb
  1. 7
      src/server/database/repositories/client/types.ts
  2. 9
      src/server/utils/WireGuard.ts
  3. 26
      src/server/utils/wgHelper.ts

7
src/server/database/repositories/client/types.ts

@ -104,11 +104,10 @@ export type ClientCreateFromExistingType = Pick<
| 'enabled' | 'enabled'
>; >;
const qrType = z.preprocess( const qrType = z.enum(['amnezia-vpn', 'wireguard']).catch('wireguard');
(val) => (val === 'amnezia-vpn' ? val : undefined),
z.enum(['amnezia-vpn']).optional()
);
export const ClientQrSchema = z.object({ export const ClientQrSchema = z.object({
type: qrType, type: qrType,
}); });
export type QrType = z.infer<typeof qrType>;

9
src/server/utils/WireGuard.ts

@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
import debug from 'debug'; import debug from 'debug';
import { encodeQR } from 'qr'; import { encodeQR } from 'qr';
import type { InterfaceType } from '#db/repositories/interface/types'; import type { InterfaceType } from '#db/repositories/interface/types';
import type { QrType } from '#db/repositories/client/types';
const WG_DEBUG = debug('WireGuard'); const WG_DEBUG = debug('WireGuard');
@ -149,7 +150,7 @@ class WireGuard {
return clients; return clients;
} }
async getClientConfiguration({ clientId, type }: { clientId: ID, type?: 'amnezia-vpn' }) { async getClientConfiguration({ clientId, type }: { clientId: ID, type?: QrType }) {
const wgInterface = await Database.interfaces.get(); const wgInterface = await Database.interfaces.get();
const userConfig = await Database.userConfigs.get(); const userConfig = await Database.userConfigs.get();
@ -167,13 +168,15 @@ class WireGuard {
const amneziaVPNClientConfig = wg.generateAmneziaVPNClientConfig(wgInterface, userConfig, client, configText, { const amneziaVPNClientConfig = wg.generateAmneziaVPNClientConfig(wgInterface, userConfig, client, configText, {
enableIpv6: !WG_ENV.DISABLE_IPV6, enableIpv6: !WG_ENV.DISABLE_IPV6,
}); });
return wg.buildAmneziaQrPack(JSON.stringify(amneziaVPNClientConfig)); const qrConfigPack = await wg.buildAmneziaQrPack(JSON.stringify(amneziaVPNClientConfig));
return qrConfigPack;
} }
return configText; return configText;
} }
async getClientQRCodeSVG({ clientId, type }: { clientId: ID, type?: 'amnezia-vpn' }) { async getClientQRCodeSVG({ clientId, type }: { clientId: ID, type?: QrType }) {
const config = await this.getClientConfiguration({ clientId, type }); const config = await this.getClientConfiguration({ clientId, type });
const ECMode = ['high', 'quartile', 'medium', 'low'] as const; const ECMode = ['high', 'quartile', 'medium', 'low'] as const;
for (const ecc of ECMode) { for (const ecc of ECMode) {

26
src/server/utils/wgHelper.ts

@ -1,4 +1,5 @@
import { deflateSync as zlibDeflateSync } from 'node:zlib'; import { deflate } from 'node:zlib';
import { promisify } from 'node:util';
import { parseCidr } from 'cidr-tools'; import { parseCidr } from 'cidr-tools';
import { stringifyIp } from 'ip-bigint'; import { stringifyIp } from 'ip-bigint';
import type { ClientType } from '#db/repositories/client/types'; import type { ClientType } from '#db/repositories/client/types';
@ -6,6 +7,8 @@ import type { InterfaceType } from '#db/repositories/interface/types';
import type { UserConfigType } from '#db/repositories/userConfig/types'; import type { UserConfigType } from '#db/repositories/userConfig/types';
import type { HooksType } from '#db/repositories/hooks/types'; import type { HooksType } from '#db/repositories/hooks/types';
const zlibDeflate = promisify(deflate);
type Options = { type Options = {
enableIpv6?: boolean; enableIpv6?: boolean;
}; };
@ -188,20 +191,14 @@ Endpoint = ${userConfig.host}:${userConfig.port}`;
if (wgExecutable === 'awg') { if (wgExecutable === 'awg') {
containerType = 'awg'; containerType = 'awg';
// S3, S4, i1, i2, i3, i4, i5 are not supported by AmneziaVPN app for now
const awgParams = { const awgParams = {
Jc: client.jC, Jc: client.jC,
Jmin: client.jMin, Jmin: client.jMin,
Jmax: client.jMax, Jmax: client.jMax,
S1: wgInterface.s1, S1: wgInterface.s1,
S2: wgInterface.s2, S2: wgInterface.s2,
// S3: wgInterface.s3, S3: wgInterface.s3,
// S4: wgInterface.s4, S4: wgInterface.s4,
// i1: client.i1,
// i2: client.i2,
// i3: client.i3,
// i4: client.i4,
// i5: client.i5,
H1: wgInterface.h1, H1: wgInterface.h1,
H2: wgInterface.h2, H2: wgInterface.h2,
H3: wgInterface.h3, H3: wgInterface.h3,
@ -217,6 +214,12 @@ Endpoint = ${userConfig.host}:${userConfig.port}`;
); );
} }
const protocolInfo: { protocol_version?: string } = {};
if (awgExtras.hasOwnProperty('S3') && awgExtras.hasOwnProperty('S4')) {
protocolInfo.protocol_version = '2';
}
const lastConfigObj = { const lastConfigObj = {
...awgExtras, ...awgExtras,
allowed_ips: client.allowedIps ?? userConfig.defaultAllowedIps ?? [], allowed_ips: client.allowedIps ?? userConfig.defaultAllowedIps ?? [],
@ -238,6 +241,7 @@ Endpoint = ${userConfig.host}:${userConfig.port}`;
isThirdPartyConfig: true, isThirdPartyConfig: true,
last_config: JSON.stringify(lastConfigObj), last_config: JSON.stringify(lastConfigObj),
port: `${userConfig.port}`, port: `${userConfig.port}`,
...protocolInfo,
transport_proto: 'udp', transport_proto: 'udp',
}, },
container: `amnezia-${containerType}`, container: `amnezia-${containerType}`,
@ -251,14 +255,14 @@ Endpoint = ${userConfig.host}:${userConfig.port}`;
}; };
}, },
buildAmneziaQrPack: (amneziaConfigJSON: string) => { buildAmneziaQrPack: async (amneziaConfigJSON: string) => {
// Observed working QR wrapper: // Observed working QR wrapper:
// [0..3] magic/version (0x07C00100) // [0..3] magic/version (0x07C00100)
// [4..7] zlib_len + 4 // [4..7] zlib_len + 4
// [8..11] uncompressed_len // [8..11] uncompressed_len
// [12..] zlib(deflate) bytes (starts with 78 DA typically) // [12..] zlib(deflate) bytes (starts with 78 DA typically)
const plain = Buffer.from(amneziaConfigJSON, 'utf8'); const plain = Buffer.from(amneziaConfigJSON, 'utf8');
const z = zlibDeflateSync(plain); const z = await zlibDeflate(plain);
const MAGIC = 0x07c00100; const MAGIC = 0x07c00100;
const header = Buffer.allocUnsafe(12); const header = Buffer.allocUnsafe(12);

Loading…
Cancel
Save