Nginx-LetsEncrypt Reverse Proxy in der Praxis

 

Um auf einem Server mehrere Webservices mit entsprechenden SSL-Zertifikaten zu betreiben, bietet sich neben Traefik, das Projekt Nginx Proxy Automation an. Bei dem Setup handelt es sich um mehrere Docker-Container die zusammen einen Nginx-Reverse-Proxy inklusive Zertifikats-Verwaltung und SSL-Offloading zur VerfĂŒgung stellen. Sind die Container ĂŒber Docker-Compose einmal gestartet, kĂŒmmern diese sich um die Bereitstellung mehrerer Websites ĂŒber eine gemeinsame IP und um dessen Zertifikats-Verwaltung: fĂŒr das Ausstellen der Zertifikate fĂŒr neue Container und das Erneuern dieser fĂŒr bestehende Container: alles im laufenden Betrieb und innerhalb weniger Sekunden. Alternativ zu Nginx Proxy Automation können auch die bekannteren Reverse-Proxy Ngnix Proxy Manager oder Traefik verwendet werden.

Schematische Darstellung

Hier schematisch dargestellt, anhand der Seiten www.libe.net und www.script-example.com:

NGINX Proxy Automation horcht nach dem Starten der Container auf Port 80 und 443. Die beiden Ports mĂŒssen im Internet unter einer öffentlichen IP verfĂŒgbar sein:

Als Webserver kann ein virtueller oder Cloud-Server eines shared Hosters verwendet werden, oder der eigene PC zu Hause mit einer eingerichteten Port-Weiterleitung am Router.

D. h. wer im Besitz einer DomĂ€ne ist, kann z. B. einen A-Record der Domain oder einer Subdomain auf die öffentliche IP des Servers oder PCs zeigen lassen. Alternativ können auch Dienste wie DynDNS dazu verwendet werden. Siehe: free DynDNS Service - Zugriff bei wechselnder öffentlicher IP. Im Falle eines PCs, der zu Hause steht, kann – falls es der Provider zulĂ€sst – die öffentliche IP des Providers fĂŒr den DNS Eintrag verwendet und am Router ein Port-Forwarding des Ports 443 auf die IP des PCs erstellt werden, siehe: port-forwarding.

Installation – Nginx Let’s Encrypt Proxy

Docker Basics

Docker ermöglicht es, Services oder Applikationen per Befehl in einem sogenannten Container zu starten.
Ein Container ist eine vom Betriebssystem (OS) unabhÀngige isolierte Umgebung:
Beim ersten Start eines Containers, lÀdt Docker selbststÀndig alle notwendigen Quellen
aus dem Internet.
Docker kann unter Windows, macOS oder einer Linux-Distribution installiert werden,
siehe auch: Docker
Als Voraussetzung fĂŒr das Setup wird natĂŒrlich Docker benötigt, siehe: Docker Installation Linux oder Docker Installation Windows.

FĂŒr einen schnellen Start kann folgendes Repo geklont werden: github.com/evertramos/nginx-proxy-automation. Die aktuelle Version des Projektes ist:

SoftwareNginx-proxy-automation
GitHubhttps://github.com/evertramos/nginx-proxy-automation
aktuelle Version 0.6
gefunden30.09.2021

Konkret werden fĂŒr die Inbetriebnahme folgenden Befehle benötigt:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git 
cd /var
mkdir docker
git clone --recurse-submodules https://github.com/evertramos/nginx-proxy-automation.git webproxy 
cd webproxy/bin && ./fresh-start.sh --yes -e your_email@domain --skip-docker-image-check

Als Netzwerk fĂŒr den Proxy habe ich „webproxy“ im Wizard angegeben.

Nach dem Start können zusĂ€tzlich beliebig viele Websites gestartet werden. Der nginx-Proxy passt seine Konfiguration automatisch anhand der Eigenschaften der Container an. Damit die Webserver fĂŒr dessen Domains auch ein Zertifikat bekommen, bzw. aus dem Internet erreichbar sind, reicht es als Eigenschaften fĂŒr die Container folgende Werte zu hinterlegen:

  • -e VIRTUAL_HOST=???.domain.tld
  • -e LETSENCRYPT_HOST=???.domain.tld
  • -e LETSENCRYPT_EMAIL=admin@domain.tld
  • --network=webproxy

