SSL Zertifikate für dein Homelab! | Nginx Proxy Manager | Homelab #002

SSL Zertifikate für dein Homelab! | Nginx Proxy Manager | Homelab #002

Übersicht

Wir schauen uns heute an, wie wir Nginx Proxy Manager als Docker Container aufsetzen, unsere Webservices im Homelab kinderleicht mit SSL Zertifikate ausstatten können und mein persönliches Highlight, wie wir Docker Container ohne das exposen von zusätzlichen Ports sicher per https erreichen können.

Video zum Beitrag: https://youtu.be/vI6XpmGS_Ec


Docker Installation

Da wir den Nginx Proxy Manager als Docker-Container laufen lassen wollen, müssen wir als erstes Docker installieren. Das geht am schnellsten mit dem offiziellen convenience script

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh
install docker
docker install

Wenn das Skript durchgelaufen ist sollte Docker und Docker Compose erfolgreich auf dem System installiert sein.


Nginx Proxy Manager Compose

Um Nginx als Container zu starten, erstellen wir uns eine passende Docker Compose Datei mit den gewünschten Einstellungen die wir brauchen.

services:
  app:
    image: jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    container_name: nginx-proxy-manager
    ports:
      # These ports are in format <host-port>:<container-port>
      - 80:80 # Public HTTP Port
      - 443:443 # Public HTTPS Port
      - 81:81 # Admin Web Port 
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:
      - /opt/nginx/data:/data
      - /opt/nginx/letsencrypt:/etc/letsencrypt
networks:
  default:
    name: reverse-proxy #das Netzwerk nutzen wir später für weitere Docker hosts

Ich persönlich habe meine Container gerne alle beisammen unter /opt, erstellen wir dort also einen Ordner für Nginx.

cd /opt
sudo mkdir nginx
cd nginx

Im Ordner angekommen können wir jetzt unsere Compose Datei erstellen und fügen den Inhalt von oben ein.

sudo nano compose.yaml

Nginx Proxy Manager starten

Nachdem wir nun unser Docker Compose File erstellt haben, können wir den Container starten.

sudo docker compose up -d

Es werde jetzt alle nötigen Ressourcen geladen, anschließend startet der Container.

docker pull
nginx container

Wir können mit docker ps überprüfen, ob der Container läuft

sudo docker ps
docker ps

Nginx Setup

Port 81 von dem Container ist die Admin-Oberfläche vom Nginx Proxy Manager. Hier können wir jetzt unser erstes initiales Setup vornehmen. Dafür rufen wir die ip mit Port 81 im Browser auf.

login
nginx Login

Die default Credentials vom Nginx Proxy Manager lauten:

Email:    admin@example.com
Password: changeme

Nach dem einloggen können wir den User anpassen.

user

Anschließend müssen wir uns noch ein eigenes Passwort vergeben.

change password

Damit haben wir das initiale Setup auch schon abgeschlossen.


SSL Zertifikat via DNS Challenge

Erklärung

Um ein SSL Zertifikat von Let´s Encrypt zu erhalten, stellen wir normalerweise eine Anfrage an Let´s Encrypt für ein neues Zertifikat. Anschließend übermittel Let´s Encrypt einen Token, welcher der Webserver dann als File auf dem Server breitstellt. Zuletzt prüft Let´s Encrypt, ob das File vorhanden ist. (HTTP-01 challenge).

Let´s Encrypt

Das erfordert einen Zugriff auf Port 80 des Servers von außerhalb. Da wir in unserem Homelab aber kein Portforwarding nach draußen betreiben wollen, kommt hier die DNS Challenge in´s Spiel.

Das Anfragen eines Zertifikats per DNS Challenge ermöglicht uns, dem Server einen API Key zu hinterlegen, mit welchem die Prüfung per DNS Einträgen stattfindet. Hierbei wird ein txt Record angelegt, welcher anschließend von Let´s Encrypt überprüft wird.

API Token

Als erstes benötigen wir einen API Token von unserem Hoster, bei dem wir die gewünschte Domain Hosten. In meinem Fall handelt es sich dabei um Cloudflare.

Cloudflare hat den großen Vorteil, dass wir einen API Key nur für DNS dieser einen Domain erstellen können. Das macht es deutlich sicherer als einen Globalen API Key.

Dafür navigieren wir zu unserem Profil → API Tokens.

create token

Bei den Templates wählen wir Edit zone DNS

zone dns template

Dann können wir unsere Domain auswählen, für die der Token gedacht ist.

choose domain

Das war es auch schon auf der Seite. Im nächsten Schritt erstellen wir dann unseren Token.

get token

Nginx SSL Zertifikat

Mit dem API Token haben wir jetzt alles was wir brauchen. Zurück in der Adminoberfläche Navigieren wir jetzt zum Reiter SSL-Certificates und erstellen ein neues Let´s Encrypt Zertifikat.

new cert
new cert

Wir können uns hier nun einfach ein Wildcard Zertifikat austellen und dieses dann für alle unsere Homelab Server und Container nutzen. Da ich nicht weiß, was ich ggf. noch über die Domain konfigurieren will, erstelle ich mir ein Wildcard Zertifikat für die Subdomain *.home.juseclab.de

wildcard

Wir setzen nun den Haken bei Use a DNS Challenge und wählen unseren Hoster aus. Anschließend sehen wir schon wo wir unseren API-Token platzieren müssen.

