# Kapitel 3 – Nginx Proxy Manager (Premium) Im Free-Teil haben wir den Nginx Proxy Manager installiert, die Ports im Router freigegeben und den ersten Proxy Host eingerichtet. Damit steht eine solide Basis, um Container sicher nach außen verfügbar zu machen. Im Premium-Teil gehen wir nun deutlich weiter. Wir kümmern uns um die Themen, die im Alltag den entscheidenden Unterschied machen – für mehr Sicherheit, Komfort und Kontrolle: - **DynDNS-Updates für mehrere Anbieter gleichzeitig** Beispiel: parallele Aktualisierung bei **DuckDNS** (kostenlos, schnell eingerichtet) und **Strato** (für die eigene Domain). - **Erweiterte SSL-Konfiguration** Wildcard-Zertifikate, automatische Verlängerung und sichere Cipher-Suites. - **Access Lists & Authentifizierung** Schutz für sensible Oberflächen (z. B. Pi-hole oder NPM selbst) mit Login-Schutz. - **Advanced Nginx Config** Eigene Weiterleitungen, Header-Anpassungen und Sicherheitsregeln direkt in der Oberfläche. - **Monitoring & Logging** Mehr Überblick, um Angriffe und Fehlerquellen schnell zu erkennen. > [!NOTE] > Der Premium-Bereich baut direkt auf dem Free-Teil auf. > Du musst nichts neu installieren – wir erweitern nur die bestehenden Funktionen und holen das Maximum aus NPM heraus. ## DynDNS-Updates für mehrere Anbieter gleichzeitig Im Premium-Teil automatisieren wir die Aktualisierung unserer DynDNS-Einträge bei **DuckDNS** und **Strato** in einem Rutsch. So bleiben sowohl Test-Hostnamen (DuckDNS) als auch produktive Subdomains (Strato) zuverlässig auf der aktuellen IP – inklusive **IPv6**. Wir legen dazu ein kleines Skript an, das beide Provider nacheinander aktualisiert und die Ergebnisse protokolliert. Öffne hierzu wieder das Teminal oder Putty über WinSCP, logge dich auf den NPM ein und gibt: ```bash nano /usr/local/bin/dyndns_update.sh ``` ein. Füge folgenden Inhalt ein **(Beispieldaten – im Produktivbetrieb ersetzen!)**: ```bash #!/bin/bash # # dyndns_update.sh # - Updates für DuckDNS und Strato # - IPv4 + globale IPv6 # - Logging nach /var/log/dyndns_update.log # NOW=$(date '+%d.%m.%Y %X') LOGFILE="/var/log/dyndns_update.log" IFACE="eth0" # ggf. anpassen (z. B. ens18) # IPv4 und IPv6 ermitteln IPV4=$(curl -s https://ipv4.icanhazip.com) IPV6=$(ip -6 addr show dev "$IFACE" scope global 2>/dev/null \ | grep inet6 \ | grep -v "fd00" \ | awk '{print $2}' \ | cut -d/ -f1 \ | head -n1) echo "[$NOW] DynDNS Update gestartet – IPv4: ${IPV4:-} / IPv6: ${IPV6:-}" >> "$LOGFILE" ################################## # DuckDNS ################################## DUCKDNS_TOKEN="DEIN_DUCKDNS_TOKEN" DUCKDNS_SUBDOMAINS=("sub1" "sub2") for SUB in "${DUCKDNS_SUBDOMAINS[@]}"; do RESULT=$(curl -s "https://www.duckdns.org/update?domains=$SUB&token=$DUCKDNS_TOKEN&ip=$IPV4&ipv6=$IPV6&verbose=true") echo "[$NOW] DuckDNS: $SUB.duckdns.org → $RESULT" >> "$LOGFILE" done ################################## # Strato ################################## STRATO_DOMAIN="beispiel-domain.de" STRATO_PASS="DEIN_DYNDNS_PASSWORT" STRATO_SUBDOMAINS=("sub1" "sub2" "sub3") for SUB in "${STRATO_SUBDOMAINS[@]}"; do HOST="$SUB.$STRATO_DOMAIN" RESULT=$(curl -s --user "$STRATO_DOMAIN:$STRATO_PASS" \ "https://dyndns.strato.com/nic/update?hostname=$HOST&myip=$IPV4,$IPV6") echo "[$NOW] Strato: $HOST → $RESULT" >> "$LOGFILE" done ``` Datei speichern und ausführbar machen: ```bash chmod +x /usr/local/bin/dyndns_update.sh ``` Jetzt richten wir die Ausführung per Cron ein, damit die Einträge regelmäßig aktualisiert werden: ```bash crontab -e ``` Eintragen: ```bash */5 * * * * /usr/local/bin/dyndns_update.sh ``` > [!NOTE] > **Interface prüfen:** In LXC-Containern heißt die Netzwerkschnittstelle meist `eth0`. > Falls bei dir ein anderer Name angezeigt wird (z. B. `ens18`), passe `IFACE="eth0"` entsprechend an. > Prüfen kannst du das mit: > ```bash > ip -6 addr show > ``` > [!TIP] > **Log ansehen:** > ```bash > tail -n 50 /var/log/dyndns_update.log > ``` > Typische Rückmeldungen: > • DuckDNS: `OK` / `KO` / `NOCHANGE` > • Strato: `good ` (aktualisiert) oder `noch aktuell` (keine Änderung). > Wenn Strato `badauth` meldet, ist fast immer das **DynDNS-Passwort** im Strato-Panel nicht korrekt hinterlegt (nicht mit dem normalen Kunden-Login verwechseln). > [!TIP] > Mit diesem Ansatz veröffentlichen wir direkt die **globale IPv6 des Containers**. > Damit umgehen wir Router-seitige IPv6-Filterungen (z. B. Fritz!Box), da die Verbindung nicht am Router hängenbleibt, sondern direkt auf die Adresse des Containers zeigt. > Wichtig: Stelle sicher, dass der Container tatsächlich eine **globale IPv6** besitzt (keine `fd00::` ULA) und dass Nginx Proxy Manager auch auf IPv6 lauscht (`[::]:443`). --- ## Erweiterte SSL-Konfiguration Standard-Zertifikate in Nginx Proxy Manager (NPM) sind schnell eingerichtet. Für den dauerhaften und professionellen Betrieb empfiehlt sich die Einrichtung von **Wildcard-Zertifikaten**. Damit werden nicht nur einzelne Subdomains, sondern die gesamte Domain (`*.example.com`) mit einem Zertifikat abgesichert. Zusätzlich härten wir die HTTPS-Verbindungen mit modernen Cipher-Suites und stellen sicher, dass Zertifikate automatisch erneuert werden. ### Wildcard-Zertifikat anlegen 1. Melde dich in der NPM-Weboberfläche an. 2. Klicke links im Menü auf **SSL-Zertifikate**. 3. Oben rechts: **+ Hinzufügen**. 4. Wähle im Dialog **Let’s Encrypt**. 5. Aktiviere die Checkbox **Wildcard-Zertifikat**. 6. Trage deine Hauptdomain ein, z. B. `example.com`. 7. Wähle als Validierungsmethode **DNS Challenge**. 8. Wähle deinen Provider aus der Liste. #### Beispiel: Cloudflare (automatisch) 1. Logge dich bei [Cloudflare](https://dash.cloudflare.com/) ein. 2. Klicke auf dein Profil (oben rechts) → **Mein Profil**. 3. Gehe zu **API-Tokens**. 4. Klicke auf **API-Token erstellen**. 5. Wähle die Vorlage **Zone:DNS Edit**. 6. Setze die Berechtigungen: **Zone → DNS → Bearbeiten**. 7. Wähle die Zone (Domain), für die der Token gilt. 8. Klicke auf **Token erstellen** und kopiere den Wert. 9. In NPM → Feld **API Key** einfügen. 10. Auf **Speichern** klicken. 👉 *Screenshot geeignet: Cloudflare API-Token-Erstellung und NPM-Eingabemaske mit „DNS Challenge“.* Ab jetzt erneuert NPM das Zertifikat automatisch, ohne dass du eingreifen musst. #### Beispiel: Strato (manuell) 1. Wähle in NPM bei DNS-Provider **Strato (Manual)**. 2. Klicke auf **Speichern**. 3. NPM zeigt dir nun einen TXT-Eintrag an, der im DNS gesetzt werden muss. - Beispiel: `_acme-challenge.example.com` - Wert: zufällig generierter Token (z. B. `p8xj8HsD2sN...`) 4. Logge dich in das [Strato-Kundenportal](https://www.strato.de/) ein. 5. Gehe zu **Domainverwaltung → DNS-Einstellungen**. 6. Füge den angezeigten TXT-Eintrag hinzu. 7. Speichere die Änderungen. 8. Warte einige Minuten, bis der Eintrag weltweit verfügbar ist. 9. Gehe zurück in NPM → klicke auf **Bestätigen**. 👉 *Screenshot geeignet: NPM mit angezeigtem TXT-Record, Strato-DNS-Einstellungen mit eingetragenem TXT-Eintrag.* #### Verlängerung kontrollieren **In der NPM-Oberfläche:** 1. Öffne **SSL-Zertifikate**. 2. Suche den Eintrag für dein Wildcard-Zertifikat (z. B. `*.example.com`, Anbieter: Let’s Encrypt). 3. Prüfe in der Tabelle **Ablaufdatum** und die **Resttage**. 4. Klicke den Eintrag, um die Details zu öffnen. Bei Problemen blendet NPM oben einen Hinweis ein (z. B. fehlgeschlagene DNS-Challenge). 5. Falls nötig, löse die Verlängerung über das Aktionsmenü des Zertifikats **manuell** aus. > [!TIP] > Startet die Verlängerung nicht oder schlägt sie fehl, prüfe die **DNS-Challenge**: API-Token gültig, Berechtigungen („DNS edit“) und richtige Zone. > Bei **manuellen Providern** (z. B. Strato) musst du den von NPM angezeigten **TXT-Record** zur Erneuerung erneut setzen. **Optional – nur wenn NPM als Docker-Container läuft (auf dem NPM-LXC in der Shell):** ```bash # Container-Namen ermitteln: docker ps # Certbot-/Renew-Meldungen prüfen: docker logs 2>&1 | grep -i -E "renew|success|invalid|challenge|error" ``` > [!NOTE] > Ohne Docker-Betrieb entfallen die Log-Befehle – nutze ausschließlich die GUI unter **SSL-Zertifikate**. 👉 *Screenshot geeignet: Log-Auszug mit erfolgreicher Erneuerung.* ### Sichere Cipher-Suites aktivieren 1. Öffne im NPM-Menü **Einstellungen → SSL-Einstellungen**. 2. Entferne die Häkchen bei **TLS 1.0** und **TLS 1.1**. 3. Aktiviere nur **TLS 1.2** und **TLS 1.3**. 4. Stelle den Cipher-Suite-Level auf **Intermediate (Mozilla)**. > [!WARNING] > „Modern“ ist sicherer, aber viele ältere Clients (Smart-TVs, alte Android-Geräte) funktionieren dann nicht mehr. Referenz: [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/) 👉 *Screenshot geeignet: NPM SSL-Einstellungen mit aktivierten TLS-Versionen.* ### Ergebnis - Mit einem einzigen Zertifikat sind alle Subdomains geschützt. - Dank API-Challenge erneuert NPM das Zertifikat automatisch. - Die HTTPS-Verbindung ist nach aktuellen Standards gehärtet. Damit sparst du Verwaltungsaufwand und erhöhst die Sicherheit deines gesamten Setups. --- ## Access Lists & Authentifizierung Manche Oberflächen im UCC sollten nicht frei über das Internet erreichbar sein. Beispiele: die Admin-Oberfläche von Pi-hole, der Proxy-Manager selbst oder interne Tools. Mit Access Lists in NPM sichern wir diese Dienste zusätzlich ab. ### Neue Access List erstellen 1. Melde dich in der NPM-Oberfläche an. 2. Klicke links im Menü auf **Access Lists**. 3. Oben rechts: **+ Hinzufügen**. 4. Vergib einen eindeutigen Namen, z. B. `Pi-hole-Admin`. 5. Unter **Authorization**: - Aktiviere **Access**. - Trage einen Benutzernamen und ein starkes Passwort ein. - Klicke auf **+ Add** für weitere Nutzer. 6. Optional: Unter **Client Access** kannst du einzelne IP-Adressen oder ganze Netze erlauben oder sperren. - Beispiel: Zugriff nur aus dem Heimnetz `192.168.50.0/24` erlauben. 7. Klicke auf **Speichern**. 👉 *Screenshot geeignet: NPM-Formular „Access List hinzufügen“ mit Benutzer und Passwort.* ### Access List auf Proxy-Host anwenden 1. Gehe in der NPM-Oberfläche zu **Proxy Hosts**. 2. Bearbeite den Eintrag für den gewünschten Dienst (z. B. `pi-hole.example.com`). 3. Wechsel auf den Tab **Access List**. 4. Wähle die zuvor erstellte Liste (z. B. `Pi-hole-Admin`). 5. Speichern. Ab sofort ist die gewählte Oberfläche nur noch nach Eingabe von Benutzername und Passwort erreichbar. > [!TIP] > Es empfiehlt sich, für sensible Dienste **zwei Schichten** einzurichten: > - Einmal die interne Login-Maske des Dienstes selbst (z. B. Pi-hole oder Nextcloud). > - Zusätzlich die vorgeschaltete Authentifizierung in NPM. > Das erhöht die Sicherheit erheblich. ### Ergebnis - Ohne Login kommt niemand mehr auf die geschützte Oberfläche. - Zugriff kann zusätzlich auf bestimmte IPs eingeschränkt werden. - Angriffe von außen werden deutlich erschwert. ## Advanced Nginx Config Manche Anwendungen im UCC – wie z. B. Nextcloud – weisen im Admin-Dashboard Sicherheitswarnungen aus. Typisch ist die Meldung: *„Die Sicherheits- und Datenschutz-Header sind nicht korrekt gesetzt“.* Nginx Proxy Manager (NPM) bietet dafür keine eigene Einstellung – aber über den **Advanced-Tab** können wir solche Header selbst ergänzen. ### Problem Nextcloud meldet im Dashboard: - **Fehlender X-Frame-Options-Header** → Schutz vor Clickjacking fehlt. - **Fehlender X-Content-Type-Options-Header** → Browser könnten Dateien in falschem MIME-Typ interpretieren. - **Fehlende Referrer-Policy** → Browser geben mehr Informationen weiter als nötig. Ohne diese Header bleibt die Warnung dauerhaft sichtbar. ### Lösung Wir tragen die fehlenden Header direkt in NPM ein. So werden sie bei jeder HTTPS-Verbindung automatisch hinzugefügt. ### Umsetzung Schritt für Schritt 1. Öffne die **NPM-Weboberfläche**. 2. Gehe links auf **Proxy Hosts**. 3. Wähle deinen Nextcloud-Host (z. B. `cloud.deine-domain.de`) → **Bearbeiten**. 4. Wechsel auf den Tab **Advanced**. 5. Trage im Feld **Custom Nginx Configuration** Folgendes ein: ```nginx add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header Referrer-Policy "no-referrer-when-downgrade"; ``` 6. Klicke auf **Speichern**. 7. Starte den Proxy-Host einmal neu, falls die Änderungen nicht sofort greifen. 👉 *Screenshot geeignet: Proxy-Host „Nextcloud bearbeiten“ → Tab Advanced mit den drei Header-Zeilen.* ### Überprüfung 1. Öffne deine Nextcloud im Browser. 2. Gehe ins **Admin-Dashboard**. - Die Warnung zu den fehlenden Headern sollte verschwunden sein. 3. Alternativ: Browser-Entwicklertools (F12 → Netzwerk → Header einer Anfrage ansehen). - Dort müssen die drei neuen Header sichtbar sein: - `X-Frame-Options: SAMEORIGIN` - `X-Content-Type-Options: nosniff` - `Referrer-Policy: no-referrer-when-downgrade` 👉 *Screenshot geeignet: Nextcloud-Adminbereich ohne Warnmeldung.* ### Mehrwert - **Nextcloud zeigt keine Sicherheitswarnung mehr an.** - Schutz vor **Clickjacking-Angriffen** und fehlerhafter MIME-Interpretation. - Mehr **Datenschutz**, da Browser weniger Referrer-Daten weitergeben. - Änderungen betreffen nur diesen Proxy Host – andere Dienste bleiben unberührt. --- ## Monitoring & Logging Die Logs in Nginx Proxy Manager sind eine wertvolle Quelle, um Fehler früh zu erkennen. Im Standard (Free) musst du sie aber manuell durchsuchen – das ist unpraktisch, wenn du mehrere Dienste laufen hast. Im Premium-Teil richten wir uns deshalb ein **komfortables Monitoring** ein: Du bekommst automatisch eine tägliche Übersicht, ob alles sauber läuft oder ob Fehler aufgetreten sind. ### Problem - Logs sind in der Oberfläche zwar sichtbar, aber schnell unübersichtlich. - Zertifikats-Fehler oder nicht erreichbare Container fallen erst auf, wenn man sie zufällig entdeckt. - Ein manuelles Durchsehen kostet jeden Tag Zeit. ### Lösung Wir erstellen einen **Tagesreport**, den dein UCC automatisch für dich ablegt. Darin siehst du übersichtlich: - wie viele Anfragen erfolgreich waren, - ob Fehler aufgetreten sind (z. B. 502 = Ziel nicht erreichbar), - ob Zertifikate Probleme hatten. So erkennst du in Sekunden, ob Handlungsbedarf besteht. ### Umsetzung Schritt für Schritt 1. **Reports-Ordner anlegen** - Melde dich auf deinem NPM-LXC an. - Lege einen Ordner für die Tagesberichte an: ```bash mkdir -p /srv/ucc/reports ``` 2. **Skript für den Tagesreport erstellen** - Öffne eine neue Datei: ```bash nano /usr/local/bin/npm_logreport.sh ``` - Füge folgenden Inhalt ein: ```bash #!/bin/bash LOGDIR="/data/logs" REPORT="/srv/ucc/reports/report-$(date '+%Y-%m-%d').txt" echo "NPM Logreport - $(date '+%d.%m.%Y %H:%M')" > $REPORT echo "------------------------------------" >> $REPORT echo "Fehler 5xx: $(grep -h -E ' 5[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT echo "Fehler 4xx: $(grep -h -E ' 4[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT echo "Erfolgreich 2xx: $(grep -h -E ' 2[0-9]{2} ' $LOGDIR/*.log | wc -l)" >> $REPORT ``` - Datei speichern und ausführbar machen: ```bash chmod +x /usr/local/bin/npm_logreport.sh ``` 3. **Automatische Ausführung einrichten** - Cronjob öffnen: ```bash crontab -e ``` - Folgende Zeile eintragen, damit das Skript jeden Abend läuft: ``` 0 23 * * * /usr/local/bin/npm_logreport.sh ``` ### Überprüfung - Am nächsten Tag findest du im Ordner `/srv/ucc/reports/` eine Datei, z. B. `report-2025-10-03.txt`. - Öffne sie: ```bash cat /srv/ucc/reports/report-2025-10-03.txt ``` - Der Inhalt zeigt dir auf einen Blick die Anzahl erfolgreicher Anfragen und Fehler. 👉 *Screenshot geeignet: Beispiel-Report im Terminal mit Fehleranzahlen.* ### Mehrwert - **Kein tägliches Suchen mehr** – du hast eine fertige Übersicht. - **Schnelles Erkennen von Problemen** – 5xx-Fehler springen sofort ins Auge. - **Archiv** – du kannst zurückschauen, ob Fehler regelmäßig auftreten. So bekommst du ein schlankes, aber wirkungsvolles Monitoring direkt im UCC – ohne externe Tools oder ständiges Nachsehen in der NPM-GUI.