Dockercontainer über subdomains erreichen

Über Docker lassen sich Webservices komfortabel auf einem NAS von zu Hause aus hosten. Wenn man zusätzlich ein VPN
einrichtet, kann man auf alle selbstgehosteten Webservices komfortabel und sicher von überall auf der
Welt darauf zugreifen. Wenn man nun aber – wie ich – damit begonnen hat, intensiv auf solche selbstgehosteten
Webservices zu setzen (nur als Beispiel, gitlab, nextcloud, bitwarden, teamspeak) muss man sich mit der Zeit
einige Ports merken, um auf die Webservices zuzugreifen. Schließlich läuft jeder Webservice in einem eigenen Dockercontainer
und besitzt einen eigenen Port. Hier die Übersicht zu behalten, ist mit der Zeit unmöglich. Vielleicht weiß man beim Einrichten
noch, welchen Port man einem Webservice gegeben hat, aber nach spätestens nach 1-2 Monaten hat man den Port vergessen. Bookmarks helfen
hier zwar, aber deutlich eleganter ist es Subdomains für die Webservices einzurichten.

Um Subdomains im lokalen Netzwerk einzurichten, kann man im Prinzip jeden Webserver verwenden und konfigurieren (z.B. nginx oder apache), aber ich bin nun – besonders in der
Kombination mit Docker – auf einen komfortableren Weg gestoßen einen reverse proxy einzurichten: Traefik ist ein sogenannter Edge
Router, der genau für Services wie Docker, Docker Swarm, Kubernetes (etc.) entwickelt worden ist. Einmal eingerichtet, erkennt
Traefik automatisch alle Dockercontainer, die gerade laufen. Die Dockercontainer kann man über Labels bei der Erstellung so
einstellen, dass Traefik automatisch Subdomains dafür einrichtet. Außerdem sieht man über ein Webinterface sofort den Status der so
verfügbaren Container.

Hier eine kurze Anleitung dazu, wie man Traefik installiert, konfiguriert und anschließend einen Dockercontainer über eine
Subdomain erreichen kann. Die Anleitung setzt die vorige Installation von Docker und Kenntnis darüber voraus.
Zunächst muss das offizielle Traefik Dockerimage gepulled werden und ein Container damit angelegt werden.

docker pull traefik:latest
docker create -p 443:443 
              -p 80:80 
              -p 8080:8080
              -v /volume1/docker/traefik-config/traefik.yml:/etc/traefik/traefik.yml
              -v /var/run/docker.sock:/var/run/docker.sock
              --name traefik1 traefik:latest

Der Container ist eingerichtet, dass https und http einfach weitergeleitet werden. Falls man auf seinem Heimserver schon einen
apache oder Ähnliches laufen hat, oder man einfach nicht die Standardports verwenden will, kann man natürlich auch andere Ports verwenden.
Im yml File auf das verwiesen wird, steht die Konfiguration von Traefik. Im einfachsten Fall kann diese wie folgt lauten:

# /volume1/docker/traefik-config/traefik.yml

providers:
  docker:
    exposedByDefault: false
api:
  insecure: true

Der Pfad in den „docker create“ Parametern muss natürlich angepasst werden. Diese Konfiguration stellt sicher, dass nicht alle,
sondern nur speziell angegebene Dockercontainer über Subdomains erreichbar sind – Mir ist es lieber hier die Kontrolle zu haben,
außerdem muss man bei der Erstellung ohnehin Labels für Traefik anlegen.
Das wars auch schon mit der Konfiguration von Traefik. Natürlich kann man noch SSL Zertifikate usw. angeben, aber das wäre dann ein
Thema für einen anderen Eintrag. Traefik muss nun nur noch gestartet werden.

docker container start traefik1

Über localhost:8080 kommt man auf das Webinterface. Jetzt, wo noch keine Dockercontainer für Traefik freigegeben sind, ist dieses zwar hübsch
anzusehen, aber noch relativ leer. Um einen Container für Traefik verfügbar zu machen, muss die Erstellung eines Containers um Labels erweitert
werden.

docker create [...] \
              -l "traefik.enable=true" \
              -l "traefik.http.routers.<CONTAINER_NAME>.rule=Host(\"container.example.com\")" \
              -l "traefik.http.services.<CONTAINER_NAME>-service.loadbalancer.server.port=80" \
              [...] 

Diese 3 Labels reichen im Normalfall aus, um einen Container über eine Subdomain im lokalen Netzwerk verfügbar zu machen. Durch die angegebenen
Labels, leitet Traefik über reverse-proxy auf den Container um. Die Angabe des Port ist nicht unbedingt nötig, sollte ein Container nur
einen Port verwenden, erkennt Traefik diesen automatisch. Einige Webservices verwenden aber mehrere Ports und hier muss der Port dann explizit
angegeben werden.

Let’s encrypt Zertifikate für Hosted Websites

Bei Hosteurope gibt es die Möglichkeit Let’s encrypt Zertifikate zu verwenden, allerdings müssen diese manuell angelegt und auch (alle 3 Monate) erneuert werden. Der Vorteil bei diesen Zertifikaten ist, sie sind gratis, der Nachteil man muss die Schritte bis zum eingetragenen Zertifikat für Hosteurope manuell durchführen. Andere Hosting Provider sind hier schon weiter, ich habe leider keine Ahnung warum sich Hosteurope weigert Let’s encrypt direkt aufzunehmen, es wird wohl ums Geld gehen, da das automatisierte Anlegen und Erneuern ebenso angeboten wird, allerdings gegen Bares.

Nichts destotrotz, die Möglichkeit gibt es, manuell halt. Hosteurope hat hierzu auch eine Anleitung veröffentlicht die es Schritt für Schritt zeigt (zu finden hier). Leider ist der ZeroSSL Service ab nun für Wildcard Domains kostenpflichtig und somit für manche auch keine Alternative mehr. Also nützt es nichts, man muss sich doch mit dem Certbot auseinandersetzen.

Certbot ist ein Tool welches für Zertifikaterstellung/erneuerung der Let’s encrypt Zertifikate zuständig ist. Das Tool ist in Python geschrieben und einfach zu handhaben. Die größere Arbeit ist es, sich in die vielen Möglichkeiten und die für einem selber notwendigen Schalter dieses Python-Kommandozeilentools einzulesen.

Meine Voraussetzungen:

  • Webspace bei Hosteurope (Webhosting Basic oder Premium, somit kein Zugriff auf Webserver Konfigs o.ä.)
  • Die Domain ist entweder direkt bei Hosteurope gehostet/gekauft oder bei einem externen Anbieter (domaindiscount24)

Um für diese Anfordungen ein Zertifikat zu bekommen, muss man Zugriff auf die DNS-Konfig haben, um eben TXT Einträge erledigen zu können und man muss vom Hosting-Provider die Möglichkeit haben manuell Zertifikate hochladen zu können.

In diesem Beispiel wird ein Let’s encrypt Zertifikat für seesle.at und *.seesle.at erstellt. Die Domain und die Website liegt bei Hosteurope.

Der Aufruf bei certbot sieht wie folgt aus:

sudo certbot -d "seesle.at,*.seesle.at" --manual-public-ip-logging-ok --manual --preferred-challenges dns certonly

Dabei bedeuten die Schalter folgendes:

  • -d: Domainnamen als Liste mit , getrennt; Durch den *. in der Wildcard Domain muss man für den Befehl diesen Parameter unter „“ setzen
  • –manual-public-ip-logging-ok: Let’s encrypt verlangt, dass die IP des Rechners auf dem der Certbot ausgeführt wird mitgeloggt wird und auch öffentlich einsehbar ist, das Ganze kommt als Abfrage und bei Nein bekommt man kein Zertifikat; Mit diesem Schalter stimmt man dem explizit zu
  • –manual: bedeutet, dass die Ausführung von Certbot interaktiv (mit Abfragen und Text) in der Kommandozeile durchgeführt wird.
  • certonly: Das Zertifikat wird erstellt und lokal gespeichert aber nicht installiert; Der Grund hier ist, normalerweiße wird certbot auf dem Server auf dem der Webservice läuft ausgeführt und kann somit gleich automatisiert die Zertifikate installieren

Nach bestätigen des Befehls wird (sofern das Zertifikat noch nie erstellt wurde) eine E-Mail Adresse als Admin Adresse abgefragt. Wenn es sich um eine Erneuerung des Zertifikats handelt, dann bekommt man sofort den ersten Schlüssel den man im DNS-Eintrag ablegen muss.

Der Schlüssel besteht aus einer gewissen Anzahl an Zeichen/Sonderzeichen und muss nun direkt aus der Kommandozeile rauskopiert werden.

Nun geht man zu Hosteurope ins KIS und geht auf Domainservices -> Domain Administration -> Nameserver – / DNS-Einträge bearbeiten. In der Liste unten wählt man nun die Domain aus und klickt auf editieren.

Sollte der TXT Eintrag im Falle einer Zertifikatserneuerung bereits gemacht worden sein, dann einfach den Eintrag _acme-challenge.seesle.at raussuchen und dort den Schlüssel hinterlegen. Falls dieser noch nicht gemacht wurde, kann er ganz unten angelegt werden.

Wichtig hier: Falls man die normale Domain und alle Subdomains (mittels Wildcard Zertifikat) beim Certbot angegeben hat, muss man zwei TXT Einträge mit _acme-challenge.seesle.at anlegen

Wenn die Keys eingegeben sind, müssen sie mit jeweils nacheinander einem Klick auf zunächst Update und anschließend Speichern bestätigt werden.

Nun muss man ein paar Minuten warten bis die Einträge im DNS-System verfügbar werden. Zur Prüfung kann hierzu eine DNS TXT-Abfrage durchgeführt werden. Bei mir lokal, hat mein Router diese Einträge gecached und somit teils sehr lange nicht erneuert deshalb hab ich dann auf folgendes Tool zurückgegriffen.

Wenn hier die zwei Schlüssel korrekt angezeigt werden, kann man wieder zurück zum Certbot in die Kommandozeile und mit Enter die Zertifikatserstellung abschließen.

Certbot prüft nun ob die Keys an den korrekten Stellen eingetragen wurden (und ob man dadurch auch der Eigentümer der Domains ist) und erstellt bei Erfolg die Zertifikate ins Verzeichnis:

/etc/letsencrypt/username/live/seesle.at

Für Hosteurope sind die Zertifikate fullchain.pem und privkey.pem wichtig. Die beiden kopiert man sich am besten irgendwohin, wo man auch über den Browser zukommt (ACHTUNG: die müssen im Anschluss wieder lokal gelöscht werden).

Nun geht man bei Hosteurope unter WebHosting -> beim jeweiligen Vertrag auf Konfigurieren -> Sicherheit/SSL -> SSL administrieren

Unten in der Liste sucht man sich die Domain raus, für die das Zertifikat werstellt wurde und klickt auf Ersetzen bzw. Anlegen.

Im folgenden Fenster gibt es drei Felder die mit einer Datei gefüllt werden und ein Passwort Feld:

  • Im Feld Zertifikat lädt ihr das fullchain.pem File rein
  • Im Feld Key lädt ihr das privkey.pem File rein
  • Unser von Let’s encrypt angelegtes Zertifikat benötigt kein Passwort, somit kann dieses leer bleiben.
  • Das Feld CA* wird ebenfalls einfach leer gelassen

Anschließend ein Klick auf Absenden und das Zertifikat sollte hochgeladen sein. Nach ein paar Minuten ist bei korrekter Konfiguration des DNS auch über https erreichbar.

Zwei zusätzliche Dinge sind bei Hosteurope noch zu beachten:

  • Wechselt ihr von http auf https muss meist auch der A-Eintrag im DNS auf eine andere IP gewechselt werden (mehr dazu findet ihr in den FAQs von Hosteurope
  • Diesen Vorgang müsst ihr nun alle 3 Monate durchführen, ihr werdet aber per E-Mail auf die am Anfang eingegebene Adresse 20 Tage vor Ablauf benachrichtigt

Ich hoffe mit diesem Artikel ein geeignete Anleitung für diese Nische verfasst zu haben und würde mich auf Feedback freuen.

HostEurope Performance Probleme Teil 2

Nachdem ich von HostEurope nun die Antwort bekam „Wir haben was geändert schauen sie nach obs besser geht, wir dürfen aber nicht verraten was wir geändert haben“ möchte ich das ganze weiter analysieren.

Angefangen hat es mit etlichen Ausfällen meines VPS. Naja Ausfälle kann man das ganze nicht wirklich nennen, eher extreme Lags. Teilweise dauerte ein Zugriff auf ein simples PHP Skript mit 2-3 Datenbankabfragen über eine Minute. Nachdem ich mit HostEurope etliche Aufträge durchgeackert habe kam als letzte Antwort nun der obige Satz. Ich verstehe nicht ganz warum ich nicht wissen darf was geändert wurde aber egal, rein vom Gefühl her ist der Server wirklich schneller und zuverlässiger erreichbar. Die Zugriffszeit ist zwar immer noch nicht wirklich eines Webspaces würdig aber was solls…

Als nächsten Schritt möchte ich mal ein komplettes Update meines Servers durchführen. Um einen Performance Vergleich vorher nachher zu haben würde ich vor diesem Update nun einen Unix Benchmark drüber laufen lassen, anschließend upgraden und zu guter letzt wieder den Benchmark laufen lassen. Nachdem die Version 6 von Ubuntu mittlerweile doch schon relativ outdated sein dürfte, könnte schon der eine oder andere Performancesprung drinnen sein. Das Update wird in zwei Schritten durchgeführt zunächst werden die Pakete alle auf den aktuellen Stand der Version 6 gebracht und anschließend wird ein Dist-Update durchgeführt. Die Benchmarks werden 5 mal hintereinander ausgeführt und der Wert wird gemittelt.

Hier noch die Screenshots zum ersten Benchmark durchlauf:

Zum Glück fiel meine Wahl gleich von Anfang an auf Ubuntu welches die Aptitude (apt-get) Paketverwaltungstools verwendet und somit recht einfach zu administrieren ist. Also zunächst mal mit Virtuozo ein Server Backup erstellen um im Fehlerfall gleich wieder den Server funktionstüchtig wiederherzustellen. Dazu mal bei Virtuozzo einloggen und unter „Maintenance => New Backup“ ein neues Erstellen. Bei HostEurope kann man sich 2 „Full Backups“ erstellen lassen, das erste wurde gleich nachdem der Server fertig Konfiguriert war gesetzt, das zweite wird jetzt gemacht. Nicht wundern das Backup dauert relativ lang.

Anschließend per SSH auf den V-Server verbinden und als root einloggen. Jetzt müssen zuerst mit „apt-get update“ die Paketlisten upgedatet werden und anschließend versuch ich mal einen „Update-Testlauf“ mit „apt-get upgrade –simulate“

Wenn hier soweit keine Probleme aufgetreten sind, dann werd ich ein upgrade mit „apt-get upgrade“ durchführen.

Der erste Schritt ist nun getan! Das System mit Ubuntu 6.04 ist nun auf dem aktuellen Stand. Als nächstes wird ein Distributions Upgrade auf die nächste Ubuntu Version mit LTS (Long Term Support) angestrebt! Mal schauen wann ich dazu komme!