A Prometheus exporter for WireGuard, written in Rust. This tool exports the wg show all dump
results in a format that Prometheus can understand. The exporter is very light on your server resources, both in terms of memory and CPU usage.
Starting from release 2.0.2 this exporter supports IPv6 addressess too (thanks to Maximilian Bosch's PR #5).
From release 3.0.0 the exporter allows two label modes: one is to dump every allowed ip in a single label (called allowed_ips
) along with their subnets. The second one is to create a pair of labels for each allowed ip/subnet pair (called allowed_ip_0
/allowed_subnet_0
, allowed_ip_1
/allowed_subnet_1
and so on for every allowed ip). The default if the single label mode but you can enable the second mode by specifying the -s
switch at startup. Thank you Toon Schoenmakers for this solution (see https://github.com/MindFlavor/prometheuswireguardexporter/issues/8).
rustc 1.35.0-nightly (8159f389f 2019-04-06)
).wg
CLI in the path. The tool will call wg show all dump
and of course will fail if the wg
executable is not found. If you want I can add the option of specifying the wg
path in the command line, just open an issue for it.To compile the latest master version:
bash
git clone https://github.com/MindFlavor/prometheus_wireguard_exporter.git
cd prometheus_wireguard_exporter
cargo install --path .
If you want the latest release you can simply use:
bash
cargo install prometheus_wireguard_exporter
Start the binary with -h
to get the complete syntax. The parameters are:
| Parameter | Mandatory | Valid values | Default | Description |
| -- | -- | -- | -- | -- |
| -v
| no | -p
| no | any valid port number | 9586 | Specify the service port. This is the port your Prometheus instance should point to.
| -n
| no | path to the wireguard configuration file | | This flag adds the friendly_name attribute to the exported entries. See Friendly names for more details.
| -s
| no | -r
| no |
Once started, the tool will listen on the specified port (or the default one, 9586, if not specified) and return a Prometheus valid response at the url /metrics
. So to check if the tool is working properly simply browse the http://localhost:9586/metrics
(or whichever port you choose).
Starting from version 1.2 you can instruct the exporter to append a friendly name to the exported entries. This can make the output more understandable than using the public keys. For example this is the standard output:
```
wireguardsentbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32"} 3208804 wireguardsentbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32"} 0 wireguardsentbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32"} 0 wireguardsentbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32"} 0 wireguardsentbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32"} 0 wireguardsentbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32"} 0 wireguardsentbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0
wireguardreceivedbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32"} 71420072 wireguardreceivedbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0
wireguardlatesthandshakeseconds{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32"} 1562834127 wireguardlatesthandshakeseconds{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0 ```
And this is the one augmented with friendly names:
```
wireguardsentbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32",friendlyname="OnePlus 6T"} 3208804 wireguardsentbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32",friendlyname="varch.local (laptop)"} 0 wireguardsentbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32",friendlyname="cantarch"} 0 wireguardsentbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32",friendlyname="frcognoarch"} 0 wireguardsentbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32",friendlyname="frcognowin10"} 0 wireguardsentbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32",friendlyname="OnePlus 5T"} 0 wireguardsentbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedips="10.70.0.5/32",friendlyname="folioarch"} 0
wireguardreceivedbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32",friendlyname="OnePlus 6T"} 71420072 wireguardreceivedbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32",friendlyname="varch.local (laptop)"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32",friendlyname="cantarch"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32",friendlyname="frcognoarch"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32",friendlyname="frcognowin10"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32",friendlyname="OnePlus 5T"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedips="10.70.0.5/32",friendlyname="folioarch"} 0
wireguardlatesthandshakeseconds{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedips="10.70.0.2/32,10.70.0.66/32",friendlyname="OnePlus 6T"} 1562834127 wireguardlatesthandshakeseconds{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedips="10.70.0.3/32",friendlyname="varch.local (laptop)"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedips="10.70.0.4/32",friendlyname="cantarch"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedips="10.70.0.50/32",friendlyname="frcognoarch"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedips="10.70.0.40/32",friendlyname="frcognowin10"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedips="10.70.0.80/32",friendlyname="OnePlus 5T"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedips="10.70.0.5/32",friendlyname="folioarch"} 0 ```
In order for this to work, you need to add comments to your wireguard configuration file (below the [Peer]
definition). The comment will be interpreted as friendly_name
and added to the entry exported to Prometheus. Note that this is not a standard but, since it's a comment, will not interfere with WireGuard in any way. For example this is how you edit your WireGuard configuration file:
``` [Peer] PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc= AllowedIPs = 10.70.0.40/32
[Peer] PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk= AllowedIPs = 10.70.0.80/32 ```
``` [Peer]
PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc= AllowedIPs = 10.70.0.40/32
[Peer]
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk= AllowedIPs = 10.70.0.80/32 ```
As you can see, all you need to do is to add the friendly name as comment (and enable the flag since this feature is opt-in).
This is a sample of the label split mode:
```
wireguardsentbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedip0="10.70.0.2",allowedsubnet0="32",allowedip1="10.70.0.66",allowedsubnet1="32",friendlyname="OnePlus 6T"} 3208804 wireguardsentbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedip0="10.70.0.3",allowedsubnet0="32",friendlyname="varch.local (laptop)"} 0 wireguardsentbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedip0="10.70.0.4",allowedsubnet0="32",friendlyname="cantarch"} 0 wireguardsentbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedip0="10.70.0.50",allowedsubnet0="32",friendlyname="frcognoarch"} 0 wireguardsentbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedip0="10.70.0.40",allowedsubnet0="32",friendlyname="frcognowin10"} 0 wireguardsentbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedip0="10.70.0.80",allowedsubnet0="32",friendlyname="OnePlus 5T"} 0 wireguardsentbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedip0="10.70.0.5",allowedsubnet0="32",friendly_name="folioarch"} 0
wireguardreceivedbytestotal{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedip0="10.70.0.2",allowedsubnet0="32",allowedip1="10.70.0.66",allowedsubnet1="32",friendlyname="OnePlus 6T"} 71420072 wireguardreceivedbytestotal{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedip0="10.70.0.3",allowedsubnet0="32",friendlyname="varch.local (laptop)"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedip0="10.70.0.4",allowedsubnet0="32",friendlyname="cantarch"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedip0="10.70.0.50",allowedsubnet0="32",friendlyname="frcognoarch"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedip0="10.70.0.40",allowedsubnet0="32",friendlyname="frcognowin10"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedip0="10.70.0.80",allowedsubnet0="32",friendlyname="OnePlus 5T"} 0 wireguardreceivedbytestotal{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedip0="10.70.0.5",allowedsubnet0="32",friendly_name="folioarch"} 0
wireguardlatesthandshakeseconds{interface="wg0",publickey="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowedip0="10.70.0.2",allowedsubnet0="32",allowedip1="10.70.0.66",allowedsubnet1="32",friendlyname="OnePlus 6T"} 1562834127 wireguardlatesthandshakeseconds{interface="wg0",publickey="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowedip0="10.70.0.3",allowedsubnet0="32",friendlyname="varch.local (laptop)"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowedip0="10.70.0.4",allowedsubnet0="32",friendlyname="cantarch"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowedip0="10.70.0.50",allowedsubnet0="32",friendlyname="frcognoarch"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowedip0="10.70.0.40",allowedsubnet0="32",friendlyname="frcognowin10"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowedip0="10.70.0.80",allowedsubnet0="32",friendlyname="OnePlus 5T"} 0 wireguardlatesthandshakeseconds{interface="wg0",publickey="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowedip0="10.70.0.5",allowedsubnet0="32",friendly_name="folioarch"} 0 ```
Now add the exporter to the Prometheus exporters as usual. I recommend to start it as a service. It's necessary to run it as root (if there is a non-root way to call wg show all dump
please let me know). My systemd service file is like this one:
``` [Unit] Description=Prometheus WireGuard Exporter Wants=network-online.target After=network-online.target
[Service] User=root Group=root Type=simple ExecStart=/usr/local/bin/prometheuswireguardexporter -n /etc/wireguard/wg0.conf
[Install] WantedBy=multi-user.target ```