Files
Homelab--Bratonein-Kontroll…/Kapitel 3/Free Rohtext.md

21 KiB
Raw Blame History

Kapitel 3 Nginx Proxy Manager

##Einleitung Im Heimnetz rufen wir unsere Container über ihre internen IP-Adressen auf einfach, solange wir im gleichen Netzwerk sind.
Sobald wir aber einen Dienst aus dem Internet erreichbar machen wollen, stoßen wir auf ein zentrales Problem:
Unser Router besitzt nach außen nur eine öffentliche IP-Adresse, die vom Internetanbieter zugeteilt wird.

Domain und DNS

Eine Domain (z. B. meinedomain.de) ist nichts anderes als ein Name, der in eine IP-Adresse aufgelöst wird.
Diesen Übersetzungsdienst übernimmt das Domain Name System (DNS).
Ruft jemand deine Domain auf, fragt DNS im Hintergrund nach, welche IP dahintersteckt, und stellt die Verbindung her.

Dynamische IP

Bei Privatanschlüssen vergeben die Provider in den allermeisten Fällen dynamische IP-Adressen.
Das heißt: deine öffentliche IP ändert sich regelmäßig manchmal einmal am Tag, manchmal bei jeder Router-Neuverbindung.
Ohne zusätzliche Technik müsstest du jedes Mal, wenn sich die IP ändert, den DNS-Eintrag deiner Domain von Hand aktualisieren.
Das ist nicht nur zeitaufwendig, sondern kann auch zu längeren Ausfällen führen, wenn die Domain auf eine alte, falsche IP zeigt.

DynDNS

Hier setzt Dynamic DNS (DynDNS) an.
DynDNS-Anbieter bieten dir eine einfache Möglichkeit, deine aktuelle IP automatisch in DNS einzutragen:

  • Ein kleiner Client im Router oder auf deinem Server meldet die aktuelle IP an den DynDNS-Dienst.
  • Dieser aktualisiert sofort den hinterlegten DNS-Eintrag.
  • Damit bleibt dein Domainname immer aktuell erreichbar, auch wenn sich deine IP-Adresse ändert.

Note

Domain und DynDNS sind nicht dasselbe.

  • Eine Domain ist der Name, der über DNS in eine IP-Adresse übersetzt wird.
  • DynDNS ist ein Mechanismus, um diese Übersetzung automatisch aktuell zu halten, wenn sich deine IP ändert.
    Am professionellsten ist die Kombination: eine eigene Domain, deren Einträge per DynDNS-Dienst regelmäßig aktualisiert werden.

Praktisches Beispiel: Nextcloud, Pi-hole Dashboard und NPM

Nehmen wir drei Container, die wir von außen erreichen wollen:

  • die Nextcloud (Dateizugriff von unterwegs),
  • das Pi-hole Dashboard (nur Verwaltung, nicht der eigentliche DNS-Dienst),
  • und die Weboberfläche des Nginx Proxy Manager selbst.

Ohne NPM müssten wir für jeden Dienst einen Port am Router freigeben:

  • meineip:8080 → Nextcloud
  • meineip:8443 → Pi-hole Dashboard
  • meineip:9000 → NPM Web-UI

Das ist unübersichtlich, schwer zu merken und öffnet mehrere Angriffsflächen.

Mit NPM sieht es professionell und sicher aus:

  • cloud.meinedomain.de → Nextcloud
  • dns.meinedomain.de → Pi-hole Dashboard
  • proxy.meinedomain.de → NPM Web-UI

Alle Anfragen laufen durch eine einzige Adresse (deine Domain) und werden vom Proxy an den richtigen Container verteilt.
Von außen sind nur Port 80 und 443 sichtbar, alle internen Dienste bleiben geschützt.

👉 Schaubild einfügen: Vergleich „ohne NPM“ (mehrere Ports, Chaos) vs. „mit NPM“ (eine Adresse, klare Subdomains).

Tip

Dieses Beispiel zeigt: Ein Reverse Proxy ist wie ein Wegweiser.
Ohne ihn endet alles in Port-Chaos, mit ihm hast du klare Adressen und eine verschlüsselte, zentrale Stelle für deine Dienste.


