diff --git a/wireguard/config.json b/wireguard/config.json index efc5f68..adf8e73 100755 --- a/wireguard/config.json +++ b/wireguard/config.json @@ -13,8 +13,13 @@ "i386" ], "ports": { + "80/tcp": null, "51820/udp": 51820 }, + "ports_description": { + "80/tcp": "WireGuard peers status API", + "51820/udp": "WireGuard: forward this port in your router" + }, "boot": "auto", "hassio_api": true, "hassio_role": "default", diff --git a/wireguard/rootfs/etc/cont-init.d/config.sh b/wireguard/rootfs/etc/cont-init.d/config.sh index 47bcd19..62e99f5 100644 --- a/wireguard/rootfs/etc/cont-init.d/config.sh +++ b/wireguard/rootfs/etc/cont-init.d/config.sh @@ -21,6 +21,7 @@ declare post_up declare pre_shared_key declare server_private_key declare server_public_key +declare filename if ! bashio::fs.directory_exists '/ssl/wireguard'; then mkdir -p /ssl/wireguard || @@ -119,6 +120,12 @@ if bashio::config.has_value 'server.dns'; then dns=$(bashio::config "server.dns | join(\", \")") fi +# Status API Storage +if ! bashio::fs.directory_exists '/var/lib/wireguard'; then + mkdir -p /var/lib/wireguard \ + || bashio::exit.nok "Could not create status API storage folder" +fi + # Fetch all the peers for peer in $(bashio::config 'peers|keys'); do @@ -222,4 +229,8 @@ for peer in $(bashio::config 'peers|keys'); do # Generate QR code with client configuration qrencode -t PNG -o "${config_dir}/qrcode.png" < "${config_dir}/client.conf" + + # Store client name for the status API based on public key + filename=$(sha1sum <<< "${peer_public_key}" | awk '{ print $1 }') + echo -n "${name}" > "/var/lib/wireguard/${filename}" done diff --git a/wireguard/rootfs/etc/services.d/api/run b/wireguard/rootfs/etc/services.d/api/run new file mode 100644 index 0000000..dc139e8 --- /dev/null +++ b/wireguard/rootfs/etc/services.d/api/run @@ -0,0 +1,52 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Community Hass.io Add-ons: WireGuard +# The most simple HTTP API you've ever seen. +# Provides status of WireGuard peers. +# ============================================================================== +declare -a peers +declare endpoint +declare json +declare latest_handshake +declare line +declare name +declare peer +declare public_key +declare transfer_rx +declare transfer_tx + +while true; do + # Get information from wg + peers=() + while IFS=$'\t' read -r -a line; do + if [[ "${#line[@]}" -gt 6 ]]; then + endpoint="${line[3]}" + latest_handshake="${line[5]}" + public_key="${line[1]}" + transfer_rx="${line[6]}" + transfer_tx="${line[7]}" + + peer=$(bashio::var.json \ + 'endpoint' "${endpoint}" \ + 'latest_handshake' "^${latest_handshake}" \ + 'transfer_rx' "^${transfer_rx}" \ + 'transfer_tx' "^${transfer_tx}") + + filename=$(sha1sum <<< "${public_key}" | awk '{ print $1 }') + if bashio::fs.file_exists "/var/lib/wireguard/${filename}"; then + name=$(<"/var/lib/wireguard/${filename}") + peers+=("${name}") + peers+=("^${peer}") + fi + fi + done <<< "$(wg show all dump)" + + # Build final json content + json="{}" + if [[ "${#peers[@]}" -ne 0 ]]; then + json=$(bashio::var.json "${peers[@]}") + fi + + echo -e "HTTP/1.1 200 OK\r\nContent-type: application/json\r\n\r\n${json}" \ + | nc -l -p 80 > /dev/null +done