Die Traefik-Labels im Einzelnen, samt der Dollarfalle

Management Summary
Traefik dient als Eingang für Webanwendungen: Anfragen gelangen zum passenden Dienst und können eine Anmeldung erfordern. In Docker-Installationen beschreiben kleine Konfigurationsangaben die Wege und Schutzregeln. Der Beitrag erklärt das Zusammenspiel und warum ein Passwort unbrauchbar werden kann, wenn ein anderes Werkzeug enthaltene Dollarzeichen bei der Einrichtung umdeutet. Das Verständnis von Weiterleitung und Zugangsschutz hilft, ungeschützte alternative Zugänge zu Anwendungen zu vermeiden.
Inhalt
Docker-Labels beschreiben bei Traefik mehrere miteinander verknüpfte Objekte. Ein HTTP-Router wählt Anfragen anhand einer Regel aus, ein Service bestimmt das Ziel, und Middleware verarbeitet Anfragen oder Antworten. Verweise verbinden diese Objekte; gleiche Namen allein erzeugen keine Bindung.
Für die Fehlersuche sind drei Ebenen zu trennen: die Compose-Datei vor der Ersetzung, die tatsächlich gespeicherten Container-Labels und die daraus erzeugte Traefik-Konfiguration. Fehler können bereits beim Einlesen entstehen; nicht jeder Tippfehler bleibt unbemerkt.