dns challenge

Nachdem wir unseren Token eingegeben haben legen wir ebenfalls den Schalter zum Akzeptieren der Let´s Encryp Terms of Service um und klicken auf Save

dns challenge setup
dns challenge

Nach kurzem laden haben wir jetzt ein Wildcard Zertifikat für unser Homelab! Das Zertifikat erneuert Automatisch alle 3 Monate, sprich wir brauchen uns nicht weiter darum zu kümmern.

certificate
let´s encrypt cert

DNS Umschreibung

Um uns vor Man in the middel Attacken Unterwegs zu schützen, macht es ggf. sinn den DNS Eintrag für unsere Domain nicht im öffentlichen DNS von unserem Hoster zu setzen. Wir erreichen die Domain sowieso nur Zuhause. Wenn also bei euch bspw. ein AdGuard DNS vorhanden ist oder andere lokale DNS Server, könnt ihr hier einen Eintrag oder eben wie im AdGuard Fall eine Umschreibung erstellen.

Dabei gebt ihr eure Wildcard Domain an und verweist mit dieser auf eure Nginx Proxy Manager instanz.

DNS-Rewrite
dns rewrite

Homelab Services mit Zertifikat versehen

Um jetzt unsere Dienste über eine sichere und verschlüsselte https Verbindung zu erreichen ohne nervige Warnungen gehen wir wie anhand des Beispiels hier mit AdGuard aus dem vorherigen Video wie folgt vor.

  1. Navigiere zu dem Reiter Proxy Hosts und erstelle einen neuen Host
add host
add new host
  1. Gebe deinen gewünschten Domainnamen ein und trage die IP des Systems und den Port auf dem der Service erreichbar ist ein. Die Schalter unten können optional aktiviert werden (manchmal ist bspw. der Websocket Support erforderlich).
setup host
proxy host
  1. Im Reiter SSL wählen wir jetzt noch das gewünschte Zertifikat aus.
add certificate
ssl cert
  1. Speichern

Prinzipiell ist der neu erstellte Host jetzt über den neuen Namen erreichbar. Da wir allerdings Öffentlich keinen DNS Eintrag für die neue Domain hinterlegt haben, müssen wir dies entweder noch tun oder noch besser, auf unserem AdGuard Server eine neue Umschreibungsregel erstellen.


Docker Anwendungen ohne offene Ports per SSL erreichen

Kommen wir zu meinem Highlight in diesem Beitrag!

Mit dem Nginx Proxy Manager auf unserem Docker Host haben wir die Möglichkeit unsere Webservices aus den Containern ohne jegliche Ports zu deployen und sicher per https und mit gültigem SSL Zertifikat zu erreichen.

Wir haben beim erstellen des Nginx Proxy Manager Containers bereits das Docker Netzwerk reverse-proxy angelegt. Dieses Netzwerk können wir jetzt weiteren Container mit anhängen um die Ports darin freizugeben. Nach außen vom Host weg ist weiterhin nur Port 443 und Port 80 von Nginx freigegeben. Dies verhindert ein löchrigen Docker-Host mit etlichen Offenen Ports.

Als Beispiel Container nehmen wir einen simplen Webserver.

  1. Zuerst erstellen wir wieder eine passende Compose Datei für unseren neuen Container im entsprechenden Ordner (in meinem fall /opt/webcontainer).
services:
  docker-nginx-hello-world:
    #der Name ist für Nginx wichtig
    container_name: mywebserver
    # Ports fallen durch diese Methode weg
    #ports:
    #  - 8080:80
    image: dockerbogo/docker-nginx-hello-world
    #das Netzwerk muss dem Service welcher nach außen erreichbar ist angehangen werden.
    networks:
      - reverse-proxy
networks:
  reverse-proxy:
   external: true
  1. Starten des neuen Containers
sudo docker compose up -d
  1. In der Adminoberfläche vom Nginx Proxy Manager erstellen wir nun einen neuen Eintrag. Wie zuvor auch wählen wir unseren Domainnamen nach belieben aus.
domainname
domain
  1. Jetzt kommt die große Besonderheit. Im Hostname Feld geben wir jetzt einfach den Containernamen an, als Port geben wir den Port ein, den wir eigentlich nach draußen exposen würden.
hostname
container as hostname
  1. Unter dem Reiter SSL wählen wir jetzt wieder unser Wildcard aus und speichern anschließend unsere Einstellungen.
ssl cert
ssl cert

Fertig! Der Container strahlt jetzt mit keinem neuen Port nach draußen, ist aber per https erreichbar.

https new container
url per https

Sollten mehrere Services in der Compose vorhanden sein wie bspw. ein zusätzlicher Datenbank Service, so muss ebenfalls noch ein Default Netzwerk angelegt werden. Das Netzwerk gebt ihr dann allen Services die miteinander Kommunizieren müssen. Dem exposenden Service gebt ihr dann zusätzlich das reverse-proxy Netzwerk mit an die Hand.


Wir werden diesen Fall aber in zukünftigen Beiträgen noch haben.


Ergebnis

Wenn wir nun also unseren angelegten Host öffnen, erreichen wir AdGuard per https mit gültigem SSL Zertifikat! Dies ist eine wunderbare Möglichkeit eure Homelab Webservices ohne viel aufwand mit einem SSL Zertifikat zu versorgen.

success
sucess