# 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-*`) ```yaml 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: ```json {"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`.