-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Init dev commit Add README.md Add README.md Co-authored-by: Роман <rorudzhov@mac.local>
- Loading branch information
Showing
9 changed files
with
419 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,3 +20,6 @@ | |
# Go workspace file | ||
go.work | ||
go.work.sum | ||
|
||
|
||
build.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# Prometheus WireGuard Exporter | ||
|
||
A Prometheus exporter for [WireGuard](https://www.wireguard.com), written in GoLang. This tool execute command `sudo /usr/bin/wg show all dump` and parse results in a format [OpenMetrics](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md) that [Prometheus](https://prometheus.io/) can understand. | ||
|
||
### Metrics | ||
|
||
All metrics are aveliable on `/metrics` path. As example you can use `curl 127.0.0.1:9172/metrics` | ||
|
||
```ebnf | ||
# HELP wireguard_keep_alive Number of keep alive seconds | ||
# TYPE wireguard_keep_alive gauge | ||
wireguard_keep_alive{ifname="wg0",publicKey="5CL0j1HMDxK0ftLz2ANXaZ5w2y5aOe9dV3tKF4llhlI="} 5 | ||
# HELP wireguard_last_handshake Timestamp of last handshake | ||
# TYPE wireguard_last_handshake counter | ||
wireguard_last_handshake{ifname="wg0",publicKey="5CL0j1HMDxK0ftLz2ANXaZ5w2y5aOe9dV3tKF4llhlI="} 2.9867196e+07 | ||
# HELP wireguard_peers_count Number of active peers | ||
# TYPE wireguard_peers_count gauge | ||
wireguard_peers_count{ifname="wg0"} 1 | ||
# HELP wireguard_rx_bytes Number of received bytes | ||
# TYPE wireguard_rx_bytes counter | ||
wireguard_rx_bytes{ifname="wg0",publicKey="5CL0j1HMDxK0ftLz2ANXaZ5w2y5aOe9dV3tKF4llhlI="} 2.9867196e+07 | ||
# HELP wireguard_tx_bytes Number of transferred bytes | ||
# TYPE wireguard_tx_bytes counter | ||
wireguard_tx_bytes{ifname="wg0",publicKey="5CL0j1HMDxK0ftLz2ANXaZ5w2y5aOe9dV3tKF4llhlI="} 2.746656e+06 | ||
``` | ||
|
||
For example this is how you edit your WireGuard configuration file: | ||
|
||
```ini | ||
[Interface] | ||
Address = 192.168.0.8/24 | ||
PrivateKey = ******uWogB6cn/Mw********j3dZeB54C1SIn4iG2k= | ||
|
||
[Peer] | ||
PublicKey = 5CL0j1HMDxK0ftLz2ANXaZ5w2y5aOe9dV3tKF4llhlI= | ||
AllowedIPs = 192.168.0.0/24,192.168.1.0/24 | ||
PersistentKeepalive = 5 | ||
Endpoint = wg0.example.com:443 | ||
``` | ||
|
||
## Flags | ||
❗SUDO RULES❗️ | ||
If the `wireguard-exporter` is not launched as `root`, then the user must have sudo rights | ||
```shell | ||
someuser ALL=(root) NOPASSWD: /usr/bin/wg | ||
``` | ||
You can simply run the `wireguard-exporter` file with standard settings on any host that has utility `wg` | ||
|
||
You can call `wireguard-exporter -h` to print all available flags | ||
|
||
```shell | ||
root@myhost:~# ./wireguard-exporter -h | ||
Usage of ./wireguard-exporter-linux-amd64: | ||
--log.format string | ||
Output format of log messages. One of: [text, json] (default "text") | ||
--log.level string | ||
Only log messages with the given severity or above. One of: [debug, info, warn, error] (default "info") | ||
--web.listem.address string | ||
Address to listen (default "0.0.0.0:9172") | ||
``` | ||
|
||
### Build for another platform | ||
If your platform is not in the releases, you can build it yourself, for this you only need a Go compiler. Just execute this shell script by changing `GOOS` and `GOARCH` with according [GoLang specification](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) | ||
```shell | ||
GOOS=linux # REQUIRED REPLACE | ||
GOARCH=amd64 # REQUIRED REPLACE | ||
|
||
export GOARCH=$GOARCH | ||
export GOOS=$GOOS | ||
file="wireguard-exporter-$GOOS-$GOARCH" | ||
go build -ldflags "-s -w" -o $file main.go | ||
``` | ||
If everything went well, just transfer the file `wireguard-exporter-...-...` to your host and execute him | ||
|
||
|
||
### Simple systemd service file | ||
|
||
❗SUDO RULES❗️ | ||
If the `wireguard-exporter` is not launched as `root`, then the user must have sudo rights | ||
```shell | ||
someuser ALL=(root) NOPASSWD: /usr/bin/wg | ||
``` | ||
|
||
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 or configure a sudo rule (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: | ||
|
||
```ini | ||
[Unit] | ||
Description=Prometheus WireGuard Exporter | ||
Wants=network-online.target | ||
After=network-online.target | ||
|
||
[Service] | ||
User=someuser | ||
Group=someuser | ||
Type=simple | ||
ExecStart=/usr/local/bin/wireguard-exporter \ | ||
--log.format text \ | ||
--log.level info \ | ||
--web.listem.address 0.0.0.0:9172 | ||
Restart=on-failure | ||
RestartSec=15s | ||
|
||
[Install] | ||
WantedBy=multi-user.target | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module main | ||
|
||
go 1.22.2 | ||
|
||
require github.com/prometheus/client_golang v1.19.1 | ||
|
||
require ( | ||
github.com/beorn7/perks v1.0.1 // indirect | ||
github.com/cespare/xxhash/v2 v2.2.0 // indirect | ||
github.com/prometheus/client_model v0.5.0 // indirect | ||
github.com/prometheus/common v0.48.0 // indirect | ||
github.com/prometheus/procfs v0.12.0 // indirect | ||
golang.org/x/sys v0.17.0 // indirect | ||
google.golang.org/protobuf v1.33.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= | ||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= | ||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= | ||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= | ||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= | ||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= | ||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= | ||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= | ||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= | ||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= | ||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= | ||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= | ||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"main/src" | ||
"net/http" | ||
"os" | ||
) | ||
|
||
var ( | ||
webListenAddress = flag.String("web.listem.address", "0.0.0.0:9172", "Address to listen") | ||
logLevel = flag.String("log.level", "info", "Only log messages with the given severity or above. One of: [debug, info, warn, error]") | ||
logFormat = flag.String("log.format", "text", "Output format of log messages. One of: [text, json]") | ||
) | ||
|
||
func main() { | ||
// Parse flags | ||
flag.Parse() | ||
|
||
// Init logger | ||
src.Init(logLevel, logFormat) | ||
logger := src.GetLogger() | ||
|
||
logger.Info("Exporter is started") | ||
|
||
// Start HTTP server | ||
server := http.NewServeMux() | ||
server.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { | ||
src.Router(writer, request, logger) | ||
}) | ||
logger.Info("Starting HTTP server on " + *webListenAddress + "") | ||
err := http.ListenAndServe(*webListenAddress, server) | ||
if err != nil { | ||
logger.Error(err.Error()) | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package src | ||
|
||
import ( | ||
"log/slog" | ||
"os" | ||
) | ||
|
||
var ( | ||
mylogger *slog.Logger | ||
) | ||
|
||
func Init(level *string, format *string) { | ||
var l_level slog.Level | ||
switch *level { | ||
case "debug": | ||
l_level = slog.LevelDebug | ||
case "warn": | ||
l_level = slog.LevelWarn | ||
case "error": | ||
l_level = slog.LevelError | ||
default: | ||
l_level = slog.LevelInfo | ||
} | ||
|
||
// Select format | ||
var handler slog.Handler | ||
switch *format { | ||
case "json": | ||
handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: l_level}) | ||
default: | ||
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: l_level}) | ||
} | ||
mylogger = slog.New(handler) | ||
} | ||
|
||
func GetLogger() *slog.Logger { | ||
return mylogger | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package src | ||
|
||
import ( | ||
"log/slog" | ||
"main/src/routes" | ||
"net/http" | ||
) | ||
|
||
// Router routes handler | ||
func Router(writer http.ResponseWriter, request *http.Request, logger *slog.Logger) { | ||
switch request.RequestURI { | ||
case "/metrics": | ||
routes.Metrics(writer, request, logger) | ||
default: | ||
routes.NotFound(writer, request, logger) | ||
} | ||
|
||
} |
Oops, something went wrong.