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_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.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_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. |

2
docker-compose.yml

@ -9,7 +9,7 @@ services:
# Optional:
# - PASSWORD=foobar123
# - 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_MTU=1420
# - 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_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 || '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'
? process.env.WG_DEFAULT_DNS
: '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_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 -A INPUT -p udp -m udp --dport 51820 -j ACCEPT;
iptables -t nat -A POSTROUTING -s ${module.exports.WG_DEFAULT_ADDRESS} -o eth0 -j MASQUERADE;
iptables -A INPUT -p udp -m udp --dport ${module.exports.WG_PORT} -j ACCEPT;
iptables -A FORWARD -i wg0 -j ACCEPT;
iptables -A FORWARD -o wg0 -j ACCEPT;
`.split('\n').join(' ');

52
src/lib/WireGuard.js

@ -6,6 +6,8 @@ const path = require('path');
const debug = require('debug')('WireGuard');
const uuid = require('uuid');
const QRCode = require('qrcode');
const { BigInteger } = require('jsbn');
const { Address4 } = require('ip-address');
const Util = require('./Util');
const ServerError = require('./ServerError');
@ -25,6 +27,11 @@ const {
WG_POST_DOWN,
} = 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 {
async getConfig() {
@ -45,7 +52,7 @@ module.exports = class WireGuard {
const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, {
log: 'echo ***hidden*** | wg pubkey',
});
const address = WG_DEFAULT_ADDRESS.replace('x', '1');
const address = await this.__getNthHostAddress(0);
config = {
server: {
@ -67,10 +74,7 @@ module.exports = class WireGuard {
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();
return config;
@ -233,20 +237,23 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
const preSharedKey = await Util.exec('wg genpsk');
// Calculate next IP
let address;
for (let i = 2; i < 255; i++) {
const client = Object.values(config.clients).find(client => {
return client.address === WG_DEFAULT_ADDRESS.replace('x', i);
});
try {
let address;
for (let i = 1; ; 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) {
address = WG_DEFAULT_ADDRESS.replace('x', i);
break;
if (!client) {
break;
}
}
}
if (!address) {
throw new Error('Maximum number of clients reached.');
} catch (error) {
throw new Error('Maximum number of clients reached.', error);
}
// Create Client
@ -320,4 +327,15 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
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",
"express": "^4.17.1",
"express-session": "^1.17.1",
"ip-address": "^8.1.0",
"jsbn": "^1.1.0",
"qrcode": "^1.4.4",
"uuid": "^8.3.2"
},
@ -30,4 +32,4 @@
"engines": {
"node": "14"
}
}
}

Loading…
Cancel
Save