Die Variable „VIRTUAL_HOST“ gibt vor, auf welchen Container der Reverse-Proxy den Traffic fĂŒr diese DomĂ€ne durchstellen soll. „LETSENCRYPT_HOST“ ist der DNS-Name fĂŒr das Lets Encrypt-Zertifikat (sollte gleich „VIRTUAL_HOST“ sein) und „LETSENCRYPT_EMAIL“ die Mail-Adresse die beim Ausstellen des Zertifikats angegeben wird. Das Netzwerk „webproxy“ wurde als Backend-Netzwerkname in der zuvor heruntergeladenen Docker-Compose-Konfig verwendet. Nachdem die Domains im nginx-Proxy bekannt gemacht wurden, werden die Anfragen auf den Container ĂŒber das Netzwerk webproxy des Reverse-Proxys geleitet.

Beispiel: Start einer Website

Bevor wir die erste Website starten, muss ein A-Record im DNS hinterlegt werden, welcher auf die öffentliche IP-Adresse des Webservers zeigt. Im Anschluss kann ein einfacher Webserver mit folgenden Befehlen im Internet zur VerfĂŒgung gestellt werden, inkl. SSL-Zertifikat:

docker run -d -e VIRTUAL_HOST=???.domain.tld \
              -e LETSENCRYPT_HOST=???.domain.tld \
              -e LETSENCRYPT_EMAIL=admin@domain.tld \
              --network=webproxy \
              --name ??? \
              -v /var/www/???/httpdocs:/var/www \
              httpd:alpine

Was macht der NGINX Proxy Automation genau?

NGINX Proxy Automation verwendet die Eigenschaften anderer Container und trĂ€gt diese als Upstream-Server ein. Er fungiert als Reverse-Proxy und leitet sĂ€mtliche Anfragen weiter. FĂŒr die Weiterleitung kann Port 80 verwendet werden, fĂŒr den Zugriff auf die gehosteten Seiten 80 oder 443. FĂŒr https, Port 443 wird das SSL-Zertifikat vom Reverse-Proxy verwaltet und verlĂ€ngert: SSL-Offloading. 

Zertifikat ausstellen und verlÀngern

Die Zertifikats-Verwaltung lÀuft mit diesem Setup automatisch. Ein Blick in die Logs verrÀt, was im Hintergrund passiert: Der Container nginx-letsencrypt kontrolliert beim Start und alle 60 Minuten die Zertifikate. Sollte ein neues Zertifikat notwendig sein, wird dieses angefordert und verwendet:

nginx-letsencrypt    | /etc/nginx/certs/www.libe.net /app
nginx-letsencrypt    | Creating/renewal www.libe.net certificates... (www.libe.net)
nginx-letsencrypt    | 2021-03-14 11:09:24,871:INFO:simp_le:1414: Generating new certificate private key
nginx-web            | www.libe.net 18.196.96.172 - - [14/Mar/2021:11:09:26 +0000] "GET /.well-known/acme-challenge/??? HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
nginx-web            | www.libe.net 3.128.26.105 - - [14/Mar/2021:11:09:26 +0000] "GET /.well-known/acme-challenge/??? HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
nginx-web            | www.libe.net 34.211.6.84 - - [14/Mar/2021:11:09:26 +0000] "GET /.well-known/acme-challenge/??? HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
nginx-web            | www.libe.net 66.133.109.36 - - [14/Mar/2021:11:09:26 +0000] "GET /.well-known/acme-challenge/??? HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
nginx-letsencrypt    | 2021-03-14 11:09:29,190:INFO:simp_le:396: Saving key.pem
nginx-letsencrypt    | 2021-03-14 11:09:29,191:INFO:simp_le:396: Saving chain.pem
nginx-letsencrypt    | 2021-03-14 11:09:29,193:INFO:simp_le:396: Saving fullchain.pem
nginx-letsencrypt    | 2021-03-14 11:09:29,193:INFO:simp_le:396: Saving cert.pem

Rate-Limit: here were too many requests of a given type :: Error creating new order

Sollte zum Beispiel der DNS noch nicht auf die öffentliche IP-Adresse zeigen und der Container dennoch bereits laufen, ist etwas Geduld gefragt. Ich hatte an dieser Stelle nicht so viel Geduld und NGINX Proxy Automation mehrfach neu gestartet, woraufhin dieser bei jedem Start um ein Zertifkat angefragt hat, welches aufgrund des DNS-Eintrags aber nicht ausgestellt werden konnte. An dieser Stelle habe ich gelernt, dass pro Stunde nur 5 Anfragen fĂŒr ein neues Zertifikat erlaubt sind, in den Logs spiegelt sich das wie folgt, wider:

Attaching to nginx-letsencrypt, nginx-gen, nginx-web
...
nginx-gen            | 2021/03/14 10:09:12 Generated '/etc/nginx/conf.d/default.conf' from 12 containers
...
nginx-gen            | 2021/03/14 10:09:12 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification ''
...
nginx-letsencrypt    | Creating/renewal www.script-example.com certificates... (www.script-example.com)
nginx-letsencrypt    | 2021-03-14 10:09:19,372:INFO:simp_le:1546: Certificates already exist and renewal is not necessary, exiting with status code 1.
...
nginx-letsencrypt    | Creating/renewal www.libe.net certificates... (www.libe.net)
nginx-letsencrypt    | 2021-03-14 10:09:17,961:INFO:simp_le:1414: Generating new certificate private key
nginx-letsencrypt    | ACME server returned an error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type :: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/
...
nginx-letsencrypt    | Sleep for 3600s

Die Lösung: eine Stunde warten. NGINX Proxy Automation versucht es in der nÀchsten Stunde wieder und wenn der DNS dann passt, wird auch ein Zertifikat ausgestellt und verwendet. 

Mehrere Subdomains (SAN)

Let's Encrypt-Zertifikate können auf mehrere Subdomains ausgestellt werden, ein einfaches gĂ€ngiges Beispiel wĂ€re die Root-DomĂ€ne und die Subdomain mit einem www-Prefix: https://libe.net und https://www.libe.net. Als Beispiel können mit folgendem Docker-Aufruf Zertifikate fĂŒr beide URLs angefordert werden:

docker run -d -e VIRTUAL_HOST=www.libe.net,libe.net \
              -e LETSENCRYPT_HOST=www.libe.net,libe.net \
              -e LETSENCRYPT_EMAIL=admin@domain.tld \
              --network=webproxy \
              --name ??? \
              -v /var/www/???/httpdocs:/var/www \
              httpd:alpine

Als Voraussetzung mĂŒssen natĂŒrlich alle DNS-EintrĂ€ge der Subdomains vorhanden sein und auf den Server zeigen.

In den Eigenschaften des Zertifikats spiegeln sich zusĂ€tzliche Subdomains als „Alternativer Antragstellername“  (SAN: Subject Alternative Name) wider:

Mit diesem Setup sollte die Website auf allen Domains erreichbar sein, meist soll der Internetauftritt aber primĂ€r eine URL verwenden: z.B. „www.libe.net“. Der Aufruf ĂŒber „libe.net“ sollte dann auf „www.libe.net“ umgeleitet werden:

URLs umleiten: Nicht-www auf www

Wer mehrere Subdomains beim Starten des Containers angegeben hat (SAN), kann fĂŒr bestimmte Subdomains eine 301 Umleitung auf eine andere Subdomain erstellen.

Damit jetzt die domain.tld auf www.domain.tld umgeleitet wird, kann unter /data/vhost.d eine Datei mit dem exakten Namen der Domain (domain.tld) angelegt und innerhalb der Datei die Umleitung platziert werden:

if ($request_uri !~ "^/.well-known/acme-challenge")
{
  return 301 https://www.domain.tld$request_uri;
}

Reload nginx

Mit folgendem Befehl kann die nginx-Konfiguration neu geladen werden:

docker exec -it proxy-web-auto nginx -s reload

Logs

Details zum Ausstellen und VerlĂ€ngern der Zertifikate können ĂŒber folgendes Log angezeigt werden:

docker logs -f letsencrypt-auto

Update von Version 0.4

Ich setzte NGINX Proxy Automation bereits seit Version 0.4 ein, siehe github.com/evertramos/nginx-proxy-automation/tree/v0.4. Da sich mit Version 0.5 an den Skripts einiges geĂ€ndert hat, muss das Update laut Anleitung durchgefĂŒhrt werden, zum Beispiel auf die Version 0.6:  github.com/evertramos/nginx-proxy-automation/blob/master/docs/upgrade-guide.md. Bei dem Update ist etwas Geduld gefragt, da die Zertifikate dabei neu erstellt werden, was je nach Anzahl der Webservices die ein oder andere Minute dauern kann.

413 Request Entity too Large

Wer beim Setup die Option „Use NGINX Conf Files“ nicht ausgewĂ€hlt hat, kann dies wie folgt nachholen:

