feat(wg): clusev-wg.sh collect — emit run/wg-status.json for the dashboard
parent
dfdb0ce732
commit
c164c0aec3
|
|
@ -15,6 +15,12 @@ WG_ENV="${STATE_DIR}/wg.env"
|
|||
GATE_MARKER="${STATE_DIR}/wg-gate.enabled"
|
||||
PANEL_PORTS="80,443" # see spec §3 post-DNAT note: matches the published container ports (Caddy 80/443)
|
||||
|
||||
# Project root (for the run/ bridge dir). The collect timer sets CLUSEV_DIR; otherwise derive it
|
||||
# from this script's location (docker/wg/clusev-wg.sh -> ../..).
|
||||
SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CLUSEV_DIR="${CLUSEV_DIR:-$(cd "${SELF_DIR}/../.." && pwd)}"
|
||||
RUN_DIR="${CLUSEV_DIR}/run"
|
||||
|
||||
bold() { printf '\033[1m%s\033[0m\n' "$*"; }
|
||||
info() { printf ' %s\n' "$*"; }
|
||||
warn() { printf '\033[33m ! %s\033[0m\n' "$*" >&2; }
|
||||
|
|
@ -259,6 +265,61 @@ EOF
|
|||
info "1) Client importieren (QR oben), 2) http://${server_ip} ueber den Tunnel oeffnen, 3) dann: clusev wg up"
|
||||
}
|
||||
|
||||
# Emit run/wg-status.json (atomic temp+mv). Public, NO secrets. If WG isn't configured, emits
|
||||
# {"configured":false}. Run every few seconds by clusev-wg-collect.timer; the dashboard reads it.
|
||||
cmd_collect() {
|
||||
mkdir -p "$RUN_DIR" 2>/dev/null || true
|
||||
local now tmp dest
|
||||
now="$(date +%s 2>/dev/null || echo 0)"
|
||||
dest="${RUN_DIR}/wg-status.json"
|
||||
tmp="$(mktemp "${RUN_DIR}/.wg-status.XXXXXX" 2>/dev/null)" || tmp="${RUN_DIR}/.wg-status.tmp"
|
||||
|
||||
if [ ! -f "$WG_CONF" ]; then
|
||||
printf '{"at":%s,"configured":false}\n' "$now" > "$tmp"
|
||||
mv -f "$tmp" "$dest" 2>/dev/null || { rm -f "$tmp"; return 0; }
|
||||
chmod 644 "$dest" 2>/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
[ -f "$WG_ENV" ] && . "$WG_ENV"
|
||||
local gate_marker=false gate_chain=false wgq
|
||||
[ -f "$GATE_MARKER" ] && gate_marker=true
|
||||
iptables -nL "$GATE_CHAIN" >/dev/null 2>&1 && gate_chain=true
|
||||
wgq="$(systemctl is-active "wg-quick@${WG_IF}" 2>/dev/null || echo inactive)"
|
||||
|
||||
# Peers from `wg show wg0 dump`, named via the wg0.conf `# clusev-peer:` comments. Peer names are
|
||||
# valid_name-restricted and pubkeys/endpoints are from safe charsets, so the values are JSON-safe.
|
||||
local peers_json
|
||||
peers_json="$({ wg show "$WG_IF" dump 2>/dev/null || true; } | awk -v conf="$WG_CONF" '
|
||||
BEGIN {
|
||||
name=""
|
||||
while ((getline line < conf) > 0) {
|
||||
if (line ~ /^# clusev-peer:/) { sub(/^# clusev-peer:[ \t]*/,"",line); name=line }
|
||||
else if (name != "" && line ~ /^PublicKey[ \t]*=/) { p=line; sub(/^PublicKey[ \t]*=[ \t]*/,"",p); names[p]=name; name="" }
|
||||
}
|
||||
close(conf); out=""; first=1
|
||||
}
|
||||
NR==1 { next } # interface line
|
||||
{
|
||||
pk=$1; endp=$3; hs=$5+0; rx=$6+0; tx=$7+0
|
||||
if (endp=="(none)") endp=""
|
||||
nm=(pk in names)?names[pk]:""
|
||||
rec="{\"name\":\"" nm "\",\"pubkey\":\"" pk "\",\"endpoint\":\"" endp "\",\"latest_handshake\":" hs ",\"rx\":" rx ",\"tx\":" tx "}"
|
||||
if (first) { out=rec; first=0 } else { out=out "," rec }
|
||||
}
|
||||
END { printf "[%s]", out }
|
||||
')"
|
||||
[ -n "$peers_json" ] || peers_json="[]"
|
||||
|
||||
printf '{"at":%s,"configured":true,"gate":{"marker":%s,"chain":%s},"wg_quick":"%s","server":{"subnet":"%s","server_ip":"%s","port":%s,"endpoint":"%s","pubkey":"%s"},"peers":%s}\n' \
|
||||
"$now" "$gate_marker" "$gate_chain" "$wgq" \
|
||||
"${WG_SUBNET:-}" "${WG_SERVER_IP:-}" "${WG_PORT:-0}" "${WG_ENDPOINT:-}" "${WG_SERVER_PUBKEY:-}" \
|
||||
"$peers_json" > "$tmp"
|
||||
mv -f "$tmp" "$dest" 2>/dev/null || { rm -f "$tmp"; return 0; }
|
||||
chmod 644 "$dest" 2>/dev/null || true
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
clusev wg — WireGuard-Zugang (Host)
|
||||
|
|
@ -283,6 +344,7 @@ case "$cmd" in
|
|||
add-peer) cmd_add_peer "$@" ;;
|
||||
remove-peer) cmd_remove_peer "$@" ;;
|
||||
gate-apply) need_root gate-apply; gate_apply ;; # called by clusev-wg-gate.service
|
||||
collect) cmd_collect ;; # called by clusev-wg-collect.timer (read-only; no root needed)
|
||||
help|-h|--help) usage ;;
|
||||
*) printf 'Unbekannter Befehl: %s\n\n' "$cmd" >&2; usage; exit 64 ;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Reference in New Issue