Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
feat: add wireguard collector (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyam8 authored Aug 4, 2022
1 parent 2c4ff1b commit b9be291
Show file tree
Hide file tree
Showing 11 changed files with 1,015 additions and 69 deletions.
139 changes: 70 additions & 69 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions config/go.d.conf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ modules:
# vcsa: yes
# vsphere: yes
# web_log: yes
# wireguard: yes
# whoisquery: yes
# wmi: yes
# x509check: yes
Expand Down
73 changes: 73 additions & 0 deletions config/go.d/wireguard.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# netdata go.d.plugin configuration for wireguard
#
# This file is in YAML format. Generally the format is:
#
# name: value
#
# There are 2 sections:
# - GLOBAL
# - JOBS
#
#
# [ GLOBAL ]
# These variables set the defaults for all JOBs, however each JOB may define its own, overriding the defaults.
#
# The GLOBAL section format:
# param1: value1
# param2: value2
#
# Currently supported global parameters:
# - update_every
# Data collection frequency in seconds. Default: 1.
#
# - autodetection_retry
# Re-check interval in seconds. Attempts to start the job are made once every interval.
# Zero means not to schedule re-check. Default: 0.
#
# - priority
# Priority is the relative priority of the charts as rendered on the web page,
# lower numbers make the charts appear before the ones with higher numbers. Default: 70000.
#
#
# [ JOBS ]
# JOBS allow you to collect values from multiple sources.
# Each source will have its own set of charts.
#
# IMPORTANT:
# - Parameter 'name' is mandatory.
# - Jobs with the same name are mutually exclusive. Only one of them will be allowed running at any time.
#
# This allows autodetection to try several alternatives and pick the one that works.
# Any number of jobs is supported.
#
# The JOBS section format:
#
# jobs:
# - name: job1
# param1: value1
# param2: value2
#
# - name: job2
# param1: value1
# param2: value2
#
# - name: job2
# param1: value1
#
# [ JOB defaults ]:
# charts:
# num: 1
# dimensions: 3
#
#
# [ JOB mandatory parameters ]:
# No parameters
#
# ------------------------------------------------MODULE-CONFIGURATION--------------------------------------------------

# update_every: 1
# autodetection_retry: 0
# priority: 70000

jobs:
- name: wireguard
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/valyala/fastjson v1.6.3
github.com/vmware/govmomi v0.22.2
go.mongodb.org/mongo-driver v1.10.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b
gopkg.in/ini.v1 v1.66.6
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.24.3
Expand Down Expand Up @@ -95,13 +96,17 @@ require (
github.com/jhump/protoreflect v1.8.2 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/likexian/gokit v0.25.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mdlayher/genetlink v1.2.0 // indirect
github.com/mdlayher/netlink v1.6.0 // indirect
github.com/mdlayher/socket v0.2.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
Expand Down Expand Up @@ -150,6 +155,7 @@ require (
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220524023933-508584e28198 // indirect
google.golang.org/grpc v1.46.2 // indirect
Expand Down
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
Expand Down Expand Up @@ -713,12 +715,20 @@ github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb44
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mdlayher/genetlink v1.2.0 h1:4yrIkRV5Wfk1WfpWTcoOlGmsWgQj3OtQN9ZsbrE+XtU=
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
github.com/mdlayher/socket v0.2.3 h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM=
github.com/mdlayher/socket v0.2.3/go.mod h1:bz12/FozYNH/VbvC3q7TRIK/Y6dH1kCKsXaUeXi/FmY=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
Expand Down Expand Up @@ -1190,6 +1200,7 @@ golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
Expand Down Expand Up @@ -1317,6 +1328,7 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -1435,6 +1447,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d h1:q4JksJ2n0fmbXC0Aj0eOs6E0AcPqnKglxWXWFqGD6x0=
golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b h1:9JncmKXcUwE918my+H6xmjBdhK2jM/UTUNXxhRG1BAk=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b/go.mod h1:yp4gl6zOlnDGOZeWeDfMwQcsdOIQnMdhuPx9mwwWBL4=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
Expand Down
1 change: 1 addition & 0 deletions modules/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import (
_ "github.com/netdata/go.d.plugin/modules/vsphere"
_ "github.com/netdata/go.d.plugin/modules/weblog"
_ "github.com/netdata/go.d.plugin/modules/whoisquery"
_ "github.com/netdata/go.d.plugin/modules/wireguard"
_ "github.com/netdata/go.d.plugin/modules/wmi"
_ "github.com/netdata/go.d.plugin/modules/x509check"
_ "github.com/netdata/go.d.plugin/modules/zookeeper"
Expand Down
56 changes: 56 additions & 0 deletions modules/wireguard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--
title: "WireGuard monitoring with Netdata"
description: "Monitor WireGuard VPN network interfaces and peers traffic."
custom_edit_url: https://github.com/netdata/go.d.plugin/edit/master/modules/wireguard/README.md
sidebar_label: "WireGuard"
-->

# WireGuard monitoring with Netdata

[WireGuard](https://www.wireguard.com/) is an extremely simple yet fast and modern VPN that utilizes state-of-the-art
cryptography.

This module monitors WireGuard VPN network interfaces and peers traffic.

## Requirements

- Grant `CAP_NET_ADMIN` capability to `go.d.plugin`.

```bash
sudo setcap CAP_NET_ADMIN+epi <INSTALL_PREFIX>/usr/libexec/netdata/plugins.d/go.d.plugin
```

## Metrics

All metrics have "wireguard." prefix.

| Metric | Scope | Dimensions | Units |
|---------------------------|:------:|:-----------------:|:-------:|
| device_peers | device | peers | peers |
| device_network_io | device | receive, transmit | B/s |
| peer_network_io | peer | receive, transmit | B/s |
| peer_latest_handshake_ago | peer | time | seconds |

## Configuration

No configuration needed.

## Troubleshooting

To troubleshoot issues with the `wireguard` collector, run the `go.d.plugin` with the debug option enabled. The output
should give you clues as to why the collector isn't working.
First, navigate to your plugins' directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on your
system, open `netdata.conf` and look for the setting `plugins directory`. Once you're in the plugin's directory, switch
to the `netdata` user.
```bash
cd /usr/libexec/netdata/plugins.d/
sudo -u netdata -s
```
You can now run the `go.d.plugin` to debug the collector:
```bash
./go.d.plugin -d -m wireguard
```
152 changes: 152 additions & 0 deletions modules/wireguard/charts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// SPDX-License-Identifier: GPL-3.0-or-later

package wireguard

import (
"fmt"
"strings"

"github.com/netdata/go.d.plugin/agent/module"
)

const (
prioDeviceNetworkIO = module.Priority + iota
prioDevicePeers
prioPeerNetworkIO
prioPeerLatestHandShake
)

var (
deviceChartsTmpl = module.Charts{
deviceNetworkIOChartTmpl.Copy(),
devicePeersChartTmpl.Copy(),
}

deviceNetworkIOChartTmpl = module.Chart{
ID: "device_%s_network_io",
Title: "Device traffic",
Units: "B/s",
Fam: "device traffic",
Ctx: "wireguard.device_network_io",
Type: module.Area,
Priority: prioDeviceNetworkIO,
Dims: module.Dims{
{ID: "device_%s_receive", Name: "receive", Algo: module.Incremental},
{ID: "device_%s_transmit", Name: "transmit", Algo: module.Incremental, Mul: -1},
},
}
devicePeersChartTmpl = module.Chart{
ID: "device_%s_peers",
Title: "Device peers",
Units: "peers",
Fam: "device peers",
Ctx: "wireguard.device_peers",
Priority: prioDevicePeers,
Dims: module.Dims{
{ID: "device_%s_peers", Name: "peers"},
},
}
)

var (
peerChartsTmpl = module.Charts{
peerNetworkIOChartTmpl.Copy(),
peerLatestHandShakeChartTmpl.Copy(),
}

peerNetworkIOChartTmpl = module.Chart{
ID: "peer_%s_network_io",
Title: "Peer traffic",
Units: "B/s",
Fam: "peer traffic",
Ctx: "wireguard.peer_network_io",
Type: module.Area,
Priority: prioPeerNetworkIO,
Dims: module.Dims{
{ID: "peer_%s_receive", Name: "receive", Algo: module.Incremental},
{ID: "peer_%s_transmit", Name: "transmit", Algo: module.Incremental, Mul: -1},
},
}
peerLatestHandShakeChartTmpl = module.Chart{
ID: "peer_%s_latest_handshake_ago",
Title: "Peer time elapsed sine the latest handshake",
Units: "seconds",
Fam: "peer latest handshake",
Ctx: "wireguard.peer_latest_handshake_ago",
Priority: prioPeerLatestHandShake,
Dims: module.Dims{
{ID: "peer_%s_latest_handshake_ago", Name: "time"},
},
}
)

func newDeviceCharts(device string) *module.Charts {
charts := deviceChartsTmpl.Copy()

for _, c := range *charts {
c.ID = fmt.Sprintf(c.ID, device)
c.Labels = []module.Label{
{Key: "device", Value: device},
}
for _, d := range c.Dims {
d.ID = fmt.Sprintf(d.ID, device)
}
}

return charts
}

func (w *WireGuard) addNewDeviceCharts(device string) {
charts := newDeviceCharts(device)

if err := w.Charts().Add(*charts...); err != nil {
w.Warning(err)
}
}

func (w *WireGuard) removeDeviceCharts(device string) {
prefix := fmt.Sprintf("device_%s", device)

for _, c := range *w.Charts() {
if strings.HasPrefix(c.ID, prefix) {
c.MarkRemove()
c.MarkNotCreated()
}
}
}

func newPeerCharts(id, device, pubKey string) *module.Charts {
charts := peerChartsTmpl.Copy()

for _, c := range *charts {
c.ID = fmt.Sprintf(c.ID, id)
c.Labels = []module.Label{
{Key: "device", Value: device},
{Key: "public_key", Value: pubKey},
}
for _, d := range c.Dims {
d.ID = fmt.Sprintf(d.ID, id)
}
}

return charts
}

func (w *WireGuard) addNewPeerCharts(id, device, pubKey string) {
charts := newPeerCharts(id, device, pubKey)

if err := w.Charts().Add(*charts...); err != nil {
w.Warning(err)
}
}

func (w *WireGuard) removePeerCharts(id string) {
prefix := fmt.Sprintf("peer_%s", id)

for _, c := range *w.Charts() {
if strings.HasPrefix(c.ID, prefix) {
c.MarkRemove()
c.MarkNotCreated()
}
}
}
Loading

0 comments on commit b9be291

Please sign in to comment.