Voraussetzungen

Für den Nginx Proxy Manager benötigen wir einen eigenen LXC-Container in Proxmox.
Dieser Container bildet die Basis, auf der wir den Proxy später installieren und betreiben.

Anforderungen an den Container

  • Betriebssystem: Debian 12
    Debian ist schlank, stabil und für Serverdienste wie NPM bestens geeignet.
  • Ressourcen:
    • 2 CPU-Kerne
    • 2 GB RAM
    • 816 GB Speicherplatz (je nach Anzahl der später verwalteten Dienste)
  • Netzwerk: Eine feste IPv4-Adresse im Heimnetz (z. B. 192.168.1.6).
    Diese Adresse wird später im Router für die Weiterleitung von Port 80 und 443 benötigt.
  • Internetverbindung: Notwendig für Paketdownloads und das Einrichten von SSL-Zertifikaten.

Hinweis bei Problemen

Falls du unsicher bist, wie ein LXC-Container in Proxmox erstellt wird, sieh dir bitte noch einmal Kapitel 1 an.
Dort haben wir den Prozess ausführlich beschrieben von der Auswahl des Templates über die Konfiguration bis hin zum ersten Zugriff.

Tip

Wähle für die IP-Adresse einen Bereich außerhalb des DHCP-Pools deines Routers.
Damit stellst du sicher, dass es später keine Konflikte mit automatisch vergebenen Adressen gibt.

👉 Screenshot geeignet: Proxmox-Dialog „Neuen LXC erstellen“ (Allgemeine Einstellungen).


Schritt für Schritt Anleitung

Installation

Wir starten im bereits erstellten LXC-Container (Debian 12) und installieren den Nginx Proxy Manager als Docker-Applikation.
Alle Befehle werden direkt im Container per SSH ausgeführt.

1) System aktualisieren & Basis-Tools

apt update
apt upgrade -y

# Basis-Tools, die wir sicher benötigen:
apt install -y ca-certificates curl gnupg lsb-release

# Dummy-Zeile: ggf. fehlende Tools im Debugging nachinstallieren
# apt install -y nano wget sudo

2) Docker-Engine + Compose-Plugin installieren

Wir installieren Docker aus dem offiziellen Repository:

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  > /etc/apt/sources.list.d/docker.list

apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Tip

Prüfe die Installation mit:

docker --version
docker compose version

3) Verzeichnisse für NPM anlegen

mkdir -p /opt/npm/data
mkdir -p /opt/npm/letsencrypt

4) docker-compose.yml erstellen

Wir legen die Compose-Datei für NPM an:

nano /opt/npm/docker-compose.yml

Inhalt einfügen:

services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    ports:
      - "80:80"    # HTTP
      - "443:443"  # HTTPS
      - "81:81"    # Web-UI
    volumes:
      - /opt/npm/data:/data
      - /opt/npm/letsencrypt:/etc/letsencrypt

5) NPM starten

cd /opt/npm
docker compose up -d
docker ps

Wenn alles klappt, sollte in der Ausgabe ein Container jc21/nginx-proxy-manager mit Status Up erscheinen.
👉 Screenshot geeignet: Terminalausgabe docker ps.

6) Erste Anmeldung in der Weboberfläche

Im Browser öffnen:

http://<Container-IP>:81

Standard-Zugangsdaten:

  • E-Mail: admin@example.com
  • Passwort: changeme

Nach dem ersten Login wirst du aufgefordert, E-Mail und Passwort zu ändern.
👉 Screenshot geeignet: Login-Maske der NPM-Weboberfläche.

Router konfigurieren

Damit der Nginx Proxy Manager von außen erreichbar ist, müssen wir den Datenverkehr durch unseren Router leiten.
Der Router ist das Tor ins Internet: alle Anfragen von außen landen dort zuerst und müssen an die richtige Stelle im Heimnetz weitergeleitet werden.

