diff --git a/README.md b/README.md index c5b9d619c..d1227c5fa 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,7 @@ 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 always listen on 51820 inside the Docker container. | | `WG_MTU` | `null` | `1420` | The MTU the clients will use. Server uses default WG MTU. | | `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.0` | `10.6.0.0` | Clients IP address range. | -| `WG_DEFAULT_ADDRESS_RANGE` | `24` | `32` | Value to define CIDR Range. If not defined fallback to `24` +| `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_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. | diff --git a/docker-compose.yml b/docker-compose.yml index 66f15dc90..5424b68ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,8 +15,7 @@ services: # Optional: # - PASSWORD=foobar123 # - WG_PORT=51820 - # - WG_DEFAULT_ADDRESS=10.8.0.0 - # - WG_DEFAULT_ADDRESS_RANGE=24 + # - WG_DEFAULT_ADDRESS=10.8.0.x # - WG_DEFAULT_DNS=1.1.1.1 # - WG_MTU=1420 # - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24 diff --git a/src/config.js b/src/config.js index c50b7cf63..1fff4c275 100644 --- a/src/config.js +++ b/src/config.js @@ -1,7 +1,5 @@ 'use strict'; -const ip = require('ip'); - const { release } = require('./package.json'); module.exports.RELEASE = release; @@ -14,21 +12,15 @@ module.exports.WG_HOST = process.env.WG_HOST; module.exports.WG_PORT = process.env.WG_PORT || '51820'; module.exports.WG_MTU = process.env.WG_MTU || null; module.exports.WG_PERSISTENT_KEEPALIVE = process.env.WG_PERSISTENT_KEEPALIVE || '0'; -module.exports.WG_DEFAULT_ADDRESS = (process.env.WG_DEFAULT_ADDRESS && process.env.WG_DEFAULT_ADDRESS.replace('x', '0')) || '10.8.0.0'; -module.exports.WG_DEFAULT_ADDRESS_RANGE = process.env.WG_DEFAULT_ADDRESS_RANGE || '24'; +module.exports.WG_DEFAULT_ADDRESS = process.env.WG_DEFAULT_ADDRESS || '10.8.0.x'; module.exports.WG_DEFAULT_DNS = typeof process.env.WG_DEFAULT_DNS === 'string' ? process.env.WG_DEFAULT_DNS : '1.1.1.1'; module.exports.WG_ALLOWED_IPS = process.env.WG_ALLOWED_IPS || '0.0.0.0/0, ::/0'; -module.exports.WG_SUBNET = ip.cidrSubnet(`${module.exports.WG_DEFAULT_ADDRESS}/${module.exports.WG_DEFAULT_ADDRESS_RANGE}`); -module.exports.WG_SERVER_ADDRESS = module.exports.WG_SUBNET.firstAddress; -module.exports.WG_CLIENT_FIRST_ADDRESS = ip.toLong(module.exports.WG_SERVER_ADDRESS) + 1; -module.exports.WG_CLIENT_LAST_ADDRESS = ip.toLong(module.exports.WG_SUBNET.lastAddress) - 1; // Exclude the broadcast address - module.exports.WG_PRE_UP = process.env.WG_PRE_UP || ''; module.exports.WG_POST_UP = process.env.WG_POST_UP || ` -iptables -t nat -A POSTROUTING -s ${module.exports.WG_SERVER_ADDRESS}/${module.exports.WG_DEFAULT_ADDRESS_RANGE} -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 51820 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; @@ -36,7 +28,7 @@ iptables -A FORWARD -o wg0 -j ACCEPT; module.exports.WG_PRE_DOWN = process.env.WG_PRE_DOWN || ''; module.exports.WG_POST_DOWN = process.env.WG_POST_DOWN || ` -iptables -t nat -D POSTROUTING -s ${module.exports.WG_SERVER_ADDRESS}/${module.exports.WG_DEFAULT_ADDRESS_RANGE} -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 51820 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; diff --git a/src/lib/Util.js b/src/lib/Util.js index 829425996..cc6e89c2d 100644 --- a/src/lib/Util.js +++ b/src/lib/Util.js @@ -4,6 +4,19 @@ const childProcess = require('child_process'); module.exports = class Util { + static isValidIPv4(str) { + const blocks = str.split('.'); + if (blocks.length !== 4) return false; + + for (let value of blocks) { + value = parseInt(value, 10); + if (Number.isNaN(value)) return false; + if (value < 0 || value > 255) return false; + } + + return true; + } + static promisify(fn) { // eslint-disable-next-line func-names return function(req, res) { diff --git a/src/lib/WireGuard.js b/src/lib/WireGuard.js index de36e1e1e..739676fb9 100644 --- a/src/lib/WireGuard.js +++ b/src/lib/WireGuard.js @@ -4,7 +4,6 @@ const fs = require('fs').promises; const path = require('path'); const debug = require('debug')('WireGuard'); -const ip = require('ip'); const uuid = require('uuid'); const QRCode = require('qrcode'); @@ -17,12 +16,9 @@ const { WG_PORT, WG_MTU, WG_DEFAULT_DNS, - WG_DEFAULT_ADDRESS_RANGE, + WG_DEFAULT_ADDRESS, WG_PERSISTENT_KEEPALIVE, WG_ALLOWED_IPS, - WG_SERVER_ADDRESS, - WG_CLIENT_FIRST_ADDRESS, - WG_CLIENT_LAST_ADDRESS, WG_PRE_UP, WG_POST_UP, WG_PRE_DOWN, @@ -49,15 +45,13 @@ module.exports = class WireGuard { const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, { log: 'echo ***hidden*** | wg pubkey', }); - const address = WG_SERVER_ADDRESS; - const cidrBlock = WG_DEFAULT_ADDRESS_RANGE; + const address = WG_DEFAULT_ADDRESS.replace('x', '1'); config = { server: { privateKey, publicKey, address, - cidrBlock, }, clients: {}, }; @@ -73,7 +67,7 @@ module.exports = class WireGuard { throw err; }); - // await Util.exec(`iptables -t nat -A POSTROUTING -s ${WG_SERVER_ADDRESS}/${WG_DEFAULT_ADDRESS_RANGE} -o ' + WG_DEVICE + ' -j MASQUERADE`); + // await Util.exec(`iptables -t nat -A POSTROUTING -s ${WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ' + WG_DEVICE + ' -j MASQUERADE`); // await Util.exec('iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT'); // await Util.exec('iptables -A FORWARD -i wg0 -j ACCEPT'); // await Util.exec('iptables -A FORWARD -o wg0 -j ACCEPT'); @@ -100,7 +94,7 @@ module.exports = class WireGuard { # Server [Interface] PrivateKey = ${config.server.privateKey} -Address = ${config.server.address}/${config.server.cidrBlock} +Address = ${config.server.address}/24 ListenPort = 51820 PreUp = ${WG_PRE_UP} PostUp = ${WG_POST_UP} @@ -143,7 +137,6 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : '' name: client.name, enabled: client.enabled, address: client.address, - cidrBlock: client.cidrBlock, publicKey: client.publicKey, createdAt: new Date(client.createdAt), updatedAt: new Date(client.updatedAt), @@ -206,7 +199,7 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : '' return ` [Interface] PrivateKey = ${client.privateKey ? `${client.privateKey}` : 'REPLACE_ME'} -Address = ${client.address}/${client.cidrBlock} +Address = ${client.address}/24 ${WG_DEFAULT_DNS ? `DNS = ${WG_DEFAULT_DNS}\n` : ''}\ ${WG_MTU ? `MTU = ${WG_MTU}\n` : ''}\ @@ -237,16 +230,15 @@ Endpoint = ${WG_HOST}:${WG_PORT}`; const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`); const preSharedKey = await Util.exec('wg genpsk'); - // find next IP + // Calculate next IP let address; - for (let i = WG_CLIENT_FIRST_ADDRESS; i <= WG_CLIENT_LAST_ADDRESS; i++) { - const currentIp = ip.fromLong(i); + for (let i = 2; i < 255; i++) { const client = Object.values(config.clients).find((client) => { - return client.address === currentIp; + return client.address === WG_DEFAULT_ADDRESS.replace('x', i); }); if (!client) { - address = currentIp; + address = WG_DEFAULT_ADDRESS.replace('x', i); break; } } @@ -257,12 +249,10 @@ Endpoint = ${WG_HOST}:${WG_PORT}`; // Create Client const id = uuid.v4(); - const cidrBlock = WG_DEFAULT_ADDRESS_RANGE; const client = { id, name, address, - cidrBlock, privateKey, publicKey, preSharedKey, @@ -319,7 +309,7 @@ Endpoint = ${WG_HOST}:${WG_PORT}`; async updateClientAddress({ clientId, address }) { const client = await this.getClient({ clientId }); - if (!ip.isV4Format(address)) { + if (!Util.isValidIPv4(address)) { throw new ServerError(`Invalid Address: ${address}`, 400); } diff --git a/src/package-lock.json b/src/package-lock.json index 72e20cf8c..e02f2b160 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -13,7 +13,6 @@ "debug": "^4.3.4", "express-session": "^1.18.0", "h3": "^1.11.1", - "ip": "^2.0.1", "qrcode": "^1.5.3", "uuid": "^9.0.1" }, @@ -2655,11 +2654,6 @@ "node": ">= 0.4" } }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" - }, "node_modules/iron-webcrypto": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.1.0.tgz", diff --git a/src/package.json b/src/package.json index ff1d5517c..3b6b94d97 100644 --- a/src/package.json +++ b/src/package.json @@ -16,7 +16,6 @@ "bcryptjs": "^2.4.3", "debug": "^4.3.4", "express-session": "^1.18.0", - "ip": "^2.0.1", "h3": "^1.11.1", "qrcode": "^1.5.3", "uuid": "^9.0.1" diff --git a/wg-easy.service b/wg-easy.service index e1ea96ea4..bcdf72fdf 100644 --- a/wg-easy.service +++ b/wg-easy.service @@ -5,8 +5,7 @@ After=network-online.target nss-lookup.target [Service] 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="WG_DEFAULT_ADDRESS=10.0.8.0" # Clients IP addresses. -#Environment="WG_DEFAULT_ADDRESS_RANGE=32" # Client CIDR Range (if not set fallback to 24) +#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_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.