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. 15 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.9.6
gefunden08.12.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. Sollte der Internetprovider die ├Âfftenliche IP-Adresse regelm├Ąssig ├Ąndern, siehe: free DynDNS Service - Zugriff bei wechselnder ├Âffentlicher IP.

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:??????"
    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 Basic-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)

(Basic-Authentication: Bevor das Dashboard aufgerufen werden kann, muss der hinterlegte Benutzername und das Passwort eingegeben werden)

Die folgende Zeile legt eine Middleware mit Namen: webserver-basic-auth an und definiert damit den Benutzernamen und das Passwort:
      - "traefik.http.middlewares.webserver-basic-auth.basicauth.users=admin:md5Passwort" 

Das Kennwort kann, wie bereits beschrieben mit einem Linux-Befehl in einen md5-Hash umgewandelt werden:
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g

Damit der Router, hier mit Namen "webserver" die angelegte Middleware verwendet, habe ich folgende Zeile hinzugefügt:

      - "traefik.http.routers.webserver.middlewares=webserver-basic-auth"

    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-basic-auth.basicauth.users=admin:md5Passwort" 
      - "traefik.http.routers.webserver.middlewares=webserver-basic-auth"

­čôó Hier wird voraussichtlich am 13.02.2023 ein neuer Beitrag verlinkt werden: Traefik Google-Authentifizierung Push-Nachrichten erlauben?

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_???2www"
      - "traefik.http.middlewares.redirect_???2www.redirectregex.regex=^https://(dev.|dev2.)?domain.tld(.*)"
      - "traefik.http.middlewares.redirect_???2www.redirectregex.replacement=https://www.domain.tld$${2}"
      - "traefik.http.middlewares.redirect_???2www.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: 12.01.2023 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...

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