plugins/inputs: New input for Wireguard server (#6367)
This commit is contained in:
parent
318a963a89
commit
d35290ac7e
|
@ -321,6 +321,7 @@ For documentation on the latest development code see the [documentation index][d
|
|||
* [rollbar](./plugins/inputs/webhooks/rollbar)
|
||||
* [win_perf_counters](./plugins/inputs/win_perf_counters) (windows performance counters)
|
||||
* [win_services](./plugins/inputs/win_services)
|
||||
* [wireguard](./plugins/inputs/wireguard)
|
||||
* [wireless](./plugins/inputs/wireless)
|
||||
* [x509_cert](./plugins/inputs/x509_cert)
|
||||
* [zfs](./plugins/inputs/zfs)
|
||||
|
|
|
@ -4647,6 +4647,13 @@
|
|||
# # timeout = "1s"
|
||||
|
||||
|
||||
# # Collect Wireguard server interface and peer statistics
|
||||
# [[inputs.wireguard]]
|
||||
# ## Optional list of Wireguard device/interface names to query.
|
||||
# ## If omitted, all Wireguard interfaces are queried.
|
||||
# # devices = ["wg0"]
|
||||
|
||||
|
||||
# # Monitor wifi signal strength and quality
|
||||
# [[inputs.wireless]]
|
||||
# ## Sets 'proc' directory path
|
||||
|
|
3
go.mod
3
go.mod
|
@ -51,7 +51,7 @@ require (
|
|||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 // indirect
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/google/go-cmp v0.4.0
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/gorilla/mux v1.6.2
|
||||
|
@ -122,6 +122,7 @@ require (
|
|||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4
|
||||
gonum.org/v1/gonum v0.6.2 // indirect
|
||||
google.golang.org/api v0.3.1
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107
|
||||
|
|
31
go.sum
31
go.sum
|
@ -186,6 +186,9 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
|||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
|
@ -258,6 +261,9 @@ github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem
|
|||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4 h1:nwOc1YaOrYJ37sEBrtWZrdqzK22hiJs3GpDmP3sR2Yw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
|
@ -300,8 +306,16 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mdlayher/apcupsd v0.0.0-20190314144147-eb3dd99a75fe h1:yMrL+YorbzaBpj/h3BbLMP+qeslPZYMbzcpHFBNy1Yk=
|
||||
github.com/mdlayher/apcupsd v0.0.0-20190314144147-eb3dd99a75fe/go.mod h1:y3mw3VG+t0m20OMqpG8RQqw8cDXvShVb+L8Z8FEnebw=
|
||||
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0 h1:mpdLgm+brq10nI9zM1BpX1kpDbh3NLl3RSnVq6ZSkfg=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
|
@ -451,8 +465,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w=
|
||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -476,8 +493,11 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
@ -498,11 +518,16 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -522,6 +547,12 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8=
|
||||
golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4 h1:KTi97NIQGgSMaN0v/oxniJV0MEzfzmrDUOAWxombQVc=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4/go.mod h1:UdS9frhv65KTfwxME1xE8+rHYoFpbm36gOud1GhBe9c=
|
||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.6.2 h1:4r+yNT0+8SWcOkXP+63H2zQbN+USnC73cjGUxnDF94Q=
|
||||
gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
||||
|
|
|
@ -170,6 +170,7 @@ import (
|
|||
_ "github.com/influxdata/telegraf/plugins/inputs/webhooks"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/win_perf_counters"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/win_services"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/wireguard"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/wireless"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/x509_cert"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/zfs"
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# Wireguard Input Plugin
|
||||
|
||||
The Wireguard input plugin collects statistics on the local Wireguard server
|
||||
using the [`wgctrl`](https://github.com/WireGuard/wgctrl-go) library. It
|
||||
reports gauge metrics for Wireguard interface device(s) and its peers.
|
||||
|
||||
### Configuration
|
||||
|
||||
```toml
|
||||
# Collect Wireguard server interface and peer statistics
|
||||
[[inputs.wireguard]]
|
||||
## Optional list of Wireguard device/interface names to query.
|
||||
## If omitted, all Wireguard interfaces are queried.
|
||||
# devices = ["wg0"]
|
||||
```
|
||||
|
||||
### Metrics
|
||||
|
||||
- `wireguard_device`
|
||||
- tags:
|
||||
- `name` (interface device name, e.g. `wg0`)
|
||||
- `type` (Wireguard tunnel type, e.g. `linux_kernel` or `userspace`)
|
||||
- fields:
|
||||
- `listen_port` (int, UDP port on which the interface is listening)
|
||||
- `firewall_mark` (int, device's current firewall mark)
|
||||
- `peers` (int, number of peers associated with the device)
|
||||
|
||||
- `wireguard_peer`
|
||||
- tags:
|
||||
- `device` (associated interface device name, e.g. `wg0`)
|
||||
- `public_key` (peer public key, e.g. `NZTRIrv/ClTcQoNAnChEot+WL7OH7uEGQmx8oAN9rWE=`)
|
||||
- fields:
|
||||
- `persistent_keepalive_interval_ns` (int, keepalive interval in nanoseconds; 0 if unset)
|
||||
- `protocol_version` (int, Wireguard protocol version number)
|
||||
- `allowed_ips` (int, number of allowed IPs for this peer)
|
||||
- `last_handshake_time_ns` (int, Unix timestamp of the last handshake for this peer in nanoseconds)
|
||||
- `rx_bytes` (int, number of bytes received from this peer)
|
||||
- `tx_bytes` (int, number of bytes transmitted to this peer)
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Error: `operation not permitted`
|
||||
|
||||
When the kernelspace implementation of Wireguard is in use (as opposed to its
|
||||
userspace implementations), Telegraf communicates with the module over netlink.
|
||||
This requires Telegraf to either run as root, or for the Telegraf binary to
|
||||
have the `CAP_NET_ADMIN` capability.
|
||||
|
||||
To add this capability to the Telegraf binary (to allow this communication under
|
||||
the default user `telegraf`):
|
||||
|
||||
```bash
|
||||
$ sudo setcap CAP_NET_ADMIN+epi $(which telegraf)
|
||||
```
|
||||
|
||||
N.B.: This capability is a filesystem attribute on the binary itself. The
|
||||
attribute needs to be re-applied if the Telegraf binary is rotated (e.g.
|
||||
on installation of new a Telegraf version from the system package manager).
|
||||
|
||||
#### Error: `error enumerating Wireguard devices`
|
||||
|
||||
This usually happens when the device names specified in config are invalid.
|
||||
Ensure that `sudo wg show` succeeds, and that the device names in config match
|
||||
those printed by this command.
|
||||
|
||||
### Example Output
|
||||
|
||||
```
|
||||
wireguard_device,host=WGVPN,name=wg0,type=linux_kernel firewall_mark=51820i,listen_port=58216i 1582513589000000000
|
||||
wireguard_device,host=WGVPN,name=wg0,type=linux_kernel peers=1i 1582513589000000000
|
||||
wireguard_peer,device=wg0,host=WGVPN,public_key=NZTRIrv/ClTcQoNAnChEot+WL7OH7uEGQmx8oAN9rWE= allowed_ips=2i,persistent_keepalive_interval_ns=60000000000i,protocol_version=1i 1582513589000000000
|
||||
wireguard_peer,device=wg0,host=WGVPN,public_key=NZTRIrv/ClTcQoNAnChEot+WL7OH7uEGQmx8oAN9rWE= last_handshake_time_ns=1582513584530013376i,rx_bytes=6484i,tx_bytes=13540i 1582513589000000000
|
||||
```
|
|
@ -0,0 +1,139 @@
|
|||
package wireguard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
measurementDevice = "wireguard_device"
|
||||
measurementPeer = "wireguard_peer"
|
||||
)
|
||||
|
||||
var (
|
||||
deviceTypeNames = map[wgtypes.DeviceType]string{
|
||||
wgtypes.Unknown: "unknown",
|
||||
wgtypes.LinuxKernel: "linux_kernel",
|
||||
wgtypes.Userspace: "userspace",
|
||||
}
|
||||
)
|
||||
|
||||
// Wireguard is an input that enumerates all Wireguard interfaces/devices on
|
||||
// the host, and reports gauge metrics for the device itself and its peers.
|
||||
type Wireguard struct {
|
||||
Devices []string `toml:"devices"`
|
||||
|
||||
client *wgctrl.Client
|
||||
}
|
||||
|
||||
func (wg *Wireguard) Description() string {
|
||||
return "Collect Wireguard server interface and peer statistics"
|
||||
}
|
||||
|
||||
func (wg *Wireguard) SampleConfig() string {
|
||||
return `
|
||||
## Optional list of Wireguard device/interface names to query.
|
||||
## If omitted, all Wireguard interfaces are queried.
|
||||
# devices = ["wg0"]
|
||||
`
|
||||
}
|
||||
|
||||
func (wg *Wireguard) Init() error {
|
||||
var err error
|
||||
|
||||
wg.client, err = wgctrl.New()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (wg *Wireguard) Gather(acc telegraf.Accumulator) error {
|
||||
devices, err := wg.enumerateDevices()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error enumerating Wireguard devices: %v", err)
|
||||
}
|
||||
|
||||
for _, device := range devices {
|
||||
wg.gatherDeviceMetrics(acc, device)
|
||||
|
||||
for _, peer := range device.Peers {
|
||||
wg.gatherDevicePeerMetrics(acc, device, peer)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wg *Wireguard) enumerateDevices() ([]*wgtypes.Device, error) {
|
||||
var devices []*wgtypes.Device
|
||||
|
||||
// If no device names are specified, defer to the library to enumerate
|
||||
// all of them
|
||||
if len(wg.Devices) == 0 {
|
||||
return wg.client.Devices()
|
||||
}
|
||||
|
||||
// Otherwise, explicitly populate only device names specified in config
|
||||
for _, name := range wg.Devices {
|
||||
dev, err := wg.client.Device(name)
|
||||
if err != nil {
|
||||
log.Printf("W! [inputs.wireguard] No Wireguard device found with name %s", name)
|
||||
continue
|
||||
}
|
||||
|
||||
devices = append(devices, dev)
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (wg *Wireguard) gatherDeviceMetrics(acc telegraf.Accumulator, device *wgtypes.Device) {
|
||||
fields := map[string]interface{}{
|
||||
"listen_port": device.ListenPort,
|
||||
"firewall_mark": device.FirewallMark,
|
||||
}
|
||||
|
||||
gauges := map[string]interface{}{
|
||||
"peers": len(device.Peers),
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"name": device.Name,
|
||||
"type": deviceTypeNames[device.Type],
|
||||
}
|
||||
|
||||
acc.AddFields(measurementDevice, fields, tags)
|
||||
acc.AddGauge(measurementDevice, gauges, tags)
|
||||
}
|
||||
|
||||
func (wg *Wireguard) gatherDevicePeerMetrics(acc telegraf.Accumulator, device *wgtypes.Device, peer wgtypes.Peer) {
|
||||
fields := map[string]interface{}{
|
||||
"persistent_keepalive_interval_ns": peer.PersistentKeepaliveInterval.Nanoseconds(),
|
||||
"protocol_version": peer.ProtocolVersion,
|
||||
"allowed_ips": len(peer.AllowedIPs),
|
||||
}
|
||||
|
||||
gauges := map[string]interface{}{
|
||||
"last_handshake_time_ns": peer.LastHandshakeTime.UnixNano(),
|
||||
"rx_bytes": peer.ReceiveBytes,
|
||||
"tx_bytes": peer.TransmitBytes,
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"device": device.Name,
|
||||
"public_key": peer.PublicKey.String(),
|
||||
}
|
||||
|
||||
acc.AddFields(measurementPeer, fields, tags)
|
||||
acc.AddGauge(measurementPeer, gauges, tags)
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("wireguard", func() telegraf.Input {
|
||||
return &Wireguard{}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package wireguard
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
func TestWireguard_gatherDeviceMetrics(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
|
||||
wg := &Wireguard{}
|
||||
device := &wgtypes.Device{
|
||||
Name: "wg0",
|
||||
Type: wgtypes.LinuxKernel,
|
||||
ListenPort: 1,
|
||||
FirewallMark: 2,
|
||||
Peers: []wgtypes.Peer{{}, {}},
|
||||
}
|
||||
|
||||
expectFields := map[string]interface{}{
|
||||
"listen_port": 1,
|
||||
"firewall_mark": 2,
|
||||
}
|
||||
expectGauges := map[string]interface{}{
|
||||
"peers": 2,
|
||||
}
|
||||
expectTags := map[string]string{
|
||||
"name": "wg0",
|
||||
"type": "linux_kernel",
|
||||
}
|
||||
|
||||
wg.gatherDeviceMetrics(&acc, device)
|
||||
|
||||
assert.Equal(t, 3, acc.NFields())
|
||||
acc.AssertDoesNotContainMeasurement(t, measurementPeer)
|
||||
acc.AssertContainsTaggedFields(t, measurementDevice, expectFields, expectTags)
|
||||
acc.AssertContainsTaggedFields(t, measurementDevice, expectGauges, expectTags)
|
||||
}
|
||||
|
||||
func TestWireguard_gatherDevicePeerMetrics(t *testing.T) {
|
||||
var acc testutil.Accumulator
|
||||
pubkey, _ := wgtypes.ParseKey("NZTRIrv/ClTcQoNAnChEot+WL7OH7uEGQmx8oAN9rWE=")
|
||||
|
||||
wg := &Wireguard{}
|
||||
device := &wgtypes.Device{
|
||||
Name: "wg0",
|
||||
}
|
||||
peer := wgtypes.Peer{
|
||||
PublicKey: pubkey,
|
||||
PersistentKeepaliveInterval: 1 * time.Minute,
|
||||
LastHandshakeTime: time.Unix(100, 0),
|
||||
ReceiveBytes: int64(40),
|
||||
TransmitBytes: int64(60),
|
||||
AllowedIPs: []net.IPNet{{}, {}},
|
||||
ProtocolVersion: 0,
|
||||
}
|
||||
|
||||
expectFields := map[string]interface{}{
|
||||
"persistent_keepalive_interval_ns": int64(60000000000),
|
||||
"protocol_version": 0,
|
||||
"allowed_ips": 2,
|
||||
}
|
||||
expectGauges := map[string]interface{}{
|
||||
"last_handshake_time_ns": int64(100000000000),
|
||||
"rx_bytes": int64(40),
|
||||
"tx_bytes": int64(60),
|
||||
}
|
||||
expectTags := map[string]string{
|
||||
"device": "wg0",
|
||||
"public_key": pubkey.String(),
|
||||
}
|
||||
|
||||
wg.gatherDevicePeerMetrics(&acc, device, peer)
|
||||
|
||||
assert.Equal(t, 6, acc.NFields())
|
||||
acc.AssertDoesNotContainMeasurement(t, measurementDevice)
|
||||
acc.AssertContainsTaggedFields(t, measurementPeer, expectFields, expectTags)
|
||||
acc.AssertContainsTaggedFields(t, measurementPeer, expectGauges, expectTags)
|
||||
}
|
Loading…
Reference in New Issue