Ohne diese Weiterleitungen würde niemand den Nginx Proxy Manager erreichen können.
Und noch wichtiger: Lets Encrypt könnte keine Zertifikate ausstellen, weil der Validierungsserver nicht bis zu unserem Container durchkommt.

Portweiterleitungen einrichten

Wir brauchen genau zwei Weiterleitungen:

  • Port 80 (HTTP)
    Wird für die Überprüfung und Ausstellung von Zertifikaten durch Lets Encrypt benötigt.

  • Port 443 (HTTPS)
    Wird für den verschlüsselten Zugriff auf unsere Dienste genutzt.

Beide Ports müssen auf die interne IP-Adresse des NPM-Containers zeigen.
Wenn dein Container z. B. die IP 192.168.1.6 hat, dann stellst du im Router Folgendes ein:

  • Extern: Port 80 → Intern: 192.168.1.6:80
  • Extern: Port 443 → Intern: 192.168.1.6:443

👉 Screenshot geeignet: Router-Oberfläche mit eingerichteter Portweiterleitung.

Unterschied zwischen interner und externer Adresse

  • Interne Adresse: 192.168.x.x (nur im Heimnetz sichtbar)
  • Externe Adresse: vom Provider zugeteilt, im Internet sichtbar (z. B. 87.123.45.67)

Von außen kommend sehen Besucher nur die externe Adresse oder Domain.
Der Router muss die Anfrage an die richtige interne IP weitergeben und genau dafür richten wir die Portweiterleitungen ein.

DynDNS am Beispiel DuckDNS

Eine einfache Möglichkeit, deine wechselnde IP-Adresse automatisch aktuell zu halten, ist der Dienst DuckDNS.org.
DuckDNS ist kostenlos, arbeitet zuverlässig und eignet sich ideal für Homelabs.

Anmeldung
  1. Gehe auf https://www.duckdns.org.
  2. Melde dich mit einem bestehenden Account an (z. B. GitHub oder Google).
  3. Nach dem Login kannst du dir einen eigenen Hostnamen anlegen, z. B.
    meinserver.duckdns.org
    

👉 Screenshot geeignet: DuckDNS-Dashboard mit angelegtem Hostnamen.

Funktionsweise

Der von dir gewählte Hostname wird bei DuckDNS mit deiner aktuellen öffentlichen IP-Adresse verknüpft.
Damit diese Zuordnung auch bei einer neuen IP weiter funktioniert, muss dein Router oder ein Update-Mechanismus die Daten regelmäßig an DuckDNS melden.

Wie genau das geschieht, hängt von deinem Router und deiner Technik ab.
DuckDNS zeigt dir nach der Anmeldung direkt an, wie du den Update-Mechanismus einrichten kannst entweder über eine DynDNS-Option im Router oder über ein kleines Skript.

Beispiel im Tutorial

Für unser Beispiel nutzen wir den Hostnamen pihole.duckdns.org.
Dieser zeigt immer auf unsere aktuelle öffentliche IP und kann später im Nginx Proxy Manager als Zieladresse für Subdomains verwendet werden.

Note

Auch wenn die Adresse von außen erreichbar ist, ist der eigentliche Pi-hole-Zugang mit Login geschützt.
Niemand kann ohne Passwort etwas verändern.

Tip

Im Premium-Teil zeigen wir eine komfortable Möglichkeit, DuckDNS automatisch und ohne zusätzliche Handarbeit zu aktualisieren.

Sicherheitshinweise

  • Öffne im Router wirklich nur Port 80 und 443
  • Andere Dienste im Heimnetz (z. B. Nextcloud oder Pi-hole) bleiben hinter dem Proxy geschützt
  • Der Nginx Proxy Manager wird zur zentralen Anlaufstelle
  • Sobald die Ports freigegeben sind, ist der NPM-Container von außen sichtbar deshalb unbedingt im nächsten Schritt die Zugangsdaten ändern

Warning

Jede unnötige Portfreigabe ist ein zusätzliches Risiko.
Stelle sicher, dass wirklich nur die beiden benötigten Ports (80 und 443) nach außen offen sind.

Test der Weiterleitung

