Wer eigene Dienste im Homelab betreibt, kennt die nervige Browser-Warnung vermutlich nur zu gut: Die Verbindung sei nicht sicher, das Zertifikat sei nicht vertrauenswürdig oder der Browser empfiehlt sogar, die Seite gar nicht erst zu öffnen.

Der Grund ist meistens ein selbst signiertes Zertifikat. Die Verbindung kann damit zwar verschlüsselt sein, aber der Browser kann nicht prüfen, ob das Zertifikat wirklich vertrauenswürdig ist. Bei einem offiziell ausgestellten Zertifikat gibt es eine Vertrauenskette zu einer bekannten Zertifizierungsstelle, zum Beispiel Let’s Encrypt. Bei selbst signierten Zertifikaten fehlt diese Vertrauenskette.

Mit dem Nginx Proxy Manager lässt sich dieses Problem sehr elegant lösen. Er sitzt als Reverse Proxy zwischen Browser und internem Dienst, nimmt die HTTPS-Verbindung entgegen und präsentiert dem Browser ein gültiges Zertifikat. Intern leitet er die Anfrage dann an den eigentlichen Dienst weiter, zum Beispiel an Pi-hole, Home Assistant, Nextcloud, Portainer oder Uptime Kuma.

In dieser Anleitung zeige ich die Installation über die Proxmox Community Scripts und zusätzlich optional die Installation auf einem eigenständigen Linux-Server mit Docker. Danach richten wir Cloudflare ein, erstellen einen API Token, stellen ein Let’s-Encrypt-Zertifikat per DNS Challenge aus und weisen dieses Zertifikat einem Proxy Host zu.


Ziel der Anleitung

Am Ende soll ein interner Dienst wie Pi-hole nicht mehr über eine unschöne IP-Adresse oder mit Zertifikatswarnung aufgerufen werden, sondern sauber über eine eigene Subdomain:

TEXT
https://pihole.deinedomain.tld

Der Browser soll anschließend anzeigen:

TEXT
Verbindung ist sicher
Zertifikat ist gültig
Ausgestellt von Let’s Encrypt

Beispielwerte in dieser Anleitung

Bitte ersetze die folgenden Beispielwerte durch deine eigenen Daten:

TEXT
Domain:                deinedomain.tld
Interner Hostname:     pihole.deinedomain.tld
IP Nginx Proxy Manager: 10.10.13.49
IP Pi-hole:             10.10.13.51
Port Pi-hole:           443 oder 80

Wichtig: Der Hostname pihole.deinedomain.tld muss später im lokalen Netzwerk auf die IP-Adresse des Nginx Proxy Managers zeigen, nicht direkt auf Pi-hole.


Warum Cloudflare DNS Challenge?

Let’s Encrypt muss prüfen, ob du die Domain wirklich kontrollierst. Das geht klassisch über HTTP auf Port 80 oder über die DNS Challenge.

Für Homelab-Setups ist die DNS Challenge besonders praktisch, weil der interne Dienst nicht öffentlich erreichbar sein muss. Stattdessen erstellt Nginx Proxy Manager über die Cloudflare API kurzzeitig einen speziellen DNS-TXT-Eintrag. Let’s Encrypt prüft diesen TXT-Eintrag und stellt danach das Zertifikat aus.

Das ist ideal, wenn du deine Dienste nur intern nutzen möchtest oder keine Ports aus dem Internet auf dein Homelab freigeben willst.


Variante 1: Installation über Proxmox Community Scripts

Diese Variante ist besonders bequem, wenn du bereits Proxmox im Einsatz hast. Die Community Scripts erstellen automatisch einen LXC-Container und installieren Nginx Proxy Manager darin.

1. Proxmox Community Scripts öffnen

Öffne die Seite der Proxmox Community Scripts und suche nach:

TEXT
Nginx Proxy Manager

Dort findest du den aktuellen Installationsbefehl. Verwende immer den Befehl von der aktuellen Projektseite, weil sich Skripte und Versionen ändern können.

