vpn eww and eww crash
This commit is contained in:
@@ -70,8 +70,60 @@ state() {
|
||||
"$w_connected" "$w_enabled" "$w_icon" "$(jstr "$w_ssid")" "$w_ip" "${w_freq:-0}" "$(band "$w_freq")" "$w_gen" "${w_signal:-0}"
|
||||
printf '"ethernet":{"connected":%s,"interface":"%s","ip":"%s","speed":"%s"},' \
|
||||
"$e_connected" "$eth" "$e_ip" "$e_speed"
|
||||
printf '"usb":{"connected":%s,"interface":"%s","ip":"%s"}}' \
|
||||
printf '"usb":{"connected":%s,"interface":"%s","ip":"%s"},' \
|
||||
"$u_connected" "$usb" "$u_ip"
|
||||
wg_json
|
||||
printf '}'
|
||||
}
|
||||
|
||||
# --- WireGuard: interfaces from the wireguard-<name>.service units (so a
|
||||
# tunnel that is down still shows up) plus any live wireguard-type link.
|
||||
# `wg show` needs root, so peer names and the endpoint come from the peer
|
||||
# units instead.
|
||||
|
||||
wg_ifaces() {
|
||||
{
|
||||
systemctl list-units --all --plain --no-legend 'wireguard-*.service' 2>/dev/null \
|
||||
| awk '$1 !~ /-peer-/ { sub(/^wireguard-/, "", $1); sub(/\.service$/, "", $1); print $1 }'
|
||||
ip -d -o link 2>/dev/null | awk '/ wireguard / { sub(":", "", $2); print $2 }'
|
||||
} | sort -u
|
||||
}
|
||||
|
||||
human_bytes() {
|
||||
awk -v b="${1:-0}" 'BEGIN {
|
||||
split("B KiB MiB GiB TiB", u, " "); i = 1
|
||||
while (b >= 1024 && i < 5) { b /= 1024; i++ }
|
||||
printf (i == 1 ? "%d %s" : "%.1f %s"), b, u[i] }'
|
||||
}
|
||||
|
||||
wg_json() { # prints the "wireguard" array and the "vpn" summary
|
||||
local name up ip rx tx peers endpoint peer_unit peer_script sep="" out="[" vpn_up=false vpn_name=""
|
||||
while read -r name; do
|
||||
[[ -n $name ]] || continue
|
||||
up=false ip="" rx=0 tx=0 endpoint=""
|
||||
if [[ -d /sys/class/net/$name ]]; then
|
||||
ip -o link show "$name" 2>/dev/null | grep -q '<[^>]*UP' && up=true
|
||||
ip=$(ipv4 "$name")
|
||||
rx=$(<"/sys/class/net/$name/statistics/rx_bytes")
|
||||
tx=$(<"/sys/class/net/$name/statistics/tx_bytes")
|
||||
fi
|
||||
peers=$(systemctl list-units --all --plain --no-legend "wireguard-$name-peer-*.service" 2>/dev/null \
|
||||
| awk '{ print $1 }' | sed "s/^wireguard-$name-peer-//; s/\.service\$//" | paste -sd, -)
|
||||
peer_unit=$(systemctl list-units --all --plain --no-legend "wireguard-$name-peer-*.service" 2>/dev/null \
|
||||
| awk 'NR == 1 { print $1 }')
|
||||
# NixOS puts `wg set … endpoint "host:port"` in the peer unit's start script
|
||||
if [[ -n $peer_unit ]]; then
|
||||
peer_script=$(systemctl show -p ExecStart --value "$peer_unit" 2>/dev/null \
|
||||
| sed -n 's/.*path=\([^ ;]*\).*/\1/p' | awk 'NR == 1')
|
||||
[[ -r $peer_script ]] && endpoint=$(grep -o 'endpoint "[^"]*"' "$peer_script" 2>/dev/null \
|
||||
| awk -F'"' 'NR == 1 { print $2 }')
|
||||
fi
|
||||
if [[ $up == true && $vpn_up == false ]]; then vpn_up=true vpn_name=$name; fi
|
||||
[[ -z $vpn_name ]] && vpn_name=$name
|
||||
out+="$sep{\"name\":\"$(jstr "$name")\",\"up\":$up,\"ip\":\"$ip\",\"rx\":\"$(human_bytes "$rx")\",\"tx\":\"$(human_bytes "$tx")\",\"peers\":\"$(jstr "$peers")\",\"endpoint\":\"$(jstr "$endpoint")\"}"
|
||||
sep=,
|
||||
done < <(wg_ifaces)
|
||||
printf '"wireguard":%s],"vpn":{"up":%s,"name":"%s"}' "$out" "$vpn_up" "$(jstr "$vpn_name")"
|
||||
}
|
||||
|
||||
refresh() { emit "$(state)"; }
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bring the WireGuard tunnel $1 down (stop its service, which takes the peer
|
||||
# units with it) or up (start its target, which pulls service and peers).
|
||||
# Needs the polkit rule from modules/nixos/system/network/wireguard.
|
||||
name=$1
|
||||
[[ -n $name ]] || exit 64
|
||||
if [[ -d /sys/class/net/$name ]]; then
|
||||
systemctl stop "wireguard-$name.service"
|
||||
else
|
||||
systemctl start "wireguard-$name.target"
|
||||
fi
|
||||
Reference in New Issue
Block a user