Konfiguration
Die Instanz wird über Umgebungsvariablen konfiguriert. Ein Teil der Einstellungen lässt sich zusätzlich im Admin-Panel pflegen — dort gilt: eine gesetzte Umgebungsvariable gewinnt immer und die Oberfläche zeigt den Wert schreibgeschützt an (gedacht für Cluster-Deployments, wo die Konfiguration von außen kommt).
Grundeinstellungen
Abschnitt betitelt „Grundeinstellungen“| Variable | Vorgabe | Bedeutung |
|---|---|---|
DNSE_LISTEN | 127.0.0.1:8422 | Adresse und Port |
DNSE_ENCRYPTION_KEY | — | Pflicht. 32 Byte als Hex oder Base64 |
DNSE_ADMIN_USER | admin | Benutzername des Bootstrap-Kontos |
DNSE_ADMIN_PASSWORD | — | Passwort beim allerersten Start (danach wirkungslos) |
DNSE_SERVE_UI | on | off liefert nur die API aus |
DNSE_SECURE_COOKIES | off | Secure für die kurzlebigen SSO-Handschlag-Cookies (EE) — die Anmeldung selbst benutzt keine Cookies mehr |
DNSE_TRUSTED_PROXIES | — | Proxy-IPs/CIDRs, deren X-Forwarded-For gilt |
DNSE_TLS_CERT | — | Zertifikatskette (PEM) — der Dienst spricht dann selbst HTTPS |
DNSE_TLS_KEY | — | Passender privater Schlüssel (PEM); nur zusammen mit DNSE_TLS_CERT |
DNSE_DEMO | off | on registriert den Demo-Provider und legt Beispieldaten an |
DNSE_UPDATE_FEED | Index auf repo.techeve.de | URL des APT-Paketindex für den Update-Hinweis im Admin-Bereich; off schaltet die Abfrage ab |
Datenbank
Abschnitt betitelt „Datenbank“| Variable | Vorgabe | Bedeutung |
|---|---|---|
DNSE_BACKUP_DIR | — | Ablage der nächtlichen Organisations-Sicherung (leer = aus) |
DNSE_DB | ./dnseditor.db | Pfad der SQLite-Datei |
DNSE_DB_DSN | — | PostgreSQL-DSN; ersetzt DNSE_DB |
DNSE_DB_YB | off | on = DNSE_DB_DSN zeigt auf einen YugabyteDB-Cluster (YSQL) |
Details in Datenbank und Schlüssel.
Sessions im Cluster
Abschnitt betitelt „Sessions im Cluster“| Variable | Vorgabe | Bedeutung |
|---|---|---|
DNSE_VALKEY_ADDR | — | host:port eines gemeinsamen Valkey; mehrere Adressen (Komma) = Cluster |
DNSE_VALKEY_PASSWORD | — | AUTH-Passwort, falls gesetzt |
DNSE_SESSION_TTL | 12h | Gültigkeit einer Anmeldung ab der letzten Benutzung |
DNSE_SESSION_TOUCH_INTERVAL | — | Mindestabstand zwischen zwei Auffrischungen; leer = jede Anfrage frischt auf |
Ohne DNSE_VALKEY_ADDR liegen Sessions im Arbeitsspeicher des Prozesses — für
eine einzelne Instanz genau richtig. Sobald mehrere Knoten hinter einem
Loadbalancer laufen, gehört ein gemeinsamer Valkey dazu: Eine Anmeldung auf
Knoten 1 gilt dann auf allen Knoten, und ein Logout wirkt überall.
DNSE_SESSION_TOUCH_INTERVAL bremst das Fortschreiben der Gültigkeit. Ohne
Angabe schreibt jede Anfrage in den Sitzungsspeicher — bei einer einzelnen
Instanz belanglos, bei einem geteilten Valkey unnötige Dauerlast für eine
Angabe, die niemand auf die Minute genau braucht. 5m ist ein brauchbarer
Wert; die Anmeldung läuft dadurch nicht früher ab, sie wird nur seltener
verlängert.
Zertifikate (ACME)
Abschnitt betitelt „Zertifikate (ACME)“| Variable | Vorgabe | Bedeutung |
|---|---|---|
DNSE_ACME_EMAIL | — | Konto-E-Mail; erst damit ist die Ausstellung aktiv |
DNSE_ACME_DIRECTORY | Let’s Encrypt (Produktion) | Abweichendes ACME-Verzeichnis |
DNSE_ACME_PROPAGATION | — | Feste Wartezeit statt Prüfung der autoritativen NS, z. B. 90s |
DNSE_ACME_PROPAGATION braucht man in Split-DNS-Umgebungen, in denen die
Vorabprüfung von lego am internen Resolver scheitert.
Kern-Einstellungen (Admin-Panel oder Environment)
Abschnitt betitelt „Kern-Einstellungen (Admin-Panel oder Environment)“Diese Werte stehen unter Administration → Kern-Einstellungen und lassen sich alternativ per Umgebungsvariable vorgeben:
| Einstellung | Variable | Wofür |
|---|---|---|
| Öffentliche Adresse | DNSE_INSTANCE_URL | Basis für Links in ausgehenden Mails |
| DynDNS-Hostname | DNSE_DYNDNS_HOSTNAME | Update-Adresse für Router |
| DynDNS-Hostname (nur IPv4) | DNSE_DYNDNS_HOSTNAME4 | erzwingt A-Auflösung |
| DynDNS-Hostname (nur IPv6) | DNSE_DYNDNS_HOSTNAME6 | erzwingt AAAA-Auflösung |
| SMTP-Server | DNSE_SMTP_HOST | Postausgang |
| SMTP-Port | DNSE_SMTP_PORT | Postausgang |
| Absender | DNSE_SMTP_FROM | Absenderadresse |
| SMTP-Benutzer | DNSE_SMTP_USERNAME | Authentifizierung |
| SMTP-Passwort | DNSE_SMTP_PASSWORD | verschlüsselt gespeichert, wird nie zurückgegeben |
| ALTCHA-Dienst | DNSE_ALTCHA_URL | Rechenaufgabe vor den öffentlichen Formularen; leer = aus |
| ALTCHA-Token | DNSE_ALTCHA_TOKEN | verschlüsselt gespeichert, wird nie zurückgegeben |
Ohne konfigurierten Postausgang funktionieren Einladungen, Passwort-Resets und Ablauf-Erinnerungen nicht — die Oberfläche zeigt in dem Fall generierte Passwörter direkt an, damit man sie manuell übergeben kann.
ALTCHA statt Captcha
Abschnitt betitelt „ALTCHA statt Captcha“Sind DNSE_ALTCHA_URL und DNSE_ALTCHA_TOKEN gesetzt, bekommen die drei
öffentlichen Formulare — Anmeldung, Registrierung, „Passwort vergessen” —
eine kleine Rechenaufgabe vorgeschaltet (Proof-of-Work, ohne Cookies, ohne
Bilderraten). Der Server prüft jede Einreichung beim Dienst; ohne bestandene
Aufgabe wird das Formular gar nicht erst bearbeitet.
Drei Eigenschaften, die man kennen sollte:
- Fail closed. Antwortet der Dienst nicht, gilt die Einreichung als ungültig. Ohne ihn hätte der Besucher ohnehin keine Aufgabe bekommen, und ein stiller Durchlass hebelte den Schutz bei jeder Störung aus.
- Jede Lösung gilt genau einmal. Der Dienst merkt sich eingereichte Lösungen; die Oberfläche rechnet nach jedem Versuch eine neue.
- Auch der zweite Anmeldeschritt (Zwei-Faktor-Code, Organisationswahl) verlangt eine Lösung — sonst genügte ein mitgeschickter Code, um am Riegel vorbei Passwörter durchzuprobieren.
Die Adresse der Website muss beim Dienst als Herkunft eingetragen sein
(ALTCHA_ORIGINS), sonst verweigert er die Aufgabe. Ist nichts konfiguriert,
bleibt alles wie bisher.
Beispiel: systemd-Unit
Abschnitt betitelt „Beispiel: systemd-Unit“[Unit]Description=DNS-EditorAfter=network-online.target
[Service]User=dnseditorEnvironment=DNSE_LISTEN=127.0.0.1:8422Environment=DNSE_DB_DSN=postgres://dnseditor:…@localhost:5432/dnseditorEnvironment=DNSE_SECURE_COOKIES=onEnvironment=DNSE_INSTANCE_URL=https://dns.example.comEnvironmentFile=/etc/dnseditor/secrets.envExecStart=/usr/local/bin/dnseditorRestart=on-failure
[Install]WantedBy=multi-user.targetDer Verschlüsselungsschlüssel und das SMTP-Passwort gehören in die
EnvironmentFile mit restriktiven Rechten, nicht in die Unit selbst.
Beispiel: nginx als Reverse Proxy
Abschnitt betitelt „Beispiel: nginx als Reverse Proxy“server { listen 443 ssl; server_name dns.example.com;
ssl_certificate /etc/ssl/dns.example.com.pem; ssl_certificate_key /etc/ssl/dns.example.com.key;
location / { proxy_pass http://127.0.0.1:8422; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; }}Dazu passend auf der Instanz:
DNSE_SECURE_COOKIES=onDNSE_TRUSTED_PROXIES=127.0.0.1DNSE_INSTANCE_URL=https://dns.example.comDNSE_TRUSTED_PROXIES nennt die Adresse, von der aus der Proxy die
Anfragen weiterreicht — nur deren X-Forwarded-For wird geglaubt. Ohne diese
Angabe würde DynDNS die Proxy-Adresse statt der Router-IP eintragen.
Ein Hinweis zur Wirkung: Gilt eine Quelle als Proxy, zählt nur noch der
Header. Ein Router, der ohne X-Forwarded-For direkt auf den Port geht,
bekommt dann 911 statt eines Updates. Die Liste also eng halten und nicht
auf 0.0.0.0/0 stellen.
Wenn der Proxy seinen Upstream per HTTPS anspricht
Abschnitt betitelt „Wenn der Proxy seinen Upstream per HTTPS anspricht“Normalfall ist der obige: TLS endet im Proxy, dahinter läuft Klartext.
Manche Proxys sind aber grundsätzlich auf proxy_pass https://…
konfiguriert (oft zusammen mit proxy_ssl_verify off). Dann muss der
Dienst selbst ein Zertifikat halten — sonst antwortet er auf den
TLS-Handshake mit einem HTTP-400 und der Proxy meldet 502:
DNSE_TLS_CERT=/etc/dnseditor/tls/cert.pemDNSE_TLS_KEY=/etc/dnseditor/tls/key.pemBeide gehören zusammen — ist nur eines gesetzt, startet der Dienst nicht (stillschweigend Klartext zu sprechen, wo TLS gemeint war, wäre die gefährlichere Antwort). Prüft der Proxy das Zertifikat nicht, genügt ein selbstsigniertes:
openssl req -x509 -newkey rsa:2048 -nodes -days 3650 -keyout key.pem -out cert.pem -subj "/CN=dns.example.com"Der Schlüssel gehört der Dienstgruppe und bleibt bei 0640.
Sicherheitskopf der Oberfläche
Abschnitt betitelt „Sicherheitskopf der Oberfläche“Die Oberfläche liefert eine Content-Security-Policy aus, die Skripte auf
die eigene Herkunft beschränkt. Das ist kein Beiwerk: Seit die Anmeldung als
Token im Browser-Speicher liegt (statt in einem HttpOnly-Cookie), könnte
eingeschleustes JavaScript sie lesen. Die Richtlinie verhindert, dass fremdes
Skript überhaupt zur Ausführung kommt.
Praktische Folge für den Betrieb: Ein Proxy, der eigene Skripte einfügt — Analytics, Consent-Banner, Fehler-Tracker — wird vom Browser blockiert. Wer so etwas braucht, muss den Header im Proxy bewusst ersetzen und weiß dann, welchen Schutz er dafür aufgibt.
Stile dürfen inline sein (die Komponenten setzen sie zur Laufzeit), Skripte ausdrücklich nicht — genau dort liegt die Gefahr.