feat(diagnostics): UI-Tools — ping/traceroute/dig/curl/tcp

Operator-Diagnose ohne SSH. Sidebar → System → Diagnose.

internal/services/diagnostics/:
  - Ping        — ping -c4 -W2 (12s timeout)
  - Traceroute  — traceroute -n -w2 -q1 -m20 (60s timeout)
  - Dig         — dig +timeout=3 +tries=2 <TYPE> <NAME> (Types A/AAAA/
                  CNAME/MX/TXT/NS/SOA/PTR/SRV/CAA whitelisted)
  - Curl        — curl -IsSv --max-time 10 (nur http(s)://, kein
                  file:// / smb:// / data://)
  - TCPProbe    — nc -zv -w5 (8s timeout)

Sicherheit: validTarget() prüft jeden Input gegen Allow-List
[a-zA-Z0-9.:/_-]; verhindert Shell-Metachar-Injection. exec.Command
mit nackten Argument-Slices (kein /bin/sh, kein Glob-Expansion).

internal/handlers/diagnostics.go: POST /api/v1/diagnostics/<tool>
hinter requireAuth.

UI (pages/Diagnostics): 5 Tool-Cards, jede mit eigenem Input + Run-
Button + monospace-Output-Pane (dunkel, scrollbar, max-height 320px).
Pro Tool ein Status-Tag (OK / exit N) + Dauer-ms. info-Alert oben
erklärt dass Tools auf der Box laufen, nicht im Browser; security-
Alert unten erklärt die Restrictions.

control: iputils-ping, traceroute, dnsutils, curl, netcat-openbsd
als Depends. Auf Test-Box bereits da (waren Distro-defaults).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-13 15:30:07 +02:00
parent e07b484a48
commit 5bdea1bced
13 changed files with 570 additions and 8 deletions

View File

@@ -21,6 +21,7 @@
"cluster": "Cluster",
"logs": "Logs",
"backups": "Backups",
"diagnostics": "Diagnostics",
"license": "License",
"settings": "Settings",
"section": {
@@ -681,6 +682,20 @@
"src": "Source IP"
}
},
"diag": {
"title": "Diagnostics",
"intro": "Operator tools straight from the UI: ping, traceroute, DNS, HTTP probe, TCP connect. All calls run authenticated on this box (not in the browser).",
"run": "Run",
"runFromBoxTitle": "Tools run on the EdgeGuard box",
"runFromBoxDesc": "These calls use the EdgeGuard's outbound connectivity — not your laptop's. If ping/curl fails here, the box's network layer is the issue (firewall rules, default route, DNS).",
"ping": { "intro": "ICMP echo-request × 4, 2 s timeout per packet. Measures loss + RTT." },
"trace": { "intro": "Hop-by-hop path with UDP probes (max 20 hops, no reverse-DNS)." },
"dig": { "intro": "DNS lookup via unbound (box resolver). Shows answer + AUTHORITY/ADDITIONAL section." },
"curl": { "intro": "HTTPS probe with -IsSv: TLS handshake details + headers. Does NOT follow redirects." },
"tcp": { "intro": "Pure TCP connect (no I/O). Ideal to verify a backend port is reachable." },
"securityTitle": "Security note",
"securityDesc": "Endpoints are behind admin auth. Targets are validated against a strict allow-list (no shell metachars). curl is restricted to http(s) — no file:// / smb:// / data://."
},
"backups": {
"title": "Backups",
"intro": "Snapshots of the PostgreSQL database + /var/lib/edgeguard (setup, license, JWT, ACME account). Daily auto job + manual trigger.",