Nachdem die Portfreigaben gespeichert sind:

  1. Prüfe deine aktuelle öffentliche IP-Adresse (z. B. über https://whatismyipaddress.com)
  2. Öffne im Browser http://<öffentliche-IP> du solltest eine Standard-Seite vom Nginx Proxy Manager sehen
  3. Noch besser: nutze deine Domain oder DynDNS-Adresse und öffne http://meinedomain.de

Wenn du eine Antwort bekommst, ist die Weiterleitung korrekt eingerichtet.
Wenn nicht, prüfe:

  • Stimmt die interne Ziel-IP im Router?
  • Sind die Ports 80/443 eventuell noch von einem anderen Gerät belegt?
  • Hat dein Provider evtl. CGNAT oder DS-Lite aktiv (dann sind eingehende Verbindungen eingeschränkt)?

Note

IPv6 / DS-Lite kann Probleme bereiten. Manche Internetanschlüsse verwenden DS-Lite (Dual-Stack Lite), bei dem keine öffentliche IPv4-Adresse vergeben wird, sondern du über ein IPv6-Tunneled-Netzwerk (Carrier-NAT) verbunden bist.
In so einem Fall funktioniert eine klassische Portweiterleitung auf IPv4 nicht, weil du gar keine öffentliche IPv4 hast.

Was bedeutet das für NPM?

  • Dein Reverse Proxy (NPM) mag korrekt laufen und unter IPv6 erreichbar sein, doch viele Dienste oder Clients (Smartphones, Zuschauer, etc.) verwenden nur IPv4.
  • Daher kann es sein, dass trotz funktionierendem Setup extern keine Verbindung möglich ist, wenn keine IPv4-Adresse verfügbar ist.
  • Viele berichtete Fälle zeigen, dass Dienste bei DS-Lite über IPv6 erreichbar sind, aber IPv4-Geräte außen blockiert bleiben. oai_citation:0‡Medium
  • Eine mögliche Lösung ist, ein externes Gateway oder Tunnel zu nutzen, z. B. einen Server im Internet, der IPv4 annimmt und über IPv6 zum Heimnetz bridgt (z. B. Tools wie Pangolin). oai_citation:1‡Deployn

Hinweis für Nutzer

  • Wenn dein Anbieter DS-Lite nutzt und du keine öffentliche IPv4-Adresse hast, wirst du nicht mit dem klassischen NPM-Setup ins Internet kommen.
  • In diesem Fall steht dir nur IPv6-Zugriff zur Verfügung vorausgesetzt, deine Domain und deine Geräte unterstützen IPv6.
  • Im Premium-Tutorial zeigen wir eine komfortable Tunnel- oder Relay-Lösung, damit dein System auch unter DS-Lite zuverlässig von außen erreichbar ist.

Warning

Wenn dein Anschluss DS-Lite nutzt, teste unbedingt früh, ob dein NPM über IPv4 erreichbar ist.
Sonst stehst du später vor einer Konfiguration, die intern funktioniert, aber extern nicht erreichbar ist.

Ersteinrichtung Nginx Proxy Manager

Nachdem der NPM-Container gestartet wurde und die Ports 80, 81 und 443 erreichbar sind, öffnen wir die Weboberfläche:

http://<Container-IP>:81

Beispiel:

http://192.168.1.6:81

Erster Login

Standard-Zugangsdaten:

  • E-Mail: admin@example.com
  • Passwort: changeme

Beim ersten Login wirst du sofort aufgefordert:

  • eine gültige E-Mail-Adresse einzutragen (diese wird für Zertifikate und Benachrichtigungen genutzt)
  • ein neues, sicheres Passwort zu vergeben

👉 Screenshot geeignet: Loginmaske mit Eingabe der Standarddaten.

Sprache einstellen

In den Einstellungen kannst du die Sprache auf Deutsch umstellen.
Das erleichtert die spätere Bedienung.

👉 Screenshot geeignet: Dashboard mit geöffneten Einstellungen.

Benutzerverwaltung

  • Lege dir im nächsten Schritt einen eigenen Benutzer an.
  • Verteile Admin-Zugänge nur, wenn es wirklich nötig ist.
  • Für normale Nutzer kannst du eingeschränkte Rollen vergeben (z. B. nur Zugriff auf bestimmte Hosts).

Warning

Lasse den Standard-Admin-Account nicht bestehen.
Er ist bekannt und stellt ein Sicherheitsrisiko dar auch dann, wenn du das Passwort änderst.

Überblick im Dashboard

Nach dem ersten Login siehst du das Dashboard:

  • Übersicht der eingerichteten Proxy Hosts
  • Status von Zertifikaten
  • Systeminformationen

Hier ist im Moment noch alles leer das ändern wir im nächsten Schritt, wenn wir den ersten Proxy Host einrichten.

👉 Screenshot geeignet: NPM-Dashboard direkt nach der Ersteinrichtung.

Ersten Proxy Host anlegen (Pi-hole Dashboard)

Nun richten wir den ersten Proxy Host im Nginx Proxy Manager ein.
Als Beispiel nehmen wir das Pi-hole Dashboard, das im Container unter Port 80 läuft.

1) Proxy Host hinzufügen

  1. Gehe im Dashboard auf Hosts → Proxy Hosts.
  2. Klicke auf Add Proxy Host.

