Files
bf-infra/adguard/ha-self-service.md
Christoph Emsenhuber 7edf01b021 TP23 Stufe 5: HA-Self-Service + Dashboard-Draft + Doku-Nachzug
- agh-exception.py: Creds aus Env/Datei (Mac ~/.secrets + HAOS /config), Domain/IP-Validierung
- HA-Self-Service dokumentiert: shell_command + Helper/Timer/2 Automations (adguard/ha-self-service.md)
- Eigenes Dashboard 'dns-ausnahmen' (1. Draft, sections) inkl. Repro-JSON
- teilprojekte.md: TP23 Quick-Index + dated Update + Ist-Stand-Block nachgezogen
  (Stufe 1-5 durch; offen nur Stufe 6 Bypass-Sperre -> separate Session)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-06 16:45:00 +02:00

4.3 KiB

TP23 Stufe 5 — HA-Self-Service für DNS-Ausnahmen

Home Assistant (HAOS-VM 100, 10.40.20.105) gibt eine Ein-Klick-Oberfläche, um eine Domain temporär (JIT) über das AGH-Paar .36/.37 zu entsperren. Ablauf/Revert nativ per timer.

Warum kein rest_command: die AGH-Endpunkte sind read-modify-write (set_rules ersetzt die ganze Liste). HA ruft deshalb die deployte RMW-CLI agh-exception.py per shell_command.

Bausteine (alle in HA .storage, via ha-mcp angelegt — keine YAML außer shell_command)

Typ entity_id Zweck
input_text input_text.dns_ausnahme_domain einzugebende Domain
input_text input_text.dns_ausnahme_aktiv aktuell aktive Ausnahme (für leak-freien Revert; init "")
input_select input_select.dns_ausnahme_dauer 15 Minuten / 1 Stunde / 4 Stunden
timer timer.dns_ausnahme JIT-Countdown (restore=false)
input_button input_button.dns_ausnahme_starten Auslöser
automation automation.dns_ausnahme_starten Button → validieren, alte Ausnahme aufräumen, agh_allow_domain, Timer starten
automation automation.dns_ausnahme_ablauf timer.finished/timer.cancelled → agh_unallow_domain, _aktiv leeren

configuration.yaml (der einzige YAML-Teil, Backup .bak-tp23-*)

shell_command:
  agh_allow_domain: "python3 /config/agh-exception.py allow-domain '{{ domain }}'"
  agh_unallow_domain: "python3 /config/agh-exception.py unallow-domain '{{ domain }}'"
  agh_unfilter_client: "python3 /config/agh-exception.py unfilter '{{ ip }}'"
  agh_refilter_client: "python3 /config/agh-exception.py refilter '{{ ip }}'"

Neue Domain → HA-Neustart nötig (reload_all lädt eine erstmals hinzugefügte Domain nicht).

Deploy auf HAOS (Zugang ssh admin@10.40.20.105, sudo passwortlos)

  • /config/agh-exception.py — Kopie von adguard/agh-exception.py (liest Creds via /config/agh-exception.secrets).
  • /config/agh-exception.secrets (chmod 600, root) — AGH_AUTOMATION_USER/_PASS.
  • Redeploy nach Script-Änderung: base64 < adguard/agh-exception.py | ssh admin@10.40.20.105 "base64 -d | sudo tee /config/agh-exception.py >/dev/null".

Bedienung

Domain eintragen → Dauer wählen → DNS-Ausnahme starten. Bei Ablauf/Abbruch wird die Regel auf beiden AGH automatisch zurückgenommen. Ungültige Domains werden HA- und CLI-seitig abgelehnt.

Dashboard (1. Draft, 2026-09-06)

Eigenes storage-mode Dashboard url_path: dns-ausnahmen (Sidebar, require_admin: false), angelegt via ha_config_set_dashboard. Da es in HA-.storage lebt, hier die Repro-Quelle:

{"views":[{"title":"DNS-Ausnahmen","path":"dns","type":"sections","icon":"mdi:dns","max_columns":2,"sections":[
 {"type":"grid","cards":[
   {"type":"heading","heading":"Domain temporaer freigeben","icon":"mdi:lock-open-variant"},
   {"type":"entities","entities":[{"entity":"input_text.dns_ausnahme_domain","name":"Domain"},{"entity":"input_select.dns_ausnahme_dauer","name":"Dauer"}]},
   {"type":"button","name":"DNS-Ausnahme starten","icon":"mdi:lock-open-check","tap_action":{"action":"perform-action","perform_action":"input_button.press","target":{"entity_id":"input_button.dns_ausnahme_starten"}},"grid_options":{"columns":"full"}}]},
 {"type":"grid","cards":[
   {"type":"heading","heading":"Status","icon":"mdi:information-outline"},
   {"type":"tile","entity":"timer.dns_ausnahme","name":"Restlaufzeit"},
   {"type":"tile","entity":"input_text.dns_ausnahme_aktiv","name":"Aktive Ausnahme"},
   {"type":"markdown","content":"**AGH-Resolver-Paar** — .36: {{ states('binary_sensor.adguard_bf1_status') }} / .37: {{ states('binary_sensor.adguard_bf2_status') }}"}]},
 {"type":"grid","cards":[
   {"type":"heading","heading":"VLAN-Filter-Policy (AGH-Gruppen)","heading_style":"subtitle"},
   {"type":"markdown","content":"MAIN/IOT/UNTRUSTED=an · INFRA/MEDIA/MGMT=aus · GUEST=an+SafeSearch/Parental · dns-bypass-exempt=aus"}]}
]}]}

⚠️ Draft-Notiz: binary_sensor.adguard_bf1_status ist stale (hing am alten .16-Container, TP42) — zeigt evtl. unavailable, obwohl .36 läuft. Sensor-Quelle gehört bei Gelegenheit auf .36 gefixt.

Verifiziert (2026-09-04)

Button → @@||doubleclick.net^ auf .36+.37, Timer 15:00, _aktiv gesetzt; Timer-Abbruch → Regel auf beiden entfernt, _aktiv geleert, .36==.37.