Zum Zeitpunkt dieser Anleitung sieht der Befehl ungefähr so aus:

BASH
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/nginxproxymanager.sh)"

2. Befehl in der Proxmox Shell ausführen

Öffne in Proxmox die Shell deines Proxmox Hosts und füge den Befehl dort ein.

BASH
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/nginxproxymanager.sh)"

Danach startet der Installationsassistent.

3. Advanced Installation auswählen

Ich empfehle die Advanced Installation, weil du dort wichtige Einstellungen selbst setzen kannst.

Empfohlene Optionen:

TEXT
Installation Mode:     Advanced
Container:             unprivileged
Hostname:              npm oder nginx-proxy-manager
Disk:                  z. B. 8 GB
CPU/RAM:               je nach Umgebung, meist reichen geringe Ressourcen
IPv4:                  statische IP-Adresse
IPv6:                  optional, wenn nicht genutzt deaktivieren
DNS Server:            dein lokaler DNS, Pi-hole, Router oder öffentlicher DNS
SSH Access:            optional aktivieren
Verbose Mode:          optional aktivieren

4. Statische IP-Adresse vergeben

Der Nginx Proxy Manager sollte eine feste IP-Adresse bekommen. Diese IP darf nicht von DHCP vergeben werden.

Beispiel:

TEXT
IP-Adresse NPM: 10.10.13.49/24
Gateway:        10.10.13.10
DNS:            10.10.13.51 oder 1.1.1.1

Wenn du nicht weißt, welche IP frei ist, kannst du von deinem PC aus testen:

BASH
ping 10.10.13.49

Kommt keine Antwort zurück, ist die IP möglicherweise frei. Besser ist es aber, im Router oder DHCP-Server direkt eine feste Reservierung oder einen freien Bereich zu prüfen.

5. Installation abschließen

Nach der Zusammenfassung bestätigst du die Installation. Der Vorgang kann einige Minuten dauern.

Nach Abschluss zeigt dir das Script die Adresse zur Weboberfläche an, normalerweise:

TEXT
http://IP-DES-NPM:81

Beispiel:

TEXT
http://10.10.13.49:81

6. Ersteinrichtung im Nginx Proxy Manager

Öffne die Weboberfläche:

TEXT
http://10.10.13.49:81

Beim ersten Start wirst du durch die Einrichtung des Admin-Kontos geführt. Verwende eine gültige oder zumindest eindeutige E-Mail-Adresse und ein starkes Passwort.

Portübersicht:

TEXT
80   = HTTP
443  = HTTPS
81   = Admin-Weboberfläche von Nginx Proxy Manager

Wichtig: Die Admin-Oberfläche auf Port 81 sollte nicht offen ins Internet gestellt werden. Zugriff am besten nur intern, per VPN oder über eine Firewall-Regel erlauben.


Variante 2: Optionale Installation auf einem eigenständigen Linux-Server

Wenn du kein Proxmox verwendest, kannst du Nginx Proxy Manager auch direkt auf einem Ubuntu- oder Debian-Server mit Docker installieren.

1. Server aktualisieren

BASH
sudo apt update
sudo apt upgrade -y
sudo reboot

Nach dem Neustart wieder per SSH verbinden.

2. Alte Docker-Pakete entfernen

BASH
sudo apt remove docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc -y

Falls nichts installiert war, ist das kein Problem.

3. Docker Repository hinzufügen

BASH
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
BASH
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
BASH
sudo apt update

4. Docker und Docker Compose Plugin installieren

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

Docker aktivieren und starten:

BASH
sudo systemctl enable --now docker

Installation testen:

BASH
sudo docker run hello-world

Optional kannst du deinen Benutzer zur Docker-Gruppe hinzufügen:

BASH
sudo usermod -aG docker $USER
newgrp docker

Danach sollte dieser Befehl ohne sudo funktionieren:

BASH
docker ps

5. Ordner für Nginx Proxy Manager erstellen

