sichere https Verbindung: Traefik Reverse Proxy + Let´s Encrypt

This page is also available in English

Für nahezu alle bekannten Websysteme gibt es fertige Docker-Container, bzw. können diese relativ einfach selbst erstellt oder bestehende Container angepasst werden. Als Docker-Container können die Webservices sehr einfacher installiert und betrieben werden. Wer einen Webservice über das Internet veröffentlicht, sollte dafür heute unbedingt eine verschlüsselte Verbindung (SSL) anbieten. Um den Zugriff auf einen oder mehrere Container zu regeln, kann ein Reverse-Proxy mit kostenlosen Let’s Encrypt-Zertifikaten für das SSL-Offloading verwendet werden, siehe auch: eigener Webserver – wie funktioniert eigentlich das Internet?

Ziel dieses Beitrags

Der Betrieb von einem oder mehrerer Docker-Webservices (Websites) inklusive HTTPS-Verschlüsselung auf einem Server.
Die Webservices können über deren Eigenschaften (Docker-Container-Labels) veröffentlicht und über eine eigene Weboberfläche kontrolliert werden.

Aufwand

Lesedauer: ca. 13 Minuten

Voraussetzung

Ein im Internet veröffentlichter Server mit Docker und eine registrierte Webdomain

Vom NGINX Proxy zu Traefik

Ursprünglich habe ich für den Betrieb mehrerer Docker-basierter Webseiten "NGINX Proxy Automation" von Evert Ramos verwendet, siehe: nginx-LetsEncrypt Reverse Proxy in der Praxis. Das Projekt funktioniert wunderbar, hat aber im Vergleich zum alternativen Reverse-Proxy: Traefik einige Limitationen. Mit Traefik ist es gefühlt noch einfacher und dank des Web-Dashboards übersichtlicher mehrere Webseiten auf einem Server zu betreiben. Zahlreiche Middleware bieten zudem zusätzliche Funktionen.

Schematische Darstellung

Der Traefik-Docker-Container kümmert sich um das Ausstellen, Verwalten und Verwenden von SSL-Zertifikaten und leitet Webanfragen auf die jeweiligen Webservices, die wiederum auch als Docker-Container bereitgestellt werden.

Traefik kümmert sich um

      • den Zugriff auf einen oder mehrere Docker-Webanwendungen
      • die Zertifikatsverwaltung für eine HTTPS-Verschlüsselung
Hier schematisch dargestellt, anhand der Seiten www.libe.net und www.script-example.com:
Die Websites www.libe.net und www.script-example.com werden von den jeweiligen Docker-Containern betrieben. Die Verbindung vom Internet wird auf der öffentlichen IP-Adresse des Webservers vom Traefik-Container entgegengenommen. Traefik durchsucht alle Docker-Container, ob bestimmte Labels vorhanden sind und veröffentlicht diese anhand derer. Die Verwaltungsoberfläche von Traefik wird auch als Webservice zur Verfügung gestellt. Da Traefik bei Verwendung von „websecure“ als Label ein SSL-Zertifikat für den hinterlegten Host (traefik.http.routers.Webseite.rule=Host(`webdomain.tld`)) und somit für den Zugriff auf dessen Container ausstellt und verwaltet, findet die Verbindung vom Browser zur Verwaltungsoberfläche von Traefik verschlüsselt statt. Der Traefik-Container baut eine unverschlüsselte Verbindung zum Container mit dem Webservice auf, wodurch sich der veröffentlichte Webservice nicht um die Zertifikatsverwaltung kümmern müssen. Die aktuelle Version des Projektes ist:
SoftwareTraefik
GitHubhttps://github.com/traefik/traefik
aktuelle Version 2.8.8
gefunden02.10.2022

Installation: Server, Domain (DNS) und Docker

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 benötigen wir natürlich einen Server und eine Webdomain. Die Webdomain kann idealerweise vom DNS-Server des Providers verwaltet werden. Wer noch keine Domain besitzt, kann diese bei einem der unzähligen Hosting-Provider bestellen, siehe auch:
eigener Webserver – wie funktioniert eigentlich das Internet?

Für das hier vorgestellte Setup wird Docker benötigt, siehe: Docker Installation Linux oder Docker Installation Windows. Bei einem Server eines Hosting-Providers kann Docker und das hier vorgestellte Setup über eine SSH-Verbindung zum Server und über die beschriebenen Bash-Befehle erfolgen. Sollte sich der Server im eigenen Heimnetzwerk befinden, muss am Router ein entsprechendes Port-Forwarding eingerichtet werden, siehe: aus dem Internet verfügbar machen: Port-Forwarding - OpenWRT.

Wer Docker bereits installiert hat und die entsprechenden A-Records in der Domainverwaltung eingetragen hat, benötigt eine Textdatei mit Namen docker-compose.yml und als Vorlage folgenden Inhalt: 

docker-compose.yml

[+]
version: "3.3"
services:
  traefik:
    image: "traefik:v2.8"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=admin@domain.tld"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
    expose:
      # traefik dashboard port
      - 8080
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.domain.tld`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=myresolver"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:xxxxxx"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"     
    restart: "always"
volumes:
  letsencrypt:
networks:
  default:
    external:
      name: webproxy

Anpassen der docker-compose.yml-Datei

Die docker-compose-yml-Vorlage verwendet nicht nur für die veröffentlichten Web-Service-Container ein Zertifikat, sondern auch für das Traefik-Dashboard, wodurch auch der Zugriff auf das Dashboard verschlüsselt stattfindet. Damit das Dashboard nicht von jedermann aufgerufen werden kann, wurde eine Basic-Authentication mit einem Admin-User hinterlegt.
Vor dem eigentlichen Start muss die Datei natürlich ein klein wenig angepasst werden:

  • traefik.domain.tld sollte mit einer eigenen Domäne für das Traefik-Dashboard,
  • acme.email mit einer Mailadresse und
  • basicauth.users mit einem eigenen Benutzernamen und einem entsprechenden md5-Kennwort ersetzt werden. 

Anstelle von traefik.domain.tld kann für den Zugriff auf das Dashboard eine Subdomain einer vorhandenen Domain verwendet werden. Als Beispiel könnte in der DNS-Zonenverwaltung für die Domäne libe.net ein A-Record für eine Subdomain traefik.libe.net auf die IP-Adresse des Webservers erstellt werden. 

Natürlich muss in der docker-compose.yml-Datei für dieses Beispiel auch traefik.libe.net anstelle von traefik.domain.tld verwendet werden. 

Die Mailadresse wird von Let’s Encrypt verwendet, um bestimmte Informationen oder Warnungen zu versenden: Zum Beispiel, falls ein Zertifikat bald abläuft. Keine Sorge, Traefik kümmert sich um die Verlängerung der Zertifikate, entsprechend sollten E-Mails mit der Information über den Ablauf eines Zertifikats ernst genommen werden. 

Das Kennwort für die Authentifizierung kann nicht im Klartext eingetragen werden und muss daher vorab über einen Befehl als MD5-Hash erzeugt werden und für die Verwendung in docker-compose müssen einfache $ mit $$ ersetzt werden, siehe: doc.traefik.io/traefik/middlewares/http/basicauth/

In Linux kann dazu folgender Befehl verwendet werden: echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g

root@Webserver:~# echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g
New password:
Re-type new password:
admin:$$2y$$05$$7liwlteyGcPyCr2oXc4Do.G/wWxjwWLYpTWg6vvQ4pU7PLAS4ysMm

Anstelle von admin kann hier auch ein anderer Benutzername verwendet werden.

Nach dem Anpassen der Datei, können wir den Traefik-Container starten. Nachträglich gestartete Docker-Container mit den hinterlegten Labels für dessen Webservice werden im laufenden Betrieb von Traefik verarbeitet und veröffentlicht.

Start des Traefik-Containers

Als Netzwerk für Traefik und für die später erstellen Webservices verwende ich ein eigenes Netzwerk mit Namen „webproxy“, welches ich vor dem Start von Traefik (docker-compose up) erstelle:

cd /OrdnerDockerComposeFileTraefik
docker network create webproxy
docker-compose up -d

Sollte alles richtig funktionieren, kann das Traefik-Dashboard über die angegebene Domain und nach Eingabe des angegebenen Benutzers aufgerufen werden:

Websites oder Services erstellen und hosten

Wird ein anderer Docker-Container mit dem Netzwerk webproxy und entsprechenden Labels für Traefik gestartet, kann dieser über Traefik aufgerufen werden.

Wer mehrere Webservices starten will, muss darauf achten, dass unterschiedliche Labels in den jeweiligen Konfigurationen verwendet werden:
z. B. Webservice 1:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice1.rule=Host(`service1.domain.tld`)"          
      - "traefik.http.routers.webservice1.entrypoints=web"
      - "traefik.http.routers.webservice1.entrypoints=websecure"
...

und für einen weiteren Docker-Container mit einem anderen Service:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice2.rule=Host(`service2.domain.tld`)"          
      - "traefik.http.routers.webservice2.entrypoints=web"
      - "traefik.http.routers.webservice2.entrypoints=websecure"
...

„web“ als Entrypoint erlaubt den unverschlüsselten Zugriff auf den Service und „websecure“ den verschlüsselten Zugriff über HTTPS.

Siehe auch: eigener Webserver - wie funktioniert eigentlich das Internet?

Authentifizierung

Wer für einen Container eine simple Basic-Authentifizierung hinzufügen möchte, kann dies durch das Hinzufügen der Basic-Authentication-Middleware. (gleich dem Traefik-Dashboard)

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webserver.rule=Host(`domain.tld`)"      
      - "traefik.http.routers.webserver.entrypoints=web"
      - "traefik.http.routers.webserver.entrypoints=websecure"
      - "traefik.http.routers.webserver.tls.certresolver=myresolver"    
      - "traefik.http.middlewares.webserver-auth.basicauth.users=admin:md5Passwort"

Zusätzliche SAN (Subject Alternative Names)

Damit ein Webzertifikat für mehrere Subdomains ausgestellt werden kann, können sogenannte SAN verwendet werden:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice.rule=Host(`domain.tld`,`www.domain.tld`,`dev.domain.tld`,`dev2.domain.tld)"      
      - "traefik.http.routers.webservice.entrypoints=web"
      - "traefik.http.routers.webservice.entrypoints=websecure"
      - "traefik.http.routers.webservice.tls.certresolver=myresolver"     

Umleitungen 

Für das Umleiten von Subdomains auf eine andere Subdomain, können Regex-Ausdrücke verwendet werden.

Diverse Subdomains und/oder Non-WWW auf WWW umleiten

Das folgende Beispiel leitet alle Subdomains und die Root-Domain (Non-WWW) auf eine URL mit WWW um: 
domain.tld, dev.domain.tld und dev2.domain.tld werden auf www.domain.tld umgeleitet. Damit das Zertifikat auch alle Domänen-Namen enthält, müssen diese in der Host-Rule angegeben werden:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice.rule=Host(`domain.tld`,`dev.domain.tld`,`dev2.domain.tld`,`www.domain.tld`)"      
      - "traefik.http.routers.webservice.entrypoints=web"
      - "traefik.http.routers.webservice.entrypoints=websecure"
      - "traefik.http.routers.webservice.tls.certresolver=myresolver"     
      
      - "traefik.http.routers.webservice.middlewares=redirect_xxx2www"
      - "traefik.http.middlewares.redirect_xxx2www.redirectregex.regex=^https://(dev.|dev2.)?domain.tld(.*)"
      - "traefik.http.middlewares.redirect_xxx2www.redirectregex.replacement=https://www.domain.tld$${2}"
      - "traefik.http.middlewares.redirect_xxx2www.redirectregex.permanent=true"

Diverse Subdomains und/oder WWW auf Non-WWW

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice.rule=Host(`domain.tld`,`dev.domain.tld`,`dev2.domain.tld`,`www.domain.tld`)"      
      - "traefik.http.routers.webservice.entrypoints=web"
      - "traefik.http.routers.webservice.entrypoints=websecure"
      - "traefik.http.routers.webservice.tls.certresolver=myresolver"     
      
      - "traefik.http.routers.webservice.middlewares=redirect_www2none"
      - "traefik.http.middlewares.redirect_www2none.redirectregex.regex=^https://(www.|dev.|dev2.)domain.tld(.*)"
      - "traefik.http.middlewares.redirect_www2none.redirectregex.replacement=https://domain.tld$${2}"
      - "traefik.http.middlewares.redirect_www2none.redirectregex.permanent=true"

HTTP auf HTTPS umleiten (nicht global, nur für den jeweiligen Container)

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webservice.rule=Host(`domain.tld`,`dev.domain.tld`,`dev2.domain.tld`,`www.domain.tld`)"      
      - "traefik.http.routers.webservice.entrypoints=web"
      - "traefik.http.routers.webservice.entrypoints=websecure"
      - "traefik.http.routers.webservice.tls.certresolver=myresolver"     
      
      - "traefik.http.routers.webservice_http.rule=Host(`domain.tld`,`www.domain.tld`,`dev.domain.tld`)"  
      - "traefik.http.routers.webservice_http.entrypoints=web"
      - "traefik.http.routers.webservice_http.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"  

FAQ

Was ist ein Reverse-Proxy?

Ein Reverse Proxy nimmt Webanfragen entgegen und leitet diese an dahinterliegende Webservices weiter. Damit die Anfragen an den richtigen Webservice weitergeleitet werden, verwenden die meisten Reverse-Proxys den Host-Header (=Domainnamen). Ein Reverse-Proxy kann zusätzliche Funktionen für einen besseren Schutz, einen optimierten Datenverkehr oder eine zusätzliche Authentifizierung bieten. 

Wozu wird ein Reverse-Proxy verwendet?

Ein Reverse Proxy wird überwiegend für den Webzugriff auf einen oder mehrere Webserver vorgeschaltet. Neben dem Verteilen der Anfragen auf mehrere Webservices, wird ein Reverse Proxy häufig für ein sogenanntes SSL-Offloading verwendet. Der Reverse-Proxy kümmert sich dabei um das Bereitstellen der Webservices über HTTPS und übernimmt neben dem Verschlüsseln und Entschlüsseln des Datenverkehrs auch häufig das Zertifikatsmanagement. 

Was ist der Unterschied zwischen einem Reverse-Proxy und einem Load Balancer?

Die Aufgabe eines Load Balancer ist primär die Last zwischen verschiedenen Servern oder Geräten zu verteilen. Ein Reverse-Proxy kann neben einem Lastausgleich auch noch andere Funktionen wie SSL-Offloading oder Caching und wird überwiegend für Webserver (HTTP) eingesetzt. Ein Load Balancer hingegen kann auch für andere Protokolle verwendet werden. 

Webservices, Beispiele

Hier eine Liste von Webservices, die ich bisher getestet habe:

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

DANKE für deine Bewertung!

Aktualisiert: 02.10.2022 von Bernhard


Top-Artikel in diesem Bereich


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.

Home-Assistant Docker Conbee 2 und Zigbee2MQTT / deCONZ
Dank zahlreicher Integrationsmöglichkeiten ist Home-Assistant eine einfache Plattform für das Steuern verschiedenster Smart-Home Geräte. Im Vergleich zu ioBroker ist mir der Start mit Home Assistant wesentlich einfacher gefallen. Während ich für ioBroker noch am Suchen war, welches Frontend ich für meine Dashboards verwenden könnte, hatte ich mit Home-Assistant out of the box ein fertig eingerichtetes System. Die Lovelance Dashboards von Home Assistant können einfach in der GUI zusammengeklickt...

Conbee 2: Phoscon deCONZ - Docker Inbetriebnahme | Review
Mit dem kleinen USB-Stick Conbee2 habe ich meinen NAS um ein Zigbee-Gateway erweitert. Conbee2 kann auf Raspbian, Ubuntu, Docker oder Windows installiert werden.

Fragen / Kommentare


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