These are my notes on enabling openHAB to display and use WireGuard client information.
Prerequisites
All setup assumes a Debian/Ubuntu based operating system on the devices.
- Wireguard - mine is running on a separate device within my network.
-
wireguard-tools
, installed on the same device as Wireguard -
mosquitto-clients
, installed on the same device as Wireguard - Mosquitto MQTT Broker, with openHAB connected
- JSONPath Transformation Service installed in openHAB
Wireguard device
I installed and setup Wireguard using PIVPN. This tutorial assumes Wireguard is already setup, and youāve succesfully connected clients.
On the same device as Wireguard, ensure wireguard-tools
is installed. With this installed, you should be able to run
wg-json
to show Wireguard status in JSON form.
In my installation that command was not recognised - I have to run
/usr/share/doc/wireguard-tools/examples/json/wg-json
The output might be something similar to:
{
"wg1": {
"privateKey": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=",
"publicKey": "/TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=",
"listenPort": 51821,
"peers": {
"fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=": {
"endpoint": "172.19.0.8:51822",
"latestHandshake": 1617235493,
"transferRx": 3481633,
"transferTx": 33460136,
"allowedIps": [
"10.0.0.2/24"
]
},
"jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=": {
"endpoint": "172.19.0.7:51823",
"latestHandshake": 1609974495,
"transferRx": 1403752,
"transferTx": 19462368,
"allowedIps": [
"10.0.0.3/24"
]
}
}
}
}
To send this to our Mosquitto MQTT Broker we can pipe the above command to mosquitto_pub
, as below:
/usr/share/doc/wireguard-tools/examples/json/wg-json | mosquitto_pub --host 192.168.1.151:1883 --stdin-file --topic wireguard/dump
- I run Mosquitto on yet another device, so have to specify the host address, otherwise it defaults to
localhost
and searches for a broker on your Wireguard device. -
--stdin-file
ensuresmosquitto_pub
ingests the full contents of thewg-json
output, and sends it as a single message. - I am dumping to the MQTT topic
wireguard/dump
I have added this command into Crontab, to send this data every minute.
*/1 * * * * /usr/share/doc/wireguard-tools/examples/json/wg-json | mosquitto_pub --host 192.168.1.151 --stdin-file --topic wireguard/dump
openHAB
I have a connection to my Mosquitto MQTT Broker as described in this tutorial. Importantly, my Broker Thing is called MosquittoMqttBroker
.
Thing
things file
// Wireguard Client1
Thing mqtt:topic:wireguardClient1 "Wireguard Client1" (mqtt:broker:MosquittoMqttBroker) {
Channels:
Type string : endpoint "endpoint" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.endpoint"
]
Type string : latestHandshake "latestHandshake" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.latestHandshake"
]
Type datetime : latestHandshake2 "latestHandshake2" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.latestHandshakeā©JS:epoch2datetime.js"
]
Type string : transferRx "transferRx" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.transferRx"
]
Type string : transferTx "transferTx" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.transferTx"
]
}
// Wireguard Client2
Thing mqtt:topic:wireguardClient2 "Wireguard Client2" (mqtt:broker:MosquittoMqttBroker) {
Channels:
Type string : endpoint "endpoint" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.endpoint"
]
Type string : latestHandshake "latestHandshake" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.latestHandshake"
]
Type datetime : latestHandshake2 "latestHandshake2" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.latestHandshakeā©JS:epoch2datetime.js"
]
Type string : transferRx "transferRx" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.transferRx"
]
Type string : transferTx "transferTx" [
stateTopic="wireguard/dump",
transformationPattern="JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.transferTx"
]
}
MainUI YAML
Client 1
UID: mqtt:topic:wireguardClient1
label: Wireguard Client1
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:MosquittoMqttBroker
channels:
- id: endpoint
channelTypeUID: mqtt:string
label: endpoint
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.endpoint
- id: latestHandshake
channelTypeUID: mqtt:string
label: latestHandshake
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.latestHandshake
- id: latestHandshake2
channelTypeUID: mqtt:datetime
label: latestHandshake2
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.latestHandshakeā©JS:epoch2datetime.js
- id: transferRx
channelTypeUID: mqtt:string
label: transferRx
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.transferRx
- id: transferTx
channelTypeUID: mqtt:string
label: transferTx
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=.transferTx
Client 2
UID: mqtt:topic:wireguardClient2
label: Wireguard Client2
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:MosquittoMqttBroker
channels:
- id: endpoint
channelTypeUID: mqtt:string
label: endpoint
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.endpoint
- id: latestHandshake
channelTypeUID: mqtt:string
label: latestHandshake
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.latestHandshake
- id: latestHandshake2
channelTypeUID: mqtt:datetime
label: latestHandshake2
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.latestHandshakeā©JS:epoch2datetime.js
- id: transferRx
channelTypeUID: mqtt:string
label: transferRx
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.transferRx
- id: transferTx
channelTypeUID: mqtt:string
label: transferTx
description: null
configuration:
retained: false
postCommand: false
formatBeforePublish: "%s"
stateTopic: wireguard/dump
transformationPattern: JSONPATH:$.wg0.peers.jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=.transferTx
Transforms
epoch2datetime.js
(function(epoch) {
return new Date(epoch*1000).toISOString();
})(input)
Items
Items file
String strWireguardClient1Endpoint {channel="mqtt:topic:wireguardClient1:endpoint"}
String strWireguardClient1LatestHandshake {channel="mqtt:topic:wireguardClient1:latestHandshake"}
DateTime dtWireguardClient1LatestHandshake2 {channel="mqtt:topic:wireguardClient1:latestHandshake2",stateDescription=""[pattern="%1$td/%1$tm/%1$tY %1$tH:%1$tM"]}
String strWireguardClient1EndpointTransferRx {channel="mqtt:topic:wireguardClient1:transferRx"}
String strWireguardClient1EndpointTransferTx {channel="mqtt:topic:wireguardClient1:transferTx"}
String strWireguardClient2Endpoint {channel="mqtt:topic:wireguardClient2:endpoint"}
String strWireguardClient2LatestHandshake {channel="mqtt:topic:wireguardClient2:latestHandshake"}
DateTime dtWireguardClient2LatestHandshake2 {channel="mqtt:topic:wireguardClient2:latestHandshake2",stateDescription=""[pattern="%1$td/%1$tm/%1$tY %1$tH:%1$tM"]}
String strWireguardClient2EndpointTransferRx {channel="mqtt:topic:wireguardClient2:transferRx"}
String strWireguardClient2EndpointTransferTx {channel="mqtt:topic:wireguardClient2:transferTx"}
The dtWireguardClient1LatestHandshake2
and dtWireguardClient2LatestHandshake2
Items will be formatted nicely so you can see when the last time that the client performed a handshake was. dtWireguardClient1LatestHandshake
and dtWireguardClient2LatestHandshake
contain the same information, but in seconds since the epoch - this may be more useful in rules.