BASH
sudo mkdir -p /opt/nginx-proxy-manager
sudo chown -R $USER:$USER /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager

6. Docker Compose Datei erstellen

BASH
nano docker-compose.yml

Inhalt:

YAML
services:
  app:
    image: jc21/nginx-proxy-manager:2.15.1
    container_name: nginx-proxy-manager
    restart: unless-stopped

    ports:
      - "80:80"
      - "443:443"
      - "81:81"

    environment:
      TZ: "Europe/Vienna"

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Speichern und schließen.

7. Container starten

BASH
docker compose up -d

Status prüfen:

BASH
docker compose ps

Logs prüfen:

BASH
docker compose logs -f

Die Weboberfläche erreichst du anschließend über:

TEXT
http://SERVER-IP:81

Cloudflare: Domain registrieren oder vorhandene Domain verwenden

Für gültige Let’s-Encrypt-Zertifikate brauchst du eine echte Domain. Für reine Homelab-Zwecke reicht eine günstige Domain völlig aus.

1. Cloudflare Konto erstellen oder anmelden

Melde dich bei Cloudflare an oder erstelle ein neues Konto.

2. Domain kaufen oder übertragen

In Cloudflare kannst du entweder:

  • eine neue Domain registrieren
  • eine bestehende Domain zu Cloudflare übertragen
  • eine bestehende Domain bei deinem Registrar lassen und nur die Nameserver auf Cloudflare umstellen

Für diese Anleitung ist nur wichtig, dass Cloudflare die DNS-Zone deiner Domain verwaltet.

3. Prüfen, ob die Domain in Cloudflare aktiv ist

Die Domain sollte in Cloudflare aktiv sein und die DNS-Zone sollte sichtbar sein. Erst dann kann Cloudflare für diese Domain DNS-Einträge erstellen und bearbeiten.


Cloudflare API Token erstellen

Nginx Proxy Manager braucht Zugriff auf die Cloudflare DNS-Zone, damit er für die DNS Challenge automatisch TXT-Einträge erstellen kann.

1. API Token Menü öffnen

In Cloudflare gehst du zu:

TEXT
Profil / My Profile > API Tokens > Create Token

2. Vorlage verwenden

Wähle die Vorlage:

TEXT
Edit zone DNS

oder auf Deutsch sinngemäß:

TEXT
Zone DNS bearbeiten

3. Berechtigungen prüfen

Für die DNS Challenge werden DNS-Berechtigungen für die betreffende Zone benötigt.

Empfohlene Berechtigungen:

TEXT
Zone / DNS / Edit
Zone / Zone / Read

Bei der Vorlage „Edit zone DNS“ sind die benötigten DNS-Rechte normalerweise bereits vorausgewählt.

4. Zone einschränken

Wähle unter Zone Resources möglichst nicht alle Domains, sondern nur die konkrete Domain, für die Nginx Proxy Manager Zertifikate erstellen soll.

Beispiel:

TEXT
Include > Specific zone > deinedomain.tld

Das ist sicherer als ein Token mit Zugriff auf alle Domains im Cloudflare-Konto.

5. Token erstellen und sicher speichern

Erstelle den Token und kopiere ihn sofort in einen Passwortmanager.

Wichtig: Der Token wird nur einmal vollständig angezeigt. Wenn du ihn später nicht mehr hast, musst du einen neuen Token erstellen.


Zertifikat im Nginx Proxy Manager erstellen

Jetzt wird das Let’s-Encrypt-Zertifikat über die Cloudflare DNS Challenge erstellt.

1. SSL Certificates öffnen

Im Nginx Proxy Manager gehst du zu:

TEXT
SSL Certificates > Add SSL Certificate > Let's Encrypt

2. Domain eintragen

Für einen einzelnen Dienst trägst du zum Beispiel ein:

TEXT
pihole.deinedomain.tld

Optional kannst du auch ein Wildcard-Zertifikat erstellen:

TEXT
*.deinedomain.tld