👉 Screenshot geeignet: Proxy Hosts → Add Proxy Host.

2) Domainname eintragen

  • Domain Names: Gib die Adresse ein, die du im DNS/DynDNS angelegt hast, z. B.
    pihole.meinedomain.de
    

3) Ziel im Heimnetz festlegen

  • Scheme: http
  • Forward Hostname / IP: interne IP des Pi-hole Containers (z. B. 192.168.1.5/admin)
  • Forward Port: 80

Damit wird jede Anfrage an pihole.meinedomain.de automatisch direkt an die interne Adresse 192.168.1.5/admin weitergegeben.

👉 Screenshot geeignet: Eingabemaske mit Scheme, IP und Port.

4) SSL-Zertifikat aktivieren

  • Gehe zum Tab SSL
  • Wähle Request a new SSL Certificate
  • Setze die Haken bei Force SSL und HTTP/2 Support
  • Akzeptiere die Lets Encrypt Bedingungen

Beim Speichern fragt NPM automatisch ein gültiges Zertifikat an.

👉 Screenshot geeignet: SSL-Tab mit aktivierter Zertifikatsanfrage.

5) Ergebnis prüfen

  • Öffne im Browser https://pihole.meinedomain.de
  • Du solltest direkt auf das Pi-hole Dashboard weitergeleitet werden.
  • Anmeldung wie gewohnt mit deinem Pi-hole Passwort.

Tip

Da wir die interne Adresse direkt auf /admin setzen, musst du die Endung nicht mehr von Hand angeben das Dashboard öffnet sofort.

Troubleshooting & Tipps

NPM-Weboberfläche nicht erreichbar

Wenn du http://<Container-IP>:81 nicht aufrufen kannst, liegt das fast immer daran, dass der Container nicht läuft oder blockiert wird.

  • Prüfe zuerst, ob NPM läuft:
    docker ps
    
    In der Liste muss der Container jc21/nginx-proxy-manager erscheinen und den Status Up haben.
  • Falls er nicht läuft:
    docker start <container-id>
    
  • Falls er gar nicht startet: Logs prüfen mit
    docker logs -f <container-id>
    
  • Wenn er läuft, aber kein Zugriff möglich ist:
    Prüfe im Proxmox-Webinterface, ob die Container-IP korrekt im Netzwerk eingebunden ist.

👉 Screenshot geeignet: docker ps mit laufendem Container.


Kein Zertifikat von Lets Encrypt

Das häufigste Problem: Port 80 oder 443 sind nicht von außen erreichbar.

  • Prüfe die Portweiterleitung im Router. Beide Ports müssen auf die interne IP des NPM-Containers zeigen.
  • Test von außen (z. B. mit Handy im Mobilfunknetz):
    curl -I http://meinedomain.de
    
    Wenn du keine Antwort bekommst, ist die Portweiterleitung falsch oder blockiert.
  • Prüfe, ob deine Domain/DynDNS auf die richtige IP zeigt:
    nslookup meinedomain.de
    
    Stimmt die Ausgabe mit deiner öffentlichen IP überein (z. B. 87.x.x.x)?
  • Wenn ja, liegt das Problem eher am Router oder Provider.
  • Falls du DS-Lite hast, bekommst du keine echte öffentliche IPv4 dann schlägt die Validierung fehl. Lösungsmöglichkeiten erklären wir später im Premium-Bereich.

