ipv6 support and set WG_SRV_MTU to configure server
This commit is contained in:
parent
3ab24487d4
commit
79ed912d44
@ -34,12 +34,14 @@ RUN chmod +x /bin/wgpw
|
|||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
dpkg \
|
dpkg \
|
||||||
dumb-init \
|
dumb-init \
|
||||||
|
ip6tables \
|
||||||
iptables \
|
iptables \
|
||||||
iptables-legacy \
|
iptables-legacy \
|
||||||
wireguard-tools
|
wireguard-tools
|
||||||
|
|
||||||
# Use iptables-legacy
|
# Use iptables-legacy
|
||||||
RUN update-alternatives --install /sbin/iptables iptables /sbin/iptables-legacy 10 --slave /sbin/iptables-restore iptables-restore /sbin/iptables-legacy-restore --slave /sbin/iptables-save iptables-save /sbin/iptables-legacy-save
|
RUN update-alternatives --install /sbin/iptables iptables /sbin/iptables-legacy 10 --slave /sbin/iptables-restore iptables-restore /sbin/iptables-legacy-restore --slave /sbin/iptables-save iptables-save /sbin/iptables-legacy-save
|
||||||
|
RUN update-alternatives --install /sbin/ip6tables ip6tables /sbin/ip6tables-legacy 10 --slave /sbin/ip6tables-restore ip6tables-restore /sbin/ip6tables-legacy-restore --slave /sbin/ip6tables-save ip6tables-save /sbin/ip6tables-legacy-save
|
||||||
|
|
||||||
# Set Environment
|
# Set Environment
|
||||||
ENV DEBUG=Server,WireGuard
|
ENV DEBUG=Server,WireGuard
|
||||||
|
@ -71,6 +71,7 @@ To automatically install & run wg-easy, simply run:
|
|||||||
-v ~/.wg-easy:/etc/wireguard \
|
-v ~/.wg-easy:/etc/wireguard \
|
||||||
-p 51820:51820/udp \
|
-p 51820:51820/udp \
|
||||||
-p 51821:51821/tcp \
|
-p 51821:51821/tcp \
|
||||||
|
--privileged=true \
|
||||||
--cap-add=NET_ADMIN \
|
--cap-add=NET_ADMIN \
|
||||||
--cap-add=SYS_MODULE \
|
--cap-add=SYS_MODULE \
|
||||||
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
|
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
|
||||||
@ -109,9 +110,12 @@ These options can be configured by setting environment variables using `-e KEY="
|
|||||||
| `WG_PORT` | `51820` | `12345` | The public UDP port of your VPN server. WireGuard will listen on that (othwise default) inside the Docker container. |
|
| `WG_PORT` | `51820` | `12345` | The public UDP port of your VPN server. WireGuard will listen on that (othwise default) inside the Docker container. |
|
||||||
| `WG_CONFIG_PORT`| `51820` | `12345` | The UDP port used on [Home Assistant Plugin](https://github.com/adriy-be/homeassistant-addons-jdeath/tree/main/wgeasy)
|
| `WG_CONFIG_PORT`| `51820` | `12345` | The UDP port used on [Home Assistant Plugin](https://github.com/adriy-be/homeassistant-addons-jdeath/tree/main/wgeasy)
|
||||||
| `WG_MTU` | `null` | `1420` | The MTU the clients will use. Server uses default WG MTU. |
|
| `WG_MTU` | `null` | `1420` | The MTU the clients will use. Server uses default WG MTU. |
|
||||||
|
| `WG_SRV_MTU` | `1420` | `1384` | The MTU the Server will use. |
|
||||||
| `WG_PERSISTENT_KEEPALIVE` | `0` | `25` | Value in seconds to keep the "connection" open. If this value is 0, then connections won't be kept alive. |
|
| `WG_PERSISTENT_KEEPALIVE` | `0` | `25` | Value in seconds to keep the "connection" open. If this value is 0, then connections won't be kept alive. |
|
||||||
| `WG_DEFAULT_ADDRESS` | `10.8.0.x` | `10.6.0.x` | Clients IP address range. |
|
| `WG_DEFAULT_ADDRESS` | `10.8.0.x` | `10.6.0.x` | Clients IP address range. |
|
||||||
| `WG_DEFAULT_DNS` | `1.1.1.1` | `8.8.8.8, 8.8.4.4` | DNS server clients will use. If set to blank value, clients will not use any DNS. |
|
| `WG_DEFAULT_ADDRESS6` | `fdcc:ad94:bacf:61a4::cafe:x` | `fdcc:ad94:bacf:61a4::42:x` | Clients IPv6 address range. Has to be a valid IPv6 ULA address. |
|
||||||
|
| `WG_DEFAULT_DNS` | `84.200.69.80` | `84.200.69.80, 84.200.70.40` | DNS server clients will use. If set to blank value, clients will not use any DNS. |
|
||||||
|
| `WG_DEFAULT_DNS6` | `2001:1608:10:25::1c04:b12f` | `2001:1608:10:25::1c04:b12f, 2001:1608:10:25::9249:d69b` | DNSv6 server clients will use. |
|
||||||
| `WG_ALLOWED_IPS` | `0.0.0.0/0, ::/0` | `192.168.15.0/24, 10.0.1.0/24` | Allowed IPs clients will use. |
|
| `WG_ALLOWED_IPS` | `0.0.0.0/0, ::/0` | `192.168.15.0/24, 10.0.1.0/24` | Allowed IPs clients will use. |
|
||||||
| `WG_PRE_UP` | `...` | - | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L19) for the default value. |
|
| `WG_PRE_UP` | `...` | - | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L19) for the default value. |
|
||||||
| `WG_POST_UP` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L20) for the default value. |
|
| `WG_POST_UP` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L20) for the default value. |
|
||||||
|
@ -17,8 +17,11 @@ services:
|
|||||||
# - WG_PORT=51820
|
# - WG_PORT=51820
|
||||||
# - WG_CONFIG_PORT=92820
|
# - WG_CONFIG_PORT=92820
|
||||||
# - WG_DEFAULT_ADDRESS=10.8.0.x
|
# - WG_DEFAULT_ADDRESS=10.8.0.x
|
||||||
# - WG_DEFAULT_DNS=1.1.1.1
|
# - WG_DEFAULT_ADDRESS6=fdcc:ad94:bacf:61a4::cafe:x
|
||||||
|
# - WG_DEFAULT_DNS=84.200.69.80
|
||||||
|
# - WG_DEFAULT_DNS6=2001:1608:10:25::1c04:b12f
|
||||||
# - WG_MTU=1420
|
# - WG_MTU=1420
|
||||||
|
# - WG_SRV_MTU=1420
|
||||||
# - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24
|
# - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24
|
||||||
# - WG_PERSISTENT_KEEPALIVE=25
|
# - WG_PERSISTENT_KEEPALIVE=25
|
||||||
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
|
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
|
||||||
@ -30,11 +33,16 @@ services:
|
|||||||
|
|
||||||
image: ghcr.io/wg-easy/wg-easy
|
image: ghcr.io/wg-easy/wg-easy
|
||||||
container_name: wg-easy
|
container_name: wg-easy
|
||||||
|
networks:
|
||||||
|
wg:
|
||||||
|
ipv4_address: 10.42.42.42
|
||||||
|
ipv6_address: fdcc:ad94:bacf:61a3::2a
|
||||||
volumes:
|
volumes:
|
||||||
- etc_wireguard:/etc/wireguard
|
- etc_wireguard:/etc/wireguard
|
||||||
ports:
|
ports:
|
||||||
- "51820:51820/udp"
|
- "51820:51820/udp"
|
||||||
- "51821:51821/tcp"
|
- "51821:51821/tcp"
|
||||||
|
privileged: true
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
@ -43,3 +51,16 @@ services:
|
|||||||
sysctls:
|
sysctls:
|
||||||
- net.ipv4.ip_forward=1
|
- net.ipv4.ip_forward=1
|
||||||
- net.ipv4.conf.all.src_valid_mark=1
|
- net.ipv4.conf.all.src_valid_mark=1
|
||||||
|
- net.ipv6.conf.all.disable_ipv6=0
|
||||||
|
- net.ipv6.conf.all.forwarding=1
|
||||||
|
- net.ipv6.conf.default.forwarding=1
|
||||||
|
|
||||||
|
networks:
|
||||||
|
wg:
|
||||||
|
driver: bridge
|
||||||
|
enable_ipv6: true
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 10.42.42.0/24
|
||||||
|
- subnet: fdcc:ad94:bacf:61a3::/64
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const childProcess = require('child_process');
|
||||||
const { release: { version } } = require('./package.json');
|
const { release: { version } } = require('./package.json');
|
||||||
|
|
||||||
module.exports.RELEASE = version;
|
module.exports.RELEASE = version;
|
||||||
@ -12,28 +13,60 @@ module.exports.WG_HOST = process.env.WG_HOST;
|
|||||||
module.exports.WG_PORT = process.env.WG_PORT || '51820';
|
module.exports.WG_PORT = process.env.WG_PORT || '51820';
|
||||||
module.exports.WG_CONFIG_PORT = process.env.WG_CONFIG_PORT || process.env.WG_PORT || '51820';
|
module.exports.WG_CONFIG_PORT = process.env.WG_CONFIG_PORT || process.env.WG_PORT || '51820';
|
||||||
module.exports.WG_MTU = process.env.WG_MTU || null;
|
module.exports.WG_MTU = process.env.WG_MTU || null;
|
||||||
|
module.exports.WG_SRV_MTU = process.env.WG_SRV_MTU || '1420';
|
||||||
module.exports.WG_PERSISTENT_KEEPALIVE = process.env.WG_PERSISTENT_KEEPALIVE || '0';
|
module.exports.WG_PERSISTENT_KEEPALIVE = process.env.WG_PERSISTENT_KEEPALIVE || '0';
|
||||||
module.exports.WG_DEFAULT_ADDRESS = process.env.WG_DEFAULT_ADDRESS || '10.8.0.x';
|
module.exports.WG_DEFAULT_ADDRESS = process.env.WG_DEFAULT_ADDRESS || '10.8.0.x';
|
||||||
|
module.exports.WG_DEFAULT_ADDRESS6 = process.env.WG_DEFAULT_ADDRESS6 || 'fdcc:ad94:bacf:61a4::cafe:x';
|
||||||
module.exports.WG_DEFAULT_DNS = typeof process.env.WG_DEFAULT_DNS === 'string'
|
module.exports.WG_DEFAULT_DNS = typeof process.env.WG_DEFAULT_DNS === 'string'
|
||||||
? process.env.WG_DEFAULT_DNS
|
? process.env.WG_DEFAULT_DNS
|
||||||
: '1.1.1.1';
|
: '84.200.69.80';
|
||||||
|
module.exports.WG_DEFAULT_DNS6 = typeof process.env.WG_DEFAULT_DNS6 === 'string'
|
||||||
|
? process.env.WG_DEFAULT_DNS6
|
||||||
|
: '2001:1608:10:25::1c04:b12f';
|
||||||
module.exports.WG_ALLOWED_IPS = process.env.WG_ALLOWED_IPS || '0.0.0.0/0, ::/0';
|
module.exports.WG_ALLOWED_IPS = process.env.WG_ALLOWED_IPS || '0.0.0.0/0, ::/0';
|
||||||
|
|
||||||
|
// Set WG_POST_UP to allow IPv6 NAT and forwarding only if the required kernel module is available
|
||||||
|
const modules = childProcess.execSync('lsmod', {
|
||||||
|
shell: 'bash',
|
||||||
|
});
|
||||||
module.exports.WG_PRE_UP = process.env.WG_PRE_UP || '';
|
module.exports.WG_PRE_UP = process.env.WG_PRE_UP || '';
|
||||||
module.exports.WG_POST_UP = process.env.WG_POST_UP || `
|
module.exports.WG_POST_UP = process.env.WG_POST_UP;
|
||||||
|
if (!process.env.WG_POST_UP) {
|
||||||
|
module.exports.WG_POST_UP = `
|
||||||
iptables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
iptables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
||||||
iptables -A INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
iptables -A INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
||||||
iptables -A FORWARD -i wg0 -j ACCEPT;
|
iptables -A FORWARD -i wg0 -j ACCEPT;
|
||||||
iptables -A FORWARD -o wg0 -j ACCEPT;
|
iptables -A FORWARD -o wg0 -j ACCEPT;`;
|
||||||
`.split('\n').join(' ');
|
|
||||||
|
if (modules.includes('ip6table_nat')) {
|
||||||
|
module.exports.WG_POST_UP += `
|
||||||
|
ip6tables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS6.replace('x', '0')}/64 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
||||||
|
ip6tables -A INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
||||||
|
ip6tables -A FORWARD -i wg0 -j ACCEPT;
|
||||||
|
ip6tables -A FORWARD -o wg0 -j ACCEPT;`;
|
||||||
|
}
|
||||||
|
module.exports.WG_POST_UP = module.exports.WG_POST_UP.replace(/\n\s*/g, ' ').trim();
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.WG_PRE_DOWN = process.env.WG_PRE_DOWN || '';
|
module.exports.WG_PRE_DOWN = process.env.WG_PRE_DOWN || '';
|
||||||
module.exports.WG_POST_DOWN = process.env.WG_POST_DOWN || `
|
module.exports.WG_POST_DOWN = process.env.WG_POST_DOWN;
|
||||||
|
if (!process.env.WG_POST_DOWN) {
|
||||||
|
module.exports.WG_POST_DOWN = `
|
||||||
iptables -t nat -D POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
iptables -t nat -D POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
||||||
iptables -D INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
iptables -D INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
||||||
iptables -D FORWARD -i wg0 -j ACCEPT;
|
iptables -D FORWARD -i wg0 -j ACCEPT;
|
||||||
iptables -D FORWARD -o wg0 -j ACCEPT;
|
iptables -D FORWARD -o wg0 -j ACCEPT;`;
|
||||||
`.split('\n').join(' ');
|
|
||||||
|
if (modules.includes('ip6table_nat')) {
|
||||||
|
module.exports.WG_POST_DOWN += `
|
||||||
|
ip6tables -t nat -D POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS6.replace('x', '0')}/64 -o ${module.exports.WG_DEVICE} -j MASQUERADE;
|
||||||
|
ip6tables -D INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
|
||||||
|
ip6tables -D FORWARD -i wg0 -j ACCEPT;
|
||||||
|
ip6tables -D FORWARD -o wg0 -j ACCEPT;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.WG_POST_DOWN = module.exports.WG_POST_DOWN.replace(/\n\s*/g, ' ').trim();
|
||||||
|
}
|
||||||
module.exports.LANG = process.env.LANG || 'en';
|
module.exports.LANG = process.env.LANG || 'en';
|
||||||
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
|
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
|
||||||
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
|
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
|
||||||
|
@ -233,6 +233,15 @@ module.exports = class Server {
|
|||||||
const { address } = await readBody(event);
|
const { address } = await readBody(event);
|
||||||
await WireGuard.updateClientAddress({ clientId, address });
|
await WireGuard.updateClientAddress({ clientId, address });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
}))
|
||||||
|
.put('/api/wireguard/client/:clientId/address6', defineEventHandler(async (event) => {
|
||||||
|
const clientId = getRouterParam(event, 'clientId');
|
||||||
|
if (clientId === '__proto__' || clientId === 'constructor' || clientId === 'prototype') {
|
||||||
|
throw createError({ status: 403 });
|
||||||
|
}
|
||||||
|
const { address6 } = await readBody(event);
|
||||||
|
await WireGuard.updateClientAddress6({ clientId, address6 });
|
||||||
|
return { success: true };
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const safePathJoin = (base, target) => {
|
const safePathJoin = (base, target) => {
|
||||||
|
@ -17,6 +17,13 @@ module.exports = class Util {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isValidIPv6(str) {
|
||||||
|
// Regex source : https://stackoverflow.com/a/17871737
|
||||||
|
const regex = new RegExp('^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$');
|
||||||
|
const matches = str.match(regex);
|
||||||
|
return !!matches;
|
||||||
|
}
|
||||||
|
|
||||||
static promisify(fn) {
|
static promisify(fn) {
|
||||||
// eslint-disable-next-line func-names
|
// eslint-disable-next-line func-names
|
||||||
return function(req, res) {
|
return function(req, res) {
|
||||||
|
@ -15,8 +15,11 @@ const {
|
|||||||
WG_PORT,
|
WG_PORT,
|
||||||
WG_CONFIG_PORT,
|
WG_CONFIG_PORT,
|
||||||
WG_MTU,
|
WG_MTU,
|
||||||
|
WG_SRV_MTU,
|
||||||
WG_DEFAULT_DNS,
|
WG_DEFAULT_DNS,
|
||||||
|
WG_DEFAULT_DNS6,
|
||||||
WG_DEFAULT_ADDRESS,
|
WG_DEFAULT_ADDRESS,
|
||||||
|
WG_DEFAULT_ADDRESS6,
|
||||||
WG_PERSISTENT_KEEPALIVE,
|
WG_PERSISTENT_KEEPALIVE,
|
||||||
WG_ALLOWED_IPS,
|
WG_ALLOWED_IPS,
|
||||||
WG_PRE_UP,
|
WG_PRE_UP,
|
||||||
@ -45,12 +48,14 @@ module.exports = class WireGuard {
|
|||||||
log: 'echo ***hidden*** | wg pubkey',
|
log: 'echo ***hidden*** | wg pubkey',
|
||||||
});
|
});
|
||||||
const address = WG_DEFAULT_ADDRESS.replace('x', '1');
|
const address = WG_DEFAULT_ADDRESS.replace('x', '1');
|
||||||
|
const address6 = WG_DEFAULT_ADDRESS6.replace('x', '1');
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
server: {
|
server: {
|
||||||
privateKey,
|
privateKey,
|
||||||
publicKey,
|
publicKey,
|
||||||
address,
|
address,
|
||||||
|
address6,
|
||||||
},
|
},
|
||||||
clients: {},
|
clients: {},
|
||||||
};
|
};
|
||||||
@ -100,7 +105,8 @@ module.exports = class WireGuard {
|
|||||||
# Server
|
# Server
|
||||||
[Interface]
|
[Interface]
|
||||||
PrivateKey = ${config.server.privateKey}
|
PrivateKey = ${config.server.privateKey}
|
||||||
Address = ${config.server.address}/24
|
Address = ${config.server.address}/24, ${config.server.address6}/64
|
||||||
|
${WG_SRV_MTU ? `MTU = ${WG_SRV_MTU}` : ''}
|
||||||
ListenPort = ${WG_PORT}
|
ListenPort = ${WG_PORT}
|
||||||
PreUp = ${WG_PRE_UP}
|
PreUp = ${WG_PRE_UP}
|
||||||
PostUp = ${WG_POST_UP}
|
PostUp = ${WG_POST_UP}
|
||||||
@ -117,7 +123,7 @@ PostDown = ${WG_POST_DOWN}
|
|||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = ${client.publicKey}
|
PublicKey = ${client.publicKey}
|
||||||
${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
||||||
}AllowedIPs = ${client.address}/32`;
|
}AllowedIPs = ${client.address}/32, ${client.address6}/128`;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug('Config saving...');
|
debug('Config saving...');
|
||||||
@ -143,6 +149,7 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
|||||||
name: client.name,
|
name: client.name,
|
||||||
enabled: client.enabled,
|
enabled: client.enabled,
|
||||||
address: client.address,
|
address: client.address,
|
||||||
|
address6: client.address6,
|
||||||
publicKey: client.publicKey,
|
publicKey: client.publicKey,
|
||||||
createdAt: new Date(client.createdAt),
|
createdAt: new Date(client.createdAt),
|
||||||
updatedAt: new Date(client.updatedAt),
|
updatedAt: new Date(client.updatedAt),
|
||||||
@ -201,11 +208,14 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
|||||||
async getClientConfiguration({ clientId }) {
|
async getClientConfiguration({ clientId }) {
|
||||||
const config = await this.getConfig();
|
const config = await this.getConfig();
|
||||||
const client = await this.getClient({ clientId });
|
const client = await this.getClient({ clientId });
|
||||||
|
const isDnsSet = WG_DEFAULT_DNS || WG_DEFAULT_DNS6;
|
||||||
|
const dnsServers = [WG_DEFAULT_DNS, WG_DEFAULT_DNS6].filter((item) => !!item).join(', ');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
[Interface]
|
[Interface]
|
||||||
PrivateKey = ${client.privateKey ? `${client.privateKey}` : 'REPLACE_ME'}
|
PrivateKey = ${client.privateKey ? `${client.privateKey}` : 'REPLACE_ME'}
|
||||||
Address = ${client.address}/24
|
Address = ${client.address}/24, ${client.address6}/64
|
||||||
|
${isDnsSet ? `DNS = ${dnsServers}\n` : ''}\
|
||||||
${WG_DEFAULT_DNS ? `DNS = ${WG_DEFAULT_DNS}\n` : ''}\
|
${WG_DEFAULT_DNS ? `DNS = ${WG_DEFAULT_DNS}\n` : ''}\
|
||||||
${WG_MTU ? `MTU = ${WG_MTU}\n` : ''}\
|
${WG_MTU ? `MTU = ${WG_MTU}\n` : ''}\
|
||||||
|
|
||||||
@ -255,12 +265,29 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
|
|||||||
throw new Error('Maximum number of clients reached.');
|
throw new Error('Maximum number of clients reached.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let address6;
|
||||||
|
for (let i = 2; i < 255; i++) {
|
||||||
|
const client = Object.values(config.clients).find((client) => {
|
||||||
|
return client.address6 === WG_DEFAULT_ADDRESS6.replace('x', i.toString(16));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
address6 = WG_DEFAULT_ADDRESS6.replace('x', i.toString(16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!address6) {
|
||||||
|
throw new Error('Maximum number of clients reached.');
|
||||||
|
}
|
||||||
|
|
||||||
// Create Client
|
// Create Client
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
const client = {
|
const client = {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
address,
|
address,
|
||||||
|
address6,
|
||||||
privateKey,
|
privateKey,
|
||||||
publicKey,
|
publicKey,
|
||||||
preSharedKey,
|
preSharedKey,
|
||||||
@ -327,6 +354,19 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
|
|||||||
await this.saveConfig();
|
await this.saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateClientAddress6({ clientId, address6 }) {
|
||||||
|
const client = await this.getClient({ clientId });
|
||||||
|
|
||||||
|
if (!Util.isValidIPv6(address6)) {
|
||||||
|
throw new ServerError(`Invalid Address: ${address6}`, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
client.address6 = address6;
|
||||||
|
client.updatedAt = new Date();
|
||||||
|
|
||||||
|
await this.saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
async __reloadConfig() {
|
async __reloadConfig() {
|
||||||
await this.__buildConfig();
|
await this.__buildConfig();
|
||||||
await this.__syncConfig();
|
await this.__syncConfig();
|
||||||
|
@ -248,6 +248,31 @@
|
|||||||
<div v-if="uiTrafficStats"
|
<div v-if="uiTrafficStats"
|
||||||
class="flex gap-2 items-center shrink-0 text-gray-400 dark:text-neutral-400 text-xs mt-px justify-end">
|
class="flex gap-2 items-center shrink-0 text-gray-400 dark:text-neutral-400 text-xs mt-px justify-end">
|
||||||
|
|
||||||
|
<!-- Address6 -->
|
||||||
|
<span class="group">
|
||||||
|
|
||||||
|
<!-- Show -->
|
||||||
|
<input v-show="clientEditAddress6Id === client.id" v-model="clientEditAddress6"
|
||||||
|
v-on:keyup.enter="updateClientAddress6(client, clientEditAddress6); clientEditAddress6 = null; clientEditAddress6Id = null;"
|
||||||
|
v-on:keyup.escape="clientEditAddress6 = null; clientEditAddress6Id = null;"
|
||||||
|
:ref="'client-' + client.id + '-address6'"
|
||||||
|
class="rounded border-2 border-gray-100 focus:border-gray-200 outline-none w-20 text-black" />
|
||||||
|
<span v-show="clientEditAddress6Id !== client.id"
|
||||||
|
class="inline-block border-t-2 border-b-2 border-transparent">{{client.address6}}</span>
|
||||||
|
|
||||||
|
<!-- Edit -->
|
||||||
|
<span v-show="clientEditAddress6Id !== client.id"
|
||||||
|
@click="clientEditAddress6 = client.address6; clientEditAddress6Id = client.id; setTimeout(() => $refs['client-' + client.id + '-address6'][0].select(), 1);"
|
||||||
|
class="cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-4 w-4 inline align-middle opacity-25 hover:opacity-100" fill="none"
|
||||||
|
viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<!-- Transfer TX -->
|
<!-- Transfer TX -->
|
||||||
<div class="min-w-20 md:min-w-24" v-if="client.transferTx">
|
<div class="min-w-20 md:min-w-24" v-if="client.transferTx">
|
||||||
<span class="flex gap-1" :title="$t('totalDownload') + bytes(client.transferTx)">
|
<span class="flex gap-1" :title="$t('totalDownload') + bytes(client.transferTx)">
|
||||||
|
@ -138,6 +138,14 @@ class API {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateClientAddress6({ clientId, address6 }) {
|
||||||
|
return this.call({
|
||||||
|
method: 'put',
|
||||||
|
path: `/wireguard/client/${clientId}/address6/`,
|
||||||
|
body: { address6 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async restoreConfiguration(file) {
|
async restoreConfiguration(file) {
|
||||||
return this.call({
|
return this.call({
|
||||||
method: 'put',
|
method: 'put',
|
||||||
|
@ -63,6 +63,8 @@ new Vue({
|
|||||||
clientEditNameId: null,
|
clientEditNameId: null,
|
||||||
clientEditAddress: null,
|
clientEditAddress: null,
|
||||||
clientEditAddressId: null,
|
clientEditAddressId: null,
|
||||||
|
clientEditAddress6: null,
|
||||||
|
clientEditAddress6Id: null,
|
||||||
qrcode: null,
|
qrcode: null,
|
||||||
|
|
||||||
currentRelease: null,
|
currentRelease: null,
|
||||||
@ -299,6 +301,11 @@ new Vue({
|
|||||||
.catch((err) => alert(err.message || err.toString()))
|
.catch((err) => alert(err.message || err.toString()))
|
||||||
.finally(() => this.refresh().catch(console.error));
|
.finally(() => this.refresh().catch(console.error));
|
||||||
},
|
},
|
||||||
|
updateClientAddress6(client, address6) {
|
||||||
|
this.api.updateClientAddress6({ clientId: client.id, address6 })
|
||||||
|
.catch((err) => alert(err.message || err.toString()))
|
||||||
|
.finally(() => this.refresh().catch(console.error));
|
||||||
|
},
|
||||||
restoreConfig(e) {
|
restoreConfig(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const file = e.currentTarget.files.item(0);
|
const file = e.currentTarget.files.item(0);
|
||||||
|
@ -6,7 +6,7 @@ After=network-online.target nss-lookup.target
|
|||||||
Environment="WG_HOST=raspberrypi.local" # Change this to your host's public address or static public ip.
|
Environment="WG_HOST=raspberrypi.local" # Change this to your host's public address or static public ip.
|
||||||
Environment="PASSWORD=REPLACEME" # When set, requires a password when logging in to the Web UI, to disable add a hashtag
|
Environment="PASSWORD=REPLACEME" # When set, requires a password when logging in to the Web UI, to disable add a hashtag
|
||||||
#Environment="WG_DEFAULT_ADDRESS=10.0.8.x" #Clients IP address range.
|
#Environment="WG_DEFAULT_ADDRESS=10.0.8.x" #Clients IP address range.
|
||||||
#Environment="WG_DEFAULT_DNS=10.0.8.1, 1.1.1.1" #DNS server clients will use. If set to blank value, clients will not use any DNS.
|
#Environment="WG_DEFAULT_DNS=10.0.8.1, 84.200.69.80" #DNS server clients will use. If set to blank value, clients will not use any DNS.
|
||||||
#Environment="WG_ALLOWED_IPS=0.0.0.0/0,::/0" #Allowed IPs clients will use.
|
#Environment="WG_ALLOWED_IPS=0.0.0.0/0,::/0" #Allowed IPs clients will use.
|
||||||
#Environment="WG_DEVICE=ens1" #Ethernet device the wireguard traffic should be forwarded through.
|
#Environment="WG_DEVICE=ens1" #Ethernet device the wireguard traffic should be forwarded through.
|
||||||
#Environment="PORT=80" #TCP port for Web UI. Default : 51821
|
#Environment="PORT=80" #TCP port for Web UI. Default : 51821
|
||||||
|
Loading…
x
Reference in New Issue
Block a user