Dazu muss in der Datei „.env“ das Verarbeiten der Conf-Files folgende Zeile hinzugefĂŒgt werden:

USE_NGINX_CONF_FILES=true

Im Anschluss können im Ordner data/conf.d/ zusĂ€tzliche Konfigurations-Files hinterlegt werden, als Beispiel das Anpassen der „client_max_body_size“ um die UploadgrĂ¶ĂŸen zu erhöhen und somit den Fehler 413 Request Entity too Large zu umgehen:

Datei: /data/conf.d/uploadsize.conf

client_max_body_size 100m;

Webservices

Die beschriebene Lösung kann dann fĂŒr den Betrieb anderer Webservices verwendet werden:

Auch wenn ich die gelisteten Websites mittlerweile auf den Traefik-Reverse-Proxy umgestellt habe, könnten diese auch mit dem hier vorgestellten LetÂŽs Encrypt-nginx-proxy-companion von Evert Ramos betrieben werden. Anstelle von Umgebungsvariablen mĂŒssen dazu Labels in der Docker-Compose-Konfiguration verwendet werden.

Wer diesen Reverse Proxy anstelle von Traefik verwenden will, sollte am einfachsten die Umgebungsvariablen gegen Labels austauschen.
Hier ein Vergleich der docker-compose.yml Settings beider Proxys: NGINX Proxy Automation vs. Traefik; Environment vs. Labels:

NGINX Proxy Automation Traefik-Reverse-Proxy
version: "3"
services:
  webserver:
    image: httpd:alpine
    container_name: webserver
    environment:
      VIRTUAL_HOST: 'webserver.domain.tld'
      VIRTUAL_PORT: '80'
      LETSENCRYPT_HOST: 'webserver.domain.tld'
      LETSENCRYPT_EMAIL: 'admin@domain.tld'
    restart: always
version: "3"
services:
  webserver:
    image: httpd:alpine
    container_name: webserver
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice1.rule=Host(`webserver.domain.tld`)"      
      - "traefik.http.routers.webservice1.entrypoints=web"
      - "traefik.http.routers.webservice1.entrypoints=websecure"
      - "traefik.http.routers.webservice1.tls.certresolver=myresolver"
      - "traefik.http.services.webservice1.loadbalancer.server.port=80"
    restart: always

 

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE fĂŒr deine Bewertung!

Aktualisiert: 18.06.2023 von Bernhard | Translation English |🔔 | Kommentare:0

➚ sichere https Verbindung: Traefik Reverse Proxy + LetÂŽs Encrypt | ➊ Container | Docker Container GUI grafische WeboberflĂ€che mit Portainer ➚

Top-Artikel in diesem Bereich


Inbetriebnahme Zigbee2MQTT in Docker - Schritt fĂŒr Schritt

Zigbee2MQTT ist eine Open-Source Zigbee-Bridge welche sich, dank dem Netzwerkprotokoll MQTT, leicht in bestehende Smarthome-Lösungen integrieren lÀsst. Als Beispiel kann Zigbee2MQTT kombiniert mit MQTT - Broker  Mosquitto und Home-Assistant Daten der Zigbee-GerÀte erfassen, anzeigen, aufzeichnen und diese steuern. Das hier beschriebene Setup verwendet Docker als Basis. Herstellerseite: https://www.zigbee2mqtt.io


ioBroker installieren - Docker

Mit ioBroker können verschiedene Automatisierungslösungen oder GerÀte in einem System zusammengefasst werden. Um bestimmte Gateways oder GerÀte ansprechen zu können, werden in ioBroker verschiedene Adapter verwendet.


Bitwarden in Docker betreiben - Setup Schritt fĂŒr Schritt

Bitwarden ist ein webbasierter Passwort-Manager, Ă€hnlich LastPass, aber Open Source und der Möglichkeit diesen selbst zu betreiben (hosten). Wie sich Bitwarden im Vergleich zu anderen Passwort-Managern einordnet, habe ich auf folgender Seite ĂŒberlegt: Passwort-Manager sicher? KeePass vs. LastPass vs. Bitwarden. Bitwarden besteht aus mehreren Services, welche ĂŒber verschiedene Container bereitgestellt werden können. Das relativ aufwĂ€ndige Setup wurde mit "Bitwarden Unified" speziell fĂŒr ein Selbs...

Fragen / Kommentare


Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu Mehr Details