Bei Wildcard-Zertifikaten ist die DNS Challenge besonders praktisch, weil Wildcard-Zertifikate nicht über die normale HTTP-Challenge ausgestellt werden.

3. E-Mail-Adresse eintragen

Trage eine E-Mail-Adresse ein. Diese kann für wichtige Hinweise zum Zertifikat verwendet werden.

4. DNS Challenge aktivieren

Aktiviere:

TEXT
Use a DNS Challenge

Als DNS Provider wählst du:

TEXT
Cloudflare

5. Cloudflare Token einfügen

Im Feld für die Zugangsdaten steht meist ein Platzhalter wie:

TEXT
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567

Ersetze den Platzhalter durch deinen echten Cloudflare API Token:

TEXT
dns_cloudflare_api_token = DEIN_CLOUDFLARE_API_TOKEN

6. Propagation Seconds erhöhen, falls nötig

Wenn die Zertifikatsausstellung fehlschlägt, kann es helfen, die Wartezeit für DNS-Propagation zu erhöhen.

Empfehlung:

TEXT
Propagation Seconds: 120

7. Let’s Encrypt Bedingungen akzeptieren und speichern

Aktiviere die Zustimmung zu den Let’s-Encrypt-Bedingungen und speichere.

Nach kurzer Zeit sollte das Zertifikat erstellt werden. In der Übersicht steht es zuerst eventuell als „not used“, weil es noch keinem Proxy Host zugewiesen wurde.


Proxy Host hinzufügen und Zertifikat zuweisen

Jetzt erstellen wir den eigentlichen Proxy Host, über den der interne Dienst erreichbar wird.

1. Proxy Host erstellen

Gehe zu:

TEXT
Hosts > Proxy Hosts > Add Proxy Host

2. Domain Name eintragen

TEXT
Domain Names: pihole.deinedomain.tld

3. Zielserver eintragen

Jetzt kommt ein wichtiger Punkt: Als Forward Hostname oder IP solltest du die echte interne IP-Adresse des Zielsystems eintragen, nicht den DNS-Namen.

Beispiel für Pi-hole:

TEXT
Scheme: https
Forward Hostname / IP: 10.10.13.51
Forward Port: 443

Wenn dein Dienst intern nur per HTTP läuft:

TEXT
Scheme: http
Forward Hostname / IP: 10.10.13.51
Forward Port: 80

Warum nicht pihole.deinedomain.tld als Ziel verwenden?

Weil dieser Name später lokal auf den Nginx Proxy Manager zeigen soll. Wenn Nginx Proxy Manager dann denselben Namen wieder als Ziel verwendet, kann eine Schleife entstehen. Deshalb ist die direkte interne IP-Adresse als Upstream-Ziel meistens die sauberere Lösung.

4. Wichtige Optionen aktivieren

Im Proxy-Host-Fenster kannst du je nach Dienst folgende Optionen aktivieren:

TEXT
Block Common Exploits: aktivieren
Websockets Support: bei Bedarf aktivieren

Websockets Support ist zum Beispiel bei Home Assistant, Uptime Kuma, Guacamole oder anderen Webanwendungen mit Live-Verbindungen oft sinnvoll.

5. SSL Zertifikat zuweisen

Wechsle in den Tab:

TEXT
SSL

Wähle bei SSL Certificate das zuvor erstellte Zertifikat aus.

Aktiviere:

TEXT
Force SSL
HTTP/2 Support

Force SSL sorgt dafür, dass Besucher automatisch auf HTTPS umgeleitet werden.

6. Einstellungen speichern

Klicke auf:

TEXT
Save

Der Proxy Host ist jetzt angelegt und verwendet das gültige Let’s-Encrypt-Zertifikat.


Notwendige DNS-Anpassung im lokalen Netzwerk

Damit der Host über den Nginx Proxy Manager aufgerufen wird, muss die Subdomain auf die IP-Adresse des Nginx Proxy Managers zeigen.

Beispiel:

TEXT
pihole.deinedomain.tld -> 10.10.13.49