Zugriff klappt nur intern

Du kannst http://192.168.1.6:81 aufrufen, aber nicht http://meinedomain.de?
Dann kommt die Anfrage nicht bis in dein Heimnetz. Typische Ursachen:

  • Domain zeigt noch auf alte IP (DynDNS-Update prüfen).
  • Router hat Portfreigaben nicht korrekt gespeichert.
  • Manche Provider blockieren Port 80.
    In diesem Fall: versuche, Port 80 temporär auf einen anderen Dienst umzuleiten, um zu testen, ob überhaupt etwas von außen ankommt.

SSL funktioniert, aber Browser warnt

Manchmal stellt NPM zwar ein Zertifikat aus, aber der Browser meldet trotzdem „unsicher“.

  • Stelle sicher, dass du die Seite wirklich mit https:// aufrufst.
  • Leere den Browser-Cache oder probiere ein anderes Gerät.
  • In NPM unter Proxy Host → SSL: aktiviere „Force SSL“.
    Dann wird jede Anfrage automatisch auf HTTPS umgeleitet.

Pi-hole Dashboard nicht erreichbar

Wenn du nur die Subdomain pihole.meinedomain.de eingetragen hast, landest du auf einer leeren Seite.
Pi-hole erwartet den Aufruf unter /admin.

  • Lösung: In NPM beim Forward Hostname die Adresse mit /admin hinterlegen, z. B. 192.168.1.5/admin.
  • Test direkt im Browser:
    http://192.168.1.5/admin
    

Bekannte Einschränkungen

  • IPv6: Manche Router unterstützen Portweiterleitungen nur für IPv4. Dann musst du IPv6 im Heimnetz deaktivieren oder ausschließlich IPv4 nutzen.
  • DS-Lite: Wenn du keine öffentliche IPv4-Adresse hast, kannst du von außen nicht direkt auf NPM zugreifen.
    Lösungsmöglichkeiten (z. B. Tunnel oder externe Server) behandeln wir im Premium-Teil.

Tip

Wenn du nicht weiterkommst, wirf einen Blick in die Logs des NPM-Containers:

docker logs -f <container-id>

Oft steht dort direkt, warum ein Zertifikat fehlschlägt oder ein Proxy Host nicht erreichbar ist.

Ergebnis

Mit dem Nginx Proxy Manager haben wir einen zentralen Reverse Proxy eingerichtet.
Er steht nun als Schaltzentrale zwischen unserem Heimnetz und dem Internet und übernimmt folgende Aufgaben:

  • Zentrale Verwaltung: Alle Anfragen von außen laufen über NPM.
  • Saubere Struktur: Dienste werden nicht mehr über Ports wie :8080 oder :8443 erreicht, sondern über klare Subdomains (cloud.meinedomain.de, pihole.meinedomain.de).
  • Sicherheit: Nur die Ports 80 und 443 sind nach außen offen. Alle internen Dienste bleiben hinter NPM geschützt.
  • Verschlüsselung: Lets Encrypt sorgt für automatische HTTPS-Zertifikate.
  • Komfort: Neue Proxy Hosts lassen sich einfach über die Weboberfläche hinzufügen.

Damit haben wir die Grundlage geschaffen, alle weiteren Container im Homelab sicher und professionell nach außen erreichbar zu machen.

👉 Screenshot geeignet: NPM-Dashboard mit erstem eingerichteten Proxy Host.

Tip

Ab diesem Punkt musst du für neue Dienste nur noch im NPM einen Proxy Host anlegen.
Jeder weitere Container wird so nahtlos eingebunden sicher, verschlüsselt und mit klarer Adresse.