Browse Source

feat: add amneziawg support (#2102)

* feat: detect wireguard executable

* feat: add amneziawg-tools to container

* feat: enhance AWG detection and configuration handling

* refactor: change env name

* refactor: change env values
master
Alexander Chepurnoy 1 day ago
committed by GitHub
parent
commit
ef463d3d85
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 13
      Dockerfile
  2. 2
      src/nuxt.config.ts
  3. 10
      src/server/utils/config.ts
  4. 34
      src/server/utils/wgHelper.ts

13
Dockerfile

@ -14,6 +14,12 @@ RUN pnpm install
COPY src ./
RUN pnpm build
# Build amneziawg-tools
RUN apk add linux-headers build-base git && \
git clone https://github.com/amnezia-vpn/amneziawg-tools.git && \
cd amneziawg-tools/src && \
make
# Copy build result to a new image.
# This saves a lot of disk space.
FROM docker.io/library/node:lts-alpine
@ -32,6 +38,10 @@ RUN cd /app/server && \
# cli
COPY --from=build /app/cli/cli.sh /usr/local/bin/cli
RUN chmod +x /usr/local/bin/cli
# Copy amneziawg-tools
COPY --from=build /app/amneziawg-tools/src/wg /usr/bin/awg
COPY --from=build /app/amneziawg-tools/src/wg-quick/linux.bash /usr/bin/awg-quick
RUN chmod +x /usr/bin/awg /usr/bin/awg-quick
# Install Linux packages
RUN apk add --no-cache \
@ -44,6 +54,9 @@ RUN apk add --no-cache \
iptables-legacy \
wireguard-tools
RUN mkdir -p /etc/amnezia
RUN ln -s /etc/wireguard /etc/amnezia/amneziawg
# Use iptables-legacy
RUN update-alternatives --install /usr/sbin/iptables iptables /usr/sbin/iptables-legacy 10 --slave /usr/sbin/iptables-restore iptables-restore /usr/sbin/iptables-legacy-restore --slave /usr/sbin/iptables-save iptables-save /usr/sbin/iptables-legacy-save
RUN update-alternatives --install /usr/sbin/ip6tables ip6tables /usr/sbin/ip6tables-legacy 10 --slave /usr/sbin/ip6tables-restore ip6tables-restore /usr/sbin/ip6tables-legacy-restore --slave /usr/sbin/ip6tables-save ip6tables-save /usr/sbin/ip6tables-legacy-save

2
src/nuxt.config.ts

@ -95,7 +95,7 @@ export default defineNuxtConfig({
esbuild: {
options: {
// to support big int
target: 'es2020',
target: 'node20',
},
},
alias: {

10
src/server/utils/config.ts

@ -12,6 +12,8 @@ export const OLD_ENV = {
PASSWORD_HASH: process.env.PASSWORD_HASH,
};
const OVERRIDE_AUTO_AWG = process.env.OVERRIDE_AUTO_AWG?.toLowerCase();
export const WG_ENV = {
/** UI is hosted on HTTP instead of HTTPS */
INSECURE: process.env.INSECURE === 'true',
@ -19,6 +21,14 @@ export const WG_ENV = {
PORT: assertEnv('PORT'),
/** If IPv6 should be disabled */
DISABLE_IPV6: process.env.DISABLE_IPV6 === 'true',
/** Override automatic detection */
OVERRIDE_AUTO_AWG:
OVERRIDE_AUTO_AWG === ('wg' as const) ||
OVERRIDE_AUTO_AWG === ('awg' as const)
? OVERRIDE_AUTO_AWG
: undefined,
/** TODO: delete on next major version */
EXPERIMENTAL_AWG: process.env.EXPERIMENTAL_AWG === 'true',
};
export const WG_INITIAL_ENV = {

34
src/server/utils/wgHelper.ts

@ -9,6 +9,18 @@ type Options = {
enableIpv6?: boolean;
};
let wgExecutable: 'awg' | 'wg' = 'wg';
if (WG_ENV.EXPERIMENTAL_AWG) {
if (WG_ENV.OVERRIDE_AUTO_AWG !== undefined) {
wgExecutable = WG_ENV.OVERRIDE_AUTO_AWG;
} else {
wgExecutable = await exec('modinfo amneziawg')
.then(() => 'awg' as const)
.catch(() => 'wg' as const);
}
}
export const wg = {
generateServerPeer: (
client: Omit<ClientType, 'createdAt' | 'updatedAt'>,
@ -107,37 +119,41 @@ Endpoint = ${userConfig.host}:${userConfig.port}`;
},
generatePrivateKey: () => {
return exec('wg genkey');
return exec(`${wgExecutable} genkey`);
},
getPublicKey: (privateKey: string) => {
return exec(`echo ${privateKey} | wg pubkey`, {
log: 'echo ***hidden*** | wg pubkey',
return exec(`echo ${privateKey} | ${wgExecutable} pubkey`, {
log: `echo ***hidden*** | ${wgExecutable} pubkey`,
});
},
generatePreSharedKey: () => {
return exec('wg genpsk');
return exec(`${wgExecutable} genpsk`);
},
up: (infName: string) => {
return exec(`wg-quick up ${infName}`);
return exec(`${wgExecutable}-quick up ${infName}`);
},
down: (infName: string) => {
return exec(`wg-quick down ${infName}`);
return exec(`${wgExecutable}-quick down ${infName}`);
},
restart: (infName: string) => {
return exec(`wg-quick down ${infName}; wg-quick up ${infName}`);
return exec(
`${wgExecutable}-quick down ${infName}; ${wgExecutable}-quick up ${infName}`
);
},
sync: (infName: string) => {
return exec(`wg syncconf ${infName} <(wg-quick strip ${infName})`);
return exec(
`${wgExecutable} syncconf ${infName} <(${wgExecutable}-quick strip ${infName})`
);
},
dump: async (infName: string) => {
const rawDump = await exec(`wg show ${infName} dump`, {
const rawDump = await exec(`${wgExecutable} show ${infName} dump`, {
log: false,
});

Loading…
Cancel
Save