Nicht auf Pi-hole selbst:

TEXT
pihole.deinedomain.tld -> 10.10.13.51

Der Ablauf soll so aussehen:

TEXT
Browser
  ↓
pihole.deinedomain.tld wird auf 10.10.13.49 aufgelöst
  ↓
Nginx Proxy Manager nimmt die Anfrage an
  ↓
Nginx Proxy Manager leitet intern an 10.10.13.51 weiter
  ↓
Pi-hole antwortet

Variante A: Lokalen DNS-Server verwenden

Die beste Lösung ist ein lokaler DNS-Server wie Pi-hole, AdGuard Home, Unbound, ein Router mit lokalen DNS-Einträgen oder ein interner DNS-Server.

In Pi-hole geht das zum Beispiel unter:

TEXT
Settings > Local DNS Records

Dort legst du folgenden Eintrag an:

TEXT
Domain:     pihole.deinedomain.tld
IP-Adresse: 10.10.13.49

Danach sollten alle Geräte, die Pi-hole als DNS-Server verwenden, den Hostnamen automatisch auf den Nginx Proxy Manager auflösen.

Variante B: Öffentlichen Cloudflare DNS Record verwenden

Wenn der Dienst öffentlich erreichbar sein soll, kannst du in Cloudflare einen DNS-Eintrag erstellen.

Beispiel:

TEXT
Type: A
Name: pihole
IPv4 address: öffentliche IP deines Anschlusses oder Servers
Proxy status: DNS only oder je nach Setup

Für reine interne Homelab-Dienste ist diese Variante nicht immer ideal. Häufig ist Split-DNS sauberer: Öffentlich verwaltet Cloudflare die Domain und die DNS Challenge, intern löst dein lokaler DNS-Server dieselbe Subdomain auf die private IP des Nginx Proxy Managers auf.


Notlösung: Lokale Hosts-Datei anpassen

Wenn du keinen lokalen DNS-Server hast, kannst du die Auflösung testweise über die Hosts-Datei deines Betriebssystems erzwingen.

Wichtig: Diese Methode gilt immer nur für den jeweiligen Client. Andere Geräte im Netzwerk wissen davon nichts.

Windows

Öffne den Editor als Administrator.

Datei öffnen:

TEXT
C:\Windows\System32\drivers\etc\hosts

Falls du die Datei im Dialog nicht siehst, stelle unten rechts von „Textdateien“ auf „Alle Dateien“ um.

Am Ende der Datei einfügen:

TEXT
10.10.13.49 pihole.deinedomain.tld

Speichern und DNS-Cache leeren:

CMD
ipconfig /flushdns

Danach im Browser testen:

TEXT
https://pihole.deinedomain.tld

Linux

Hosts-Datei bearbeiten:

BASH
sudo nano /etc/hosts

Eintrag hinzufügen:

TEXT
10.10.13.49 pihole.deinedomain.tld

Speichern und schließen.

DNS-Cache leeren, falls systemd-resolved verwendet wird:

BASH
sudo resolvectl flush-caches

Alternativ auf älteren Systemen:

BASH
sudo systemd-resolve --flush-caches

Danach testen:

BASH
ping pihole.deinedomain.tld

macOS

Hosts-Datei bearbeiten:

BASH
sudo nano /etc/hosts

Eintrag hinzufügen:

TEXT
10.10.13.49 pihole.deinedomain.tld

Speichern und schließen.

DNS-Cache leeren:

BASH
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

Danach im Browser testen:

TEXT
https://pihole.deinedomain.tld

Test im Browser

Rufe jetzt deinen Hostnamen auf:

TEXT
https://pihole.deinedomain.tld

Wenn alles richtig eingerichtet ist, sollte keine Zertifikatswarnung mehr erscheinen.

Im Browser kannst du auf das Schloss-Symbol klicken und das Zertifikat prüfen. Dort sollte sichtbar sein:

TEXT
Zertifikat ist gültig
Ausgestellt von Let’s Encrypt
Name: pihole.deinedomain.tld

Das Ablaufdatum ist normalerweise kein Problem, weil Nginx Proxy Manager das Zertifikat automatisch verlängert.


Häufige Fehler und Lösungen

502 Bad Gateway / openresty

Dieser Fehler bedeutet meistens, dass Nginx Proxy Manager den Zielserver nicht erreichen kann.

Prüfe:

TEXT
Stimmt die IP-Adresse des Zielsystems?
Stimmt der Port?
Stimmt das Scheme http oder https?
Läuft der Dienst wirklich?
Blockiert eine Firewall die Verbindung?

Vom Nginx Proxy Manager aus kannst du testen:

BASH
curl -I http://10.10.13.51

oder bei HTTPS:

BASH
curl -k -I https://10.10.13.51

Zertifikat kann nicht erstellt werden

Prüfe:

TEXT
Ist die Domain wirklich in Cloudflare aktiv?
Hat der API Token die richtigen Rechte?
Wurde der Token korrekt eingefügt?
Ist die DNS Challenge aktiviert?
Sind Propagation Seconds eventuell zu niedrig?

Setze testweise:

TEXT
Propagation Seconds: 120

Falls du die Proxmox Community Scripts verwendest und der Cloudflare DNS Provider oder das Certbot-Plugin fehlt, prüfe im LXC-Container, ob die Certbot-Plugins installiert sind. Je nach Script-Version kann dazu folgendes Script vorhanden sein:

BASH
/app/scripts/install-certbot-plugins

Browser zeigt weiterhin alte Zertifikatswarnung

Prüfe zuerst, ob der Hostname wirklich auf den Nginx Proxy Manager zeigt:

BASH
nslookup pihole.deinedomain.tld

oder:

BASH
dig pihole.deinedomain.tld

Die Antwort sollte die IP-Adresse des Nginx Proxy Managers liefern:

TEXT
10.10.13.49

Wenn noch die alte IP erscheint, ist die DNS-Anpassung noch nicht korrekt oder der Client verwendet einen anderen DNS-Server.


Empfehlung für ein sauberes Homelab-Setup

Für ein sauberes internes Setup empfehle ich folgende Struktur:

TEXT
Cloudflare
  verwaltet die öffentliche DNS-Zone und ermöglicht die DNS Challenge

Nginx Proxy Manager
  stellt gültige Let’s-Encrypt-Zertifikate bereit und leitet Anfragen weiter

Pi-hole oder AdGuard Home
  löst interne Hostnamen lokal auf die IP des Nginx Proxy Managers auf

Interne Dienste
  laufen weiterhin geschützt im lokalen Netzwerk

Beispiel:

TEXT
pihole.deinedomain.tld      -> 10.10.13.49
homeassistant.deinedomain.tld -> 10.10.13.49
portainer.deinedomain.tld   -> 10.10.13.49
uptime.deinedomain.tld      -> 10.10.13.49

Im Nginx Proxy Manager gibt es dann für jede Subdomain einen eigenen Proxy Host, der intern auf den jeweiligen Dienst zeigt.


Fazit

Mit Nginx Proxy Manager, Cloudflare und der DNS Challenge lassen sich gültige SSL-Zertifikate auch für interne Homelab-Dienste sehr bequem nutzen. Die nervigen Browser-Warnungen bei selbst signierten Zertifikaten verschwinden und Dienste wie Pi-hole, Home Assistant, Nextcloud oder Portainer lassen sich sauber über HTTPS und eine eigene Subdomain aufrufen.

Der wichtigste Punkt ist die DNS-Auflösung: Der Browser muss den Hostnamen auf die IP-Adresse des Nginx Proxy Managers auflösen. Der Nginx Proxy Manager selbst leitet dann im Hintergrund an den eigentlichen Dienst weiter und präsentiert dem Browser das gültige Zertifikat.

Damit ist das Homelab deutlich komfortabler, sauberer und näher an einem professionellen Setup.