-
-
Save kafeg/51689dcad1b175481d7586d36a2b5af8 to your computer and use it in GitHub Desktop.
Wireguard CLI to MQTT Bash Script - For getting Wireguard information in to Home Assistant MQTT sensors
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
# A script to pull information from the Wireguard CLI and print | |
# Based on the original script from here https://gist.github.com/mehstg/466045bbd0316d7be0a196c1a049477e | |
# Original script publishes to MQTT, but in my case broker unavilable, I call this script via SSH from HomeAssistant | |
#!/bin/bash | |
# Function to parse the transfer line and convert units to bytes | |
parse_transfer_line() { | |
local line="$1" | |
# Split the line by spaces and extract the values and units | |
local received_value=$(echo "$line" | awk '{print $1}') | |
local received_unit=$(echo "$line" | awk '{print $2}') | |
local sent_value=$(echo "$line" | awk '{print $3}') | |
local sent_unit=$(echo "$line" | awk '{print $4}') | |
# Convert received to bytes | |
case "$received_unit" in | |
"GiB") | |
received_bytes=$(echo "$received_value * 1024 * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"MiB") | |
received_bytes=$(echo "$received_value * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"TiB") | |
received_bytes=$(echo "$received_value * 1024 * 1024 * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"KiB") | |
received_bytes=$(echo "$received_value * 1024" | bc | awk '{print int($1)}') | |
;; | |
"B") | |
received_bytes=$(echo "$received_value" | awk '{print int($1)}') | |
;; | |
esac | |
# Convert sent to bytes | |
case "$sent_unit" in | |
"GiB") | |
sent_bytes=$(echo "$sent_value * 1024 * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"MiB") | |
sent_bytes=$(echo "$sent_value * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"TiB") | |
sent_bytes=$(echo "$sent_value * 1024 * 1024 * 1024 * 1024" | bc | awk '{print int($1)}') | |
;; | |
"KiB") | |
sent_bytes=$(echo "$sent_value * 1024" | bc | awk '{print int($1)}') | |
;; | |
"B") | |
sent_bytes=$(echo "$sent_value" | awk '{print int($1)}') | |
;; | |
esac | |
# Print the received and sent bytes | |
echo "$received_bytes $sent_bytes" | |
} | |
while IFS= read -r RESULT | |
do | |
IP=$(docker exec amnezia-awg wg | grep -A 5 $RESULT | grep 'endpoint' | sed 's/endpoint://' | sed -e 's/^[[:space:]]*//') | |
ALLOWED_IPS=$(docker exec amnezia-awg wg | grep -A 5 $RESULT | grep 'allowed ips' | sed 's/allowed ips://' | sed -e 's/^[[:space:]]*//') | |
LASTSEEN=$(docker exec amnezia-awg wg | grep -A 5 $RESULT | grep 'latest' | sed 's/latest handshake://' | sed -e 's/^[[:space:]]*//') | |
DATA=$(docker exec amnezia-awg wg | grep -A 5 $RESULT | grep 'transfer' | sed 's/transfer://' | sed -e 's/^[[:space:]]*//') | |
PEER_ID_CLEAN=$(echo $RESULT | tr -d '+#/=,') | |
PEER_NAME_CLEAN=$(docker exec amnezia-awg cat /opt/amnezia/awg/clientsTable | grep $RESULT -A 5 | grep clientName | sed -e 's/^[[:space:]]*//' | cut -d" " -f2 | tr -d '"+#/=,') | |
received_bytes="0" | |
sent_bytes="0" | |
DATA_CLEAN=$(echo $DATA | sed 's/received//' | sed 's/sent//' | sed 's/,//' | sed 's/^ *//;s/ *$//') | |
received_sent=$(parse_transfer_line "$DATA_CLEAN") | |
received_bytes=$(echo "$received_sent" | awk '{print $1}') | |
sent_bytes=$(echo "$received_sent" | awk '{print $2}') | |
FINAL='{"id":"'"$PEER_ID_CLEAN"'","name":"'"$PEER_NAME_CLEAN"'","ip":"'"$IP"'","allowed":"'"$ALLOWED_IPS"'","handshake":"'"$LASTSEEN"'","data":"'"$DATA"'","rx":"'"$received_bytes"'","tx":"'"$sent_bytes"'"}' | |
echo $FINAL | |
done < <(docker exec amnezia-awg wg | grep peer | cut -d" " -f2) |
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
# This script must be runned in the HomeAssistant container (for e.g. save it in ./homeassistant/packages/wireguard_mqtt/wireguard_mqtt.sh) | |
# After the call it will ssh to server, get WireGuard stats and publish it to local MQTT broker | |
# Please keep in mind you must have set up SSH keys to access servers from Home Assistant + added to known hosts | |
#!/bin/bash | |
MQTT_IP="core-mosquitto.local.hass.io" | |
MQTT_USERNAME="user" # change to yours | |
MQTT_PASSWORD="pass" # change to yours | |
# Function to generate a shortened client identifier using first and last characters | |
shorten_client_id() { | |
local client_id="$1" | |
local shortened="${client_id:0:4}-${client_id: -4}" | |
echo "$shortened" | |
} | |
# Function to generate a custom client identifier using the = inserties for better line breaks | |
insert_hyphens() { | |
local input="$1" | |
local output="" | |
# Use a loop to read 8 characters at a time and append them with a hyphen | |
while [[ -n "$input" ]]; do | |
output+="${input:0:8}-" | |
input="${input:8}" | |
done | |
# Remove the trailing hyphen | |
output="${output%-}" | |
echo "$output" | |
} | |
# Function to detect online status (handshake <= 5 minutes ago) | |
check_status() { | |
local handshake="$1" | |
if [[ -z "$handshake" ]]; then | |
echo "OFF" | |
return | |
fi | |
# Convert handshake to minutes | |
local minutes=0 | |
if [[ "$handshake" == *"day"* ]]; then | |
echo "OFF" | |
return | |
elif [[ "$handshake" == *"minute"* ]]; then | |
minutes=$(echo "$handshake" | awk '{print $1}') | |
elif [[ "$handshake" == *"second"* ]]; then | |
minutes=0 | |
fi | |
if [[ $minutes -lt 5 ]]; then | |
echo "ON" | |
else | |
echo "OFF" | |
fi | |
} | |
# Function to publish MQTT configuration for each entity | |
publish_mqtt_config() { | |
topic="$1" | |
model="$2" | |
prefix="$3" | |
client="$4" | |
short_client_id=$(shorten_client_id "$client") | |
breaked_client_id=$(insert_hyphens "$client") | |
ip="$5" | |
allowed="$6" | |
handshake="$7" | |
received="$8" | |
sent="$9" | |
data="${10}" | |
name="${11}" | |
status=$(check_status "$handshake") | |
# Publish IP sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/ip/config" -m \ | |
"{ | |
\"name\": \"IP\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.ip }}\", | |
\"unique_id\": \"${short_client_id}_ip\", | |
\"icon\": \"mdi:ip\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"], | |
\"name\": \"${prefix} ${short_client_id}\", | |
\"manufacturer\": \"WireGuard\", | |
\"model\": \"$model\" | |
} | |
}" | |
# Publish Allowed IPs sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/allowed/config" -m \ | |
"{ | |
\"name\": \"Allowed IPs\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.allowed }}\", | |
\"unique_id\": \"${short_client_id}_allowed\", | |
\"icon\": \"mdi:format-list-bulleted\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Full Client Identifier sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/id/config" -m \ | |
"{ | |
\"name\": \"Uniq Id\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.id }}\", | |
\"unique_id\": \"${short_client_id}_id\", | |
\"icon\": \"mdi:identifier\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Last Seen sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/handshake/config" -m \ | |
"{ | |
\"name\": \"Last Handshake\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.handshake }}\", | |
\"unique_id\": \"${short_client_id}_handshake\", | |
\"icon\": \"mdi:handshake\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Received sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/rx/config" -m \ | |
"{ | |
\"name\": \"Received\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.rx }}\", | |
\"unique_id\": \"${short_client_id}_rx\", | |
\"icon\": \"mdi:call-received\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Sent sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/tx/config" -m \ | |
"{ | |
\"name\": \"Sent\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.tx }}\", | |
\"unique_id\": \"${short_client_id}_tx\", | |
\"icon\": \"mdi:call-made\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Data string sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/data/config" -m \ | |
"{ | |
\"name\": \"Data\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.data }}\", | |
\"unique_id\": \"${short_client_id}_data\", | |
\"icon\": \"mdi:cable-data\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Name sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/sensor/${prefix}_${short_client_id}/name/config" -m \ | |
"{ | |
\"name\": \"Name\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.name }}\", | |
\"unique_id\": \"${short_client_id}_name\", | |
\"icon\": \"mdi:devices\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
# Publish Status sensor configuration | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "homeassistant/binary_sensor/${prefix}_${short_client_id}/status/config" -m \ | |
"{ | |
\"name\": \"Online status\", | |
\"state_topic\": \"${topic}/${short_client_id}\", | |
\"value_template\": \"{{ value_json.status }}\", | |
\"unique_id\": \"${short_client_id}_status\", | |
\"device\": { | |
\"identifiers\": [\"${prefix}_${short_client_id}\"] | |
} | |
}" | |
} | |
publish_mqtt_values() { | |
topic="$1" | |
model="$2" | |
prefix="$3" | |
client="$4" | |
short_client_id=$(shorten_client_id "$client") | |
breaked_client_id=$(insert_hyphens "$client") | |
ip="$5" | |
allowed="$6" | |
handshake="$7" | |
received="$8" | |
sent="$9" | |
data="${10}" | |
name="${11}" | |
status=$(check_status "$handshake") | |
mosquitto_pub -h $MQTT_IP -u $MQTT_USERNAME -P $MQTT_PASSWORD -t "${topic}/${short_client_id}" -m \ | |
"{ | |
\"id\": \"${breaked_client_id:=-}\", | |
\"ip\": \"${ip:=-}\", | |
\"allowed\": \"${allowed:=-}\", | |
\"handshake\": \"${handshake:=-}\", | |
\"rx\": \"${received:=-}\", | |
\"tx\": \"${sent:=-}\", | |
\"data\": \"${data:=-}\", | |
\"name\": \"${name:=-}\", | |
\"status\": \"${status:=-}\" | |
}" | |
} | |
# vpn.example.com (auth by SSH keys must be activated) | |
while IFS= read -r RESULT | |
do | |
# first params are important: 'MQTT topic', 'device model' and entities 'prefix' | |
publish_mqtt_config "wireguard-vpn" "vpn.example.com" "vpn-wg" "$(echo $RESULT | jq .id -r)" "$(echo $RESULT | jq .ip -r)" "$(echo $RESULT | jq .allowed -r)" "$(echo $RESULT | jq .handshake -r)" "$(echo $RESULT | jq .rx -r)" "$(echo $RESULT | jq .tx -r)" "$(echo $RESULT | jq .data -r)" "$(echo $RESULT | jq .name -r)" | |
sleep 1 | |
publish_mqtt_values "wireguard-vpn" "vpn.example.com" "vpn-wg" "$(echo $RESULT | jq .id -r)" "$(echo $RESULT | jq .ip -r)" "$(echo $RESULT | jq .allowed -r)" "$(echo $RESULT | jq .handshake -r)" "$(echo $RESULT | jq .rx -r)" "$(echo $RESULT | jq .tx -r)" "$(echo $RESULT | jq .data -r)" "$(echo $RESULT | jq .name -r)" | |
#exit 0 | |
done < <(ssh [email protected] -- /root/wireguard_stats.sh) | |
# add more servers here if needed... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment