A Prometheus metrics exporter for WireGuard VPN interfaces, written in Go.
- Discovers all WireGuard interfaces automatically
- Filters interfaces using a deny-list
- Exports comprehensive metrics for interfaces and peers
- Human-friendly peer names - Uses display names from WireGuard config files instead of public keys in metrics labels
- Supports configuration via CLI flags, environment variables, or config file (with priority: CLI > ENV > file)
- Secure by design - never exposes private keys or sensitive data
The exporter provides the following metrics:
wireguard_peers_total- Number of configured peers per interfacewireguard_peer_latest_handshake_seconds- Unix timestamp of the latest handshake per peerwireguard_peer_handshake_age_seconds- Age in seconds of the latest handshake per peerwireguard_peer_bytes_sent- Total bytes sent to peerwireguard_peer_bytes_received- Total bytes received from peerwireguard_interface_listening_port- Listening port of the WireGuard interfacewireguard_peer_endpoint- Peer endpoint information (1 if endpoint exists, 0 otherwise)wireguard_peer_allowed_ips_count- Number of allowed IPs per peer
All peer-level metrics use a peer label that contains either:
- The display name from the WireGuard config file (if available and config file reading is enabled)
- The peer's public key (as fallback)
Disclaimer: I saw this technique in another repo that parsed the Wireguard config files but don't remember where exactly, so I'm sorry I cannot give proper kudos.
The exporter can read display names from WireGuard config files to use human-friendly names in metrics instead of public keys. To enable this, add a # display-name = <name> comment in each [Peer] block of your WireGuard config file:
[Peer]
# display-name = Mobile Phone
PublicKey = <whatever_public_key>
AllowedIPs = <whatever_ip_range>You probably want to use a display name that is prometheus label friendly.
You can use either display-name or display_name format. The exporter will:
- Read the config file at
/etc/wireguard/<interface>.confby default - Match peers by their public key
- Use the display name in the
peerlabel for all metrics
If config file reading is disabled or a display name is not found, the public key is used as the label value.
--listen-address- Address to listen on (default::9586)--metrics-path- Path for metrics endpoint (default:/metrics)--wg-command-path- Path towgcommand (default:wg)--interfaces-denylist- Comma-separated list of interfaces to exclude--show-endpoints- Show peer endpoints in metrics (default:true)--read-config-files- Enable reading WireGuard config files for display names (default:true)--config- Path to configuration file (JSON)
WG_LISTEN_ADDRESS- Address to listen onWG_METRICS_PATH- Path for metrics endpointWG_COMMAND_PATH- Path towgcommandWG_INTERFACES_DENYLIST- Comma-separated list of interfaces to excludeWG_SHOW_ENDPOINTS- Show peer endpoints (trueor1)WG_READ_CONFIG_FILES- Enable reading WireGuard config files for display names (trueor1)
{
"listen_address": ":9586",
"metrics_path": "/metrics",
"interfaces_denylist": ["wg-example"],
"wg_command_path": "wg",
"show_endpoints": true,
"read_config_files": true,
"config_file_paths": {
"wg0": "/etc/wireguard/wg0.conf",
"wg1": "/custom/path/to/wg1.conf"
}
}read_config_files- Enable reading WireGuard config files for display names (default:true). When disabled, the exporter will use public keys as peer labels.config_file_paths- Optional map of interface names to custom config file paths. If not specified, defaults to/etc/wireguard/<interface>.conf
Configuration priority: CLI flags > Environment variables > Config file
Note: Running the wg command requires privileges, so you may need to run the app as sudo
./wireguard-exporter-go./wireguard-exporter-go --listen-address :9090./wireguard-exporter-go --interfaces-denylist "wg-test,wg-dev"If you want to prevent the exporter from reading your WireGuard config files (for privacy or security reasons), you can disable it:
./wireguard-exporter-go --read-config-files=falseIn this case, the exporter will use public keys as peer labels in metrics.
./wireguard-exporter-go --config config.json- Private keys are never parsed or exposed
- Interface names are validated to prevent command injection
- Command execution uses explicit paths with timeouts
- Sensitive data is filtered from logs
- Endpoint IPs can be hidden using
--show-endpoints=false - Config file reading can be disabled using
--read-config-files=falseto prevent the exporter from accessing your WireGuard configuration files
go mod download
go build -o wireguard-exporter-go- Go 1.21 or later
- WireGuard installed and
wgcommand available in PATH - Linux (currently only Linux is supported)
MIT
Co-authored by Claude via Cursor (I know you already noticed)