Browse Source

Implemented CIDR support for WG_DEFAULT_ADDRESS

The `.x` syntax is still supported
pull/393/head
BrainStone 4 years ago
parent
commit
8bd1c0ff47
No known key found for this signature in database GPG Key ID: 66CCC234C2CEB306
  1. 2
      README.md
  2. 2
      docker-compose.yml
  3. 6
      src/config.js
  4. 52
      src/lib/WireGuard.js
  5. 3586
      src/package-lock.json
  6. 4
      src/package.json

2
README.md

@ -86,7 +86,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_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_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_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.0/24` | `10.6.0.x` or `10.6.8.0/22` | Clients IP address range. |
| `WG_DEFAULT_DNS` | `1.1.1.1` | `8.8.8.8, 8.8.4.4` | DNS server clients will use. | | `WG_DEFAULT_DNS` | `1.1.1.1` | `8.8.8.8, 8.8.4.4` | DNS 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/WeeJeWel/wg-easy/blob/master/src/config.js#L19) for the default value. | | `WG_PRE_UP` | `...` | - | See [config.js](https://github.com/WeeJeWel/wg-easy/blob/master/src/config.js#L19) for the default value. |

2
docker-compose.yml

@ -9,7 +9,7 @@ services:
# Optional: # Optional:
# - PASSWORD=foobar123 # - PASSWORD=foobar123
# - WG_PORT=51820 # - WG_PORT=51820
# - WG_DEFAULT_ADDRESS=10.8.0.x # - WG_DEFAULT_ADDRESS=10.8.0.0/24
# - WG_DEFAULT_DNS=1.1.1.1 # - WG_DEFAULT_DNS=1.1.1.1
# - WG_MTU=1420 # - WG_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

6
src/config.js

@ -10,7 +10,7 @@ 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_MTU = process.env.WG_MTU || null; module.exports.WG_MTU = process.env.WG_MTU || null;
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.replace(/\.x$/, '.0/24') || '10.8.0.0/24';
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'; : '1.1.1.1';
@ -18,8 +18,8 @@ module.exports.WG_ALLOWED_IPS = process.env.WG_ALLOWED_IPS || '0.0.0.0/0, ::/0';
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 || `
iptables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS} -o eth0 -j MASQUERADE;
iptables -A INPUT -p udp -m udp --dport 51820 -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(' '); `.split('\n').join(' ');

52
src/lib/WireGuard.js

@ -6,6 +6,8 @@ const path = require('path');
const debug = require('debug')('WireGuard'); const debug = require('debug')('WireGuard');
const uuid = require('uuid'); const uuid = require('uuid');
const QRCode = require('qrcode'); const QRCode = require('qrcode');
const { BigInteger } = require('jsbn');
const { Address4 } = require('ip-address');
const Util = require('./Util'); const Util = require('./Util');
const ServerError = require('./ServerError'); const ServerError = require('./ServerError');
@ -25,6 +27,11 @@ const {
WG_POST_DOWN, WG_POST_DOWN,
} = require('../config'); } = require('../config');
// Address constants
const address = new Address4(WG_DEFAULT_ADDRESS);
const startAddressI = address.startAddressExclusive().bigInteger();
const endAddressI = address.endAddressExclusive().bigInteger();
module.exports = class WireGuard { module.exports = class WireGuard {
async getConfig() { async getConfig() {
@ -45,7 +52,7 @@ module.exports = class WireGuard {
const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, { const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, {
log: 'echo ***hidden*** | wg pubkey', log: 'echo ***hidden*** | wg pubkey',
}); });
const address = WG_DEFAULT_ADDRESS.replace('x', '1'); const address = await this.__getNthHostAddress(0);
config = { config = {
server: { server: {
@ -67,10 +74,7 @@ module.exports = class WireGuard {
throw err; throw err;
}); });
// await Util.exec(`iptables -t nat -A POSTROUTING -s ${WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o eth0 -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');
await this.__syncConfig(); await this.__syncConfig();
return config; return config;
@ -233,20 +237,23 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
const preSharedKey = await Util.exec('wg genpsk'); const preSharedKey = await Util.exec('wg genpsk');
// Calculate next IP // Calculate next IP
let address; try {
for (let i = 2; i < 255; i++) { let address;
const client = Object.values(config.clients).find(client => { for (let i = 1; ; i++) {
return client.address === WG_DEFAULT_ADDRESS.replace('x', i); address = await this.__getNthHostAddress(i);
}); // warns about address being used unsafely, but since the function only exists in the loop
// scope this isn't an issue
// eslint-disable-next-line no-loop-func
const client = Object.values(config.clients).find(client => {
return address;
});
if (!client) { if (!client) {
address = WG_DEFAULT_ADDRESS.replace('x', i); break;
break; }
} }
} } catch (error) {
throw new Error('Maximum number of clients reached.', error);
if (!address) {
throw new Error('Maximum number of clients reached.');
} }
// Create Client // Create Client
@ -320,4 +327,15 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
await this.saveConfig(); await this.saveConfig();
} }
async __getNthHostAddress(n) {
const bigN = new BigInteger(n.toString());
const newAddressI = startAddressI.add(bigN);
if (newAddressI.compareTo(endAddressI) > 0) {
throw new Error(`Subnet ${WG_DEFAULT_ADDRESS} doesn't contain ${n} host addresses!`);
}
return Address4.fromBigInteger(newAddressI).correctForm();
}
}; };

3586
src/package-lock.json

File diff suppressed because it is too large

4
src/package.json

@ -15,6 +15,8 @@
"debug": "^4.3.1", "debug": "^4.3.1",
"express": "^4.17.1", "express": "^4.17.1",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"ip-address": "^8.1.0",
"jsbn": "^1.1.0",
"qrcode": "^1.4.4", "qrcode": "^1.4.4",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
@ -30,4 +32,4 @@
"engines": { "engines": {
"node": "14" "node": "14"
} }
} }

Loading…
Cancel
Save