@@ -8,13 +8,11 @@
|
|||||||
|
|
||||||
You have found the easiest way to install & manage WireGuard on any Linux host!
|
You have found the easiest way to install & manage WireGuard on any Linux host!
|
||||||
|
|
||||||
<!-- markdownlint-disable MD033 -->
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./assets/screenshot.png" alt="screenshot" width="802" />
|
<img src="./assets/screenshot.png" width="802" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* All-in-one: WireGuard + Web UI.
|
* All-in-one: WireGuard + Web UI.
|
||||||
* Easy installation, simple to use.
|
* Easy installation, simple to use.
|
||||||
* List, create, edit, delete, enable & disable clients.
|
* List, create, edit, delete, enable & disable clients.
|
||||||
@@ -28,7 +26,6 @@ You have found the easiest way to install & manage WireGuard on any Linux host!
|
|||||||
* UI_TRAFFIC_STATS (default off)
|
* UI_TRAFFIC_STATS (default off)
|
||||||
* UI_SHOW_LINKS (default off)
|
* UI_SHOW_LINKS (default off)
|
||||||
* WG_ENABLE_EXPIRES_TIME (default off)
|
* WG_ENABLE_EXPIRES_TIME (default off)
|
||||||
* Prometheus metrics support
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -37,7 +34,7 @@ You have found the easiest way to install & manage WireGuard on any Linux host!
|
|||||||
|
|
||||||
## Versions
|
## Versions
|
||||||
|
|
||||||
We provide more then 1 docker image to get, this will help you decide which one is best for you. <br\>
|
We provide more then 1 docker image to get, this will help you decide which one is best for you. <br>
|
||||||
For **stable** versions instead of nightly or development please read **README** from the **production** branch!
|
For **stable** versions instead of nightly or development please read **README** from the **production** branch!
|
||||||
|
|
||||||
| tag | Branch | Example | Description |
|
| tag | Branch | Example | Description |
|
||||||
@@ -65,7 +62,7 @@ And log in again.
|
|||||||
|
|
||||||
To automatically install & run wg-easy, simply run:
|
To automatically install & run wg-easy, simply run:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name=wg-easy \
|
--name=wg-easy \
|
||||||
-e LANG=de \
|
-e LANG=de \
|
||||||
@@ -90,8 +87,6 @@ To automatically install & run wg-easy, simply run:
|
|||||||
|
|
||||||
The Web UI will now be available on `http://0.0.0.0:51821`.
|
The Web UI will now be available on `http://0.0.0.0:51821`.
|
||||||
|
|
||||||
The Prometheus metrics will now be available on `http://0.0.0.0:51821/metrics`. Grafana dashboard [21733](https://grafana.com/grafana/dashboards/21733-wireguard/)
|
|
||||||
|
|
||||||
> 💡 Your configuration files will be saved in `~/.wg-easy`
|
> 💡 Your configuration files will be saved in `~/.wg-easy`
|
||||||
|
|
||||||
WireGuard Easy can be launched with Docker Compose as well - just download
|
WireGuard Easy can be launched with Docker Compose as well - just download
|
||||||
@@ -131,7 +126,7 @@ These options can be configured by setting environment variables using `-e KEY="
|
|||||||
| `UI_SHOW_LINKS` | `false` | `true` | Enable display of a short download link in Web UI |
|
| `UI_SHOW_LINKS` | `false` | `true` | Enable display of a short download link in Web UI |
|
||||||
| `MAX_AGE` | `0` | `1440` | The maximum age of Web UI sessions in minutes. `0` means that the session will exist until the browser is closed. |
|
| `MAX_AGE` | `0` | `1440` | The maximum age of Web UI sessions in minutes. `0` means that the session will exist until the browser is closed. |
|
||||||
| `UI_ENABLE_SORT_CLIENTS` | `false` | `true` | Enable UI sort clients by name |
|
| `UI_ENABLE_SORT_CLIENTS` | `false` | `true` | Enable UI sort clients by name |
|
||||||
| `ENABLE_PROMETHEUS_METRICS` | `true` | `true` | Enable Prometheus metrics `http://0.0.0.0:51821/metrics` and `http://0.0.0.0:51821/metrics/json`|
|
|
||||||
|
|
||||||
> If you change `WG_PORT`, make sure to also change the exposed port.
|
> If you change `WG_PORT`, make sure to also change the exposed port.
|
||||||
|
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ services:
|
|||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- SYS_MODULE
|
- SYS_MODULE
|
||||||
environment:
|
environment:
|
||||||
# - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG # 'foobar123'
|
# - PASSWORD=p
|
||||||
- WG_HOST=192.168.1.233
|
- WG_HOST=192.168.1.233
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ services:
|
|||||||
# - UI_SHOW_LINKS=true
|
# - UI_SHOW_LINKS=true
|
||||||
# - UI_ENABLE_SORT_CLIENTS=true
|
# - UI_ENABLE_SORT_CLIENTS=true
|
||||||
# - WG_ENABLE_EXPIRES_TIME=true
|
# - WG_ENABLE_EXPIRES_TIME=true
|
||||||
# - ENABLE_PROMETHEUS_METRICS=false
|
|
||||||
|
|
||||||
image: ghcr.io/wg-easy/wg-easy
|
image: ghcr.io/wg-easy/wg-easy
|
||||||
container_name: wg-easy
|
container_name: wg-easy
|
||||||
|
|||||||
@@ -41,4 +41,3 @@ module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
|
|||||||
module.exports.UI_SHOW_LINKS = process.env.UI_SHOW_LINKS || 'false';
|
module.exports.UI_SHOW_LINKS = process.env.UI_SHOW_LINKS || 'false';
|
||||||
module.exports.UI_ENABLE_SORT_CLIENTS = process.env.UI_ENABLE_SORT_CLIENTS || 'false';
|
module.exports.UI_ENABLE_SORT_CLIENTS = process.env.UI_ENABLE_SORT_CLIENTS || 'false';
|
||||||
module.exports.WG_ENABLE_EXPIRES_TIME = process.env.WG_ENABLE_EXPIRES_TIME || 'false';
|
module.exports.WG_ENABLE_EXPIRES_TIME = process.env.WG_ENABLE_EXPIRES_TIME || 'false';
|
||||||
module.exports.ENABLE_PROMETHEUS_METRICS = process.env.ENABLE_PROMETHEUS_METRICS || 'true';
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ const {
|
|||||||
UI_SHOW_LINKS,
|
UI_SHOW_LINKS,
|
||||||
UI_ENABLE_SORT_CLIENTS,
|
UI_ENABLE_SORT_CLIENTS,
|
||||||
WG_ENABLE_EXPIRES_TIME,
|
WG_ENABLE_EXPIRES_TIME,
|
||||||
ENABLE_PROMETHEUS_METRICS,
|
|
||||||
} = require('../config');
|
} = require('../config');
|
||||||
|
|
||||||
const requiresPassword = !!PASSWORD_HASH;
|
const requiresPassword = !!PASSWORD_HASH;
|
||||||
@@ -287,20 +286,6 @@ module.exports = class Server {
|
|||||||
const { expireDate } = await readBody(event);
|
const { expireDate } = await readBody(event);
|
||||||
await WireGuard.updateClientExpireDate({ clientId, expireDate });
|
await WireGuard.updateClientExpireDate({ clientId, expireDate });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}))
|
|
||||||
.get('/metrics', defineEventHandler(async (event) => {
|
|
||||||
setHeader(event, 'Content-Type', 'text/plain');
|
|
||||||
if (ENABLE_PROMETHEUS_METRICS === 'true') {
|
|
||||||
return WireGuard.getMetrics();
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}))
|
|
||||||
.get('/metrics/json', defineEventHandler(async (event) => {
|
|
||||||
setHeader(event, 'Content-Type', 'application/json');
|
|
||||||
if (ENABLE_PROMETHEUS_METRICS === 'true') {
|
|
||||||
return WireGuard.getMetricsJSON();
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const safePathJoin = (base, target) => {
|
const safePathJoin = (base, target) => {
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
|||||||
latestHandshakeAt: null,
|
latestHandshakeAt: null,
|
||||||
transferRx: null,
|
transferRx: null,
|
||||||
transferTx: null,
|
transferTx: null,
|
||||||
endpoint: null,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Loop WireGuard status
|
// Loop WireGuard status
|
||||||
@@ -187,7 +186,6 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
|
|||||||
client.latestHandshakeAt = latestHandshakeAt === '0'
|
client.latestHandshakeAt = latestHandshakeAt === '0'
|
||||||
? null
|
? null
|
||||||
: new Date(Number(`${latestHandshakeAt}000`));
|
: new Date(Number(`${latestHandshakeAt}000`));
|
||||||
client.endpoint = endpoint === '(none)' ? null : endpoint;
|
|
||||||
client.transferRx = Number(transferRx);
|
client.transferRx = Number(transferRx);
|
||||||
client.transferTx = Number(transferTx);
|
client.transferTx = Number(transferTx);
|
||||||
client.persistentKeepalive = persistentKeepalive;
|
client.persistentKeepalive = persistentKeepalive;
|
||||||
@@ -400,75 +398,4 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMetrics() {
|
|
||||||
const clients = await this.getClients();
|
|
||||||
let wireguardPeerCount = 0;
|
|
||||||
let wireguardEnabledPeersCount = 0;
|
|
||||||
let wireguardConnectedPeersCount = 0;
|
|
||||||
let wireguardSentBytes = '';
|
|
||||||
let wireguardReceivedBytes = '';
|
|
||||||
let wireguardLatestHandshakeSeconds = '';
|
|
||||||
for (const client of Object.values(clients)) {
|
|
||||||
wireguardPeerCount++;
|
|
||||||
if (client.enabled === true) {
|
|
||||||
wireguardEnabledPeersCount++;
|
|
||||||
}
|
|
||||||
if (client.endpoint !== null) {
|
|
||||||
wireguardConnectedPeersCount++;
|
|
||||||
}
|
|
||||||
wireguardSentBytes += `wireguard_sent_bytes{interface="wg0",enabled="${client.enabled}",address="${client.address}",name="${client.name}"} ${Number(client.transferTx)}\n`;
|
|
||||||
wireguardReceivedBytes += `wireguard_received_bytes{interface="wg0",enabled="${client.enabled}",address="${client.address}",name="${client.name}"} ${Number(client.transferRx)}\n`;
|
|
||||||
wireguardLatestHandshakeSeconds += `wireguard_latest_handshake_seconds{interface="wg0",enabled="${client.enabled}",address="${client.address}",name="${client.name}"} ${client.latestHandshakeAt ? (new Date().getTime() - new Date(client.latestHandshakeAt).getTime()) / 1000 : 0}\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let returnText = '# HELP wg-easy and wireguard metrics\n';
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_configured_peers\n';
|
|
||||||
returnText += '# TYPE wireguard_configured_peers gauge\n';
|
|
||||||
returnText += `wireguard_configured_peers{interface="wg0"} ${Number(wireguardPeerCount)}\n`;
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_enabled_peers\n';
|
|
||||||
returnText += '# TYPE wireguard_enabled_peers gauge\n';
|
|
||||||
returnText += `wireguard_enabled_peers{interface="wg0"} ${Number(wireguardEnabledPeersCount)}\n`;
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_connected_peers\n';
|
|
||||||
returnText += '# TYPE wireguard_connected_peers gauge\n';
|
|
||||||
returnText += `wireguard_connected_peers{interface="wg0"} ${Number(wireguardConnectedPeersCount)}\n`;
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_sent_bytes Bytes sent to the peer\n';
|
|
||||||
returnText += '# TYPE wireguard_sent_bytes counter\n';
|
|
||||||
returnText += `${wireguardSentBytes}`;
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_received_bytes Bytes received from the peer\n';
|
|
||||||
returnText += '# TYPE wireguard_received_bytes counter\n';
|
|
||||||
returnText += `${wireguardReceivedBytes}`;
|
|
||||||
|
|
||||||
returnText += '\n# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake\n';
|
|
||||||
returnText += '# TYPE wireguard_latest_handshake_seconds gauge\n';
|
|
||||||
returnText += `${wireguardLatestHandshakeSeconds}`;
|
|
||||||
|
|
||||||
return returnText;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMetricsJSON() {
|
|
||||||
const clients = await this.getClients();
|
|
||||||
let wireguardPeerCount = 0;
|
|
||||||
let wireguardEnabledPeersCount = 0;
|
|
||||||
let wireguardConnectedPeersCount = 0;
|
|
||||||
for (const client of Object.values(clients)) {
|
|
||||||
wireguardPeerCount++;
|
|
||||||
if (client.enabled === true) {
|
|
||||||
wireguardEnabledPeersCount++;
|
|
||||||
}
|
|
||||||
if (client.endpoint !== null) {
|
|
||||||
wireguardConnectedPeersCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
wireguard_configured_peers: Number(wireguardPeerCount),
|
|
||||||
wireguard_enabled_peers: Number(wireguardEnabledPeersCount),
|
|
||||||
wireguard_connected_peers: Number(wireguardConnectedPeersCount),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user