Router, Service und Middleware ausdrücklich verbinden
Dieser Ausschnitt gehört unter einen Anwendungsservice in Compose. Voraussetzung sind ein eingerichteter Docker-Provider, der EntryPoint websecure, der Resolver le und ein tatsächlich unter proxy vorhandenes gemeinsames Docker-Netz. Der Docker-Provider liest Routing-Einstellungen aus Container-Labels. Ein EntryPoint legt fest, wo Traefik Verbindungen annimmt; der Zertifikatsresolver beschafft TLS-Zertifikate. Die Anwendung muss auf dem internen Port 8080 erreichbar sein. Die Benutzerdatei muss im Traefik-Container unter dem angegebenen Pfad lesbar eingebunden sein; der Ausschnitt allein ist keine vollständige Installation.
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
- "traefik.http.routers.blog.entrypoints=websecure"
- "traefik.http.routers.blog.tls=true"
- "traefik.http.routers.blog.tls.certresolver=le"
- "traefik.http.routers.blog.service=blog-service"
- "traefik.http.routers.blog.middlewares=blog-auth@docker"
- "traefik.http.middlewares.blog-auth.basicauth.usersfile=/etc/traefik/auth/blog.htpasswd"
- "traefik.http.services.blog-service.loadbalancer.server.port=8080"blog, blog-service und blog-auth sind bewusst unterschiedliche Namen. router.service und router.middlewares stellen die Verweise her. Ein Tippfehler im frei gewählten Objektnamen kann ein anderes Objekt deklarieren; ein Tippfehler in einem festgelegten Feld wie loadbalancer kann dagegen einen Dekodierungsfehler erzeugen.
Ohne ausdrücklichen Service-Verweis kann der Docker-Provider einen einzigen definierten Service automatisch zuordnen oder einen Service erzeugen. Mehrere Services machen diese automatische Auswahl mehrdeutig. Ein abweichender Servicename kann deshalb im Ein-Service-Fall unauffällig bleiben, obwohl ein späterer ausdrücklicher Verweis scheitert. Namen sollten innerhalb des Providers konfliktfrei sein, auch über Compose-Projekte hinweg.
Ohne expliziten Zielport nutzt die dokumentierte Docker-Porterkennung den einzelnen beziehungsweise niedrigsten exponierten Port. Das ist kein automatisch gefundener Hostport und keine Prüfung, ob dort die gewünschte Anwendung lauscht. Ein ausdrücklicher interner Port macht die Absicht sichtbar.
Provider-Namen und tatsächlicher Schutz
Ein Middleware-Name ohne Provider-Zusatz wird im Provider des Routers aufgelöst. blog-auth@docker nennt diesen Namensraum ausdrücklich; blog-auth@file verweist auf eine Middleware aus dem aktivierten File-Provider. Ein fehlendes referenziertes Objekt verhindert den Aufbau der betreffenden Route. Das ist aber keine allgemeine Sicherheitsgarantie für den Hostnamen: Ein anderer passender Router kann weiterhin Anfragen annehmen.
Eine deklarierte Middleware schützt nicht automatisch jeden Zugang zum Service. Routerketten und gegebenenfalls EntryPoint-Standard-Middlewares bestimmen die wirksame Kette. Daher bedeutet eine leere Middleware-Liste des Routers nicht zwingend fehlenden Schutz; umgekehrt können ein weiterer Hostname, anderer EntryPoint oder direkt veröffentlichter Backend-Port die erwartete Absicherung umgehen. BasicAuth benötigt HTTPS, damit Zugangsdaten auf dem Transportweg geschützt sind.
Was Compose mit Dollarzeichen tatsächlich macht
Bei der Variablenersetzung tritt der eingestellte Wert an die Stelle des Variablennamens. Dieser Vorgang heißt Interpolation. Compose ersetzt gültige Variablenausdrücke wie $NAME und ${NAME}. Ein einfacher Variablenname beginnt mit Buchstabe oder Unterstrich. Die bcrypt-Präfixe $2y und $05 werden deshalb nicht als solche Variablen entfernt. Ein folgender Hashteil wie $e6zX... kann jedoch als Variablenanfang erkannt werden; eine nicht gesetzte Variable ergibt gewöhnlich eine Warnung und einen leeren Ersatz. Die ursprüngliche Hashzeichenfolge ist danach nicht mehr zuverlässig erhalten.
Für einen direkt in einem interpolierten Compose-Label stehenden Hash empfiehlt Traefik deshalb, jedes $ als $$ zu schreiben. Die folgende Bash-Zeile fragt das Passwort interaktiv ab und verdoppelt die Dollarzeichen der erzeugten Benutzerzeile:
set -o pipefail
htpasswd -nB admin | sed 's/\$/$$/g'Die Ausgabe gehört als vollständige Benutzerzeile hinter basicauth.users=, falls diese Variante statt usersfile verwendet wird. Auslassungspunkte in erklärenden Hashfragmenten sind kein gültiger Ersatz für den vollständigen Hash. Ein Passwort als htpasswd -b-Argument kann in Prozesslisten oder Shell-Historie auftauchen; die interaktive Variante vermeidet dieses Argument.
Die Verdopplung gilt für die Compose-Verarbeitung, nicht für Traefik selbst. Eine unverändert eingebundene Benutzerdatei und eine direkt gelesene dynamische Traefik-Datei enthalten einfache Dollarzeichen. Bei Befehlszeilen muss zusätzlich die jeweilige Shell berücksichtigt werden; in einer POSIX-Shell schützen einfache Anführungszeichen einen wörtlichen Hash vor Variablenersetzung. Auch .env-Dateien besitzen eigene Zitierregeln. Ein Wechsel des Ablageorts erfordert deshalb eine erneute Prüfung.
Diagnose ohne feste Statuscode-Zusagen
| Befund | Geeignete Prüfung |
|---|---|
| Service oder Middleware fehlt | Providername, Verweis und Routerfehler prüfen. Ohne andere passende Route ist 404 typisch; andere Router oder vorgeschaltete Systeme können anders antworten. |
| Hash verändert oder ungültig | Compose-Warnungen, wirksamen Wert und Authentifizierungsfehler prüfen. 401 ist möglich, aber kein eindeutiger Beweis für Interpolation. |
| Backend nicht erreichbar | Netz, interne IP, Port, Listener und Zeitüberschreitungen prüfen. 502/504 sind typische Hinweise, keine vollständige Ursachenbestimmung. |
| Container nicht freigegeben | Bei exposedByDefault=false sind traefik.enable=true und weitere Providerbedingungen zu prüfen. |
| Gleicher Objektname mit abweichenden Definitionen | Providerweite Namenskonflikte und Logs untersuchen; automatische Projektnamen von Compose lösen Label-Namenskonflikte nicht zuverlässig. |
docker compose config zeigt die aufgelöste Compose-Konfiguration, startet aber keine Container. docker inspect zeigt gespeicherte Labels und Netze eines vorhandenen Containers. Ein Vergleich muss den vollständigen Hash prüfen, nicht nur dessen Länge; beide Ausgaben können sensible Werte enthalten. Anschließend zeigen Traefik-Logs und die wirksamen Router-/Serviceobjekte, was tatsächlich übernommen wurde. Eine Dashboard-Ansicht ersetzt keinen Test der Anmeldung und aller Zugangswege.
Fragen und Antworten
Ist usersFile die gleiche Datei im Anwendungscontainer?
Nein. Traefik liest die Datei aus der eigenen Laufzeitumgebung. Eine Einbindung nur in die Anwendung genügt nicht. Leserechte und schreibgeschützte Einbindung sind zu prüfen. Werden users und usersFile kombiniert, werden beide Listen zusammengeführt; der Vorrang bei gleichen Namen ist anhand der eingesetzten Traefik-Version zu prüfen.
Welchen Netzwerknamen erwartet das Label?
traefik.docker.network erwartet den tatsächlichen Docker-Netznamen. Compose kann einen Projektnamen voranstellen; ein ausdrücklich gesetztes name oder externes Netz kann davon abweichen. Das Label verbindet keine Container mit dem Netz, sondern wählt aus vorhandenen Netzen.
Wie lässt sich das Dashboard sinnvoll nutzen?
Über einen geschützten, kontrolliert erreichbaren Zugang mit passender Authentifizierung und TLS. Ein öffentlich erreichbares api.insecure ist keine geeignete Abkürzung. Fehlende Route, falsche Authentifizierung und Backendfehler werden jeweils anhand von Konfiguration, Logs und gezielten Anfragen geprüft.
Quellen
- Docker: Variablenersetzung in Compose
- Traefik: Docker-Labels für Routing
- Traefik: BasicAuth
- Traefik: Standard-Middleware für EntryPoints
- Apache HTTP Server: htpasswd
- Traefik: Docker-Provider
- Traefik: API und Dashboard
- Traefik: Quellcode der Provider-Konfiguration
- Docker: Umgebungsvariablen einsetzen
- Traefik: Dokumentation