Ein paar irrelevante Tutorials

Nginx Proxy Manager

Den Nginx Proxy Manager (NPM) kann man vor Webservices im eigenen Netz schalten. Der Datenverkehr wird dann immer durch den NPM zu den Webservices geleitet. Das kann man z.B. dazu nutzen, Absicherungen wie Virenschutz, Contentfilter oder Ad-Blocker dazwischen zu stellen. Vor allem aber kann man den NPM dazu nutzen, Webservices mit sicheren SSL-Zertifikaten abzusichern und so zum Beispiel per https auf eine Webanwendung zuzugreifen, die eigentlich nur http kann.

Installation

Wir sind auf unserem Server per SSH angemeldet und besitzen auch die Sudo-Rechte (siehe hierzu: https://tutorials.kernke.koeln/sicherheit/server-absichern.html#Admin-User-einrichten). Zunächst ist eine Dockerumgebung zu installieren. Dazu gibt es verschiedene Methoden. Meine habe ich hier beschrieben.
Dann wird ein Verzeichnis namens "npm" erstellt und in selbiges gewechselt. Darin erstellen wir mit nano eine Datei namens "config.json" mit folgendem Inhalt:

{
  "database": {
    "engine": "mysql",
    "host": "db",
    "name": "npm",
    "user": "npm",
    "password": "npm",
    "port": 3306
  }
}

Dann brauchen wir wieder einmal eine Datei namens "docker-compose.yml", die diesmal folgenden Inhalt bekommt:

services:
  app:
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - 80:80
      - 81:81
      - 443:443
    volumes:
      - ./config.json:/app/config/production.json
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db
    environment:
    # if you want pretty colors in your docker logs:
    - FORCE_COLOR=1
  db:
    image: mariadb:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "npm"
      MYSQL_DATABASE: "npm"
      MYSQL_USER: "npm"
      MYSQL_PASSWORD: "npm"
    volumes:
      - ./data/mysql:/var/lib/mysql

Mittels Docker-Compose werden nun die hier definierten Images erstellt und die Container gestartet:

docker compose up -d

In manchen Installationen muss der Befehl "docker-compose" (also mit Bindestrich) lauten. Wenn die Container gestartet sind, kann man sich zum ersten Mal auf der Weboberfläche des NPM anmelden. Dazu gibt man die Adresse des Systems mit dem Port 81 in den Browser ein. Man landet auf einer Login-Seite, auf der man die temporär gültigen Credentials 

Email address: admin@example.com
Password: changeme

eingeben muss. Wie das Passwort bereits erahnen lässt, müssen wir das natürlich als erstes ändern. Wichtig ist, hierbei eine gültige eMail-Adresse einzugeben, damit wir nachher Let's encrypt Zertifikate beziehen und erneuern können.

Nutzung von Let's encrypt Zertifikaten für Freigaben

Wenn wir einen Dienst im Internet freigeben, dann können wir den NPM dazu nutzen, ihn mit einem SSL-Zertifikat verschlüsselt auszuliefern. Im Folgenden gehe ich daher davon aus, dass es einen intern gehosteten Webdienst gibt und dass eine Portfreigabe auf den NPM im Internet-Router eingerichtet ist. Außerdem gibt es eine (dynamische) Domain, die auf dem Router als DynDNS eingetragen ist. Wie das im Einzelnen geht, hängt vom jeweils verwendeten Internet-Router ab und ist daher nicht Gegenstand dieses Tutorials.

Wir gehen also zunächst auf die Web-GUI des NPM und dort auf "Hosts/Proxy Hosts" und klicken auf den Button "Add Proxy Host". In dem sich nun öffnenden Dialog geben wir den Namen, unter dem der Dienst von außen erreichbar ist, ein und die interne IP-Adresse sowie den Port.

Dann wählen wir das Register "SSL" aus. Dort wählen wir aus: "Request a new SSL Certificate with Let's Encrypt". "Force SSL" sollte man aktivieren. Das bewirkt, dass HTTP-Requests auf HTTPS umgelenkt werden. Bedarfsweise könnten wir hier noch die eMail-Adresse ändern. Natürlich müssen wir die Nutzungsbedingungen von Let's Encrypt akzeptieren. Wenn wir jetzt auf "Save" klicken, dann wird bei Let's Encrypt ein neues Zertifikat für die vorher eingegebene Domain abgerufen und auf dem NPM gespeichert. 

Wenn wir hier keine Fehlermeldung erhalten, dann haben wir alles richtig gemacht und unser interner Webdienst ist von außen über die eingegebene Domain mit einem sicheren SSL-Zertifikat erreichbar.

Absicherung von ausschließlich intern erreichbaren Diensten

Wenn wir Webdienste haben, die wir auch intern mit einem vertrauenswürdigen SSL-Zertifikat absichern möchten, dann können wir dazu einen Dienst wie DuckDNS nutzen. Hier besteht die Möglichkeit, ein Let's Encrypt Zertifikat zu beziehen, ohne den Dienst für das Internet freizugeben. Zunächst muss man sich bei DuckDNS unter https://www.duckdns.org registrieren oder einloggen. Hier kann man kostenlos bis zu 5 Subdomains von duckdns.org beziehen. Diese kann man für DynDNS nutzen oder aber - und das machen wir hier - als Pseudo-Domains, die aus dem großen, bösen Internet gar nicht erreichbar sind. Auf der Webseite von Duckdns sucht man sich zunächst eine freie Domain aus. Wenn man sie ausgewählt hat, dann wird unter "current ip" die IP-Adresse angezeigt, mit der man gerade im WWW unterwegs ist. Diese überschreibt man nun einfach mit der internen Adresse des Webdienstes, also z.B. 192.168.47.11. Diese Adresse ist von außen nicht erreichbar. 

Im oberen Teil der Webseite wird ein Token angezeigt. Das ist wichtig und muss kopiert werden. Nun loggt man sich auf der Webseite des NPM ein und geht dort auf die Seite "SSL Certificates". Dort klickt man auf "Add SSL Certificate" und "Let's Encrypt". In dem sich öffnenden Dialogfenster gibt man zunächst die Domain(s) ein, die man nutzen möchte. Hier empfiehlt es sich, die soeben registrierte Subdomain mit und ohne vorgestelltes "*." einzugeben. Dann wählt man "Use a DNS Challenge" und den DNS Provider "DuckDNS" aus. Außerdem kopiert man in das Feld "Credentials File Content" das vorher kopierte Token hinein.

Wenn jetzt keine Fehlermeldung erscheint, dann haben wir ein Let's Encypt Zertifikat, das wir intern verwenden können. Manchmal muss man erst ein zweites oder sogar drittes Mal auf "Save" klicken, damit das klappt. Fluchen könnte auch helfen. Wenn es dann geklappt hat, dann steht ein neuer Eintrag in der Liste der Zertifikate aber noch mit dem Status "Inactive". Wir haben ja noch keinen Dienst damit verknüpft. Dazu gehen wir auf das Register "Hosts" und wählen "Proxy Hosts" aus. Hier klicken wir auf "Add Proxy Host". Dort geben wir eine Domain ein. Wenn wir das Zertifikat mit einer "*"-Domain eingerichtet haben, dann können wir es als Root-Zertifikat für die gewählte Subdomain verwenden und somit für jeden abzusichernden Webdienst eine eigene Sub-Subdomain erfinden. Untere "Scheme" haben wir die Wahl zwischen "http" und "https". Dann können wir die interne Domain des Dienstes und den Port, unter dem er lauscht, angeben.

Jetzt wählen wir das Register "SSL" und wählen hier das soeben erstellte Zertifikat aus, wählen noch mindestens "Force SSL" aus und klicken auf "Save". Nun ist der interne Webdienst unter der ausgewählten Subdomain mit einem gültigen SSL-Zertifikat geschützt. Aber erreichen können wir ihn so noch nicht. Was ist falsch? Naja, woher soll unser Rechner, oder irgend ein Rechner in unserem Netzwerk wissen, was er mit der Adresse z.B. "hanswurst4711.duckdns.org" anfangen soll? Hierzu ist eine Namensauflösung im internen Netzwerk erforderlich. Entweder wir betreiben einen eigenen DNS-Server, wie ihn zum Beispiel Adblocker mitbringen oder wir manipulieren die Namensauflösung der Clients. Bei Linux-Clients schreibt man dazu einfach eine entsprechende Zeile in die Datei "/etc/hosts", die man mit Root-Rechten bearbeiten muss.

sudo nano /etc/hosts

Und fügt z.B. ein:

192.168.47.12   *.hanswurst4711.duckdns.org

Dabei verwendet man natürlich nicht die Adresse des betreffenden Webdienstes, sondern des NPM. Nun ist der Webdienst unter der Subdomain mit HTTPS und einem gültigen Zertifikat erreichbar.

Let's Encrypt Zertifikate erneuern

Zertifikate sind immer nur eine begrenzte Zeit gültig. Rechtzeitig bevor sie ablaufen, erhalten wir eine freundliche Mail von Let's Encrypt. Ein Zertifikat im NPM zu erneuern, ist so ziemlich das Einfachste, was man sich vorstellen kann. Man geht auf der Web-Oberfläche des NPM auf "SSL Certificates" und klickt auf die drei Punkte neben dem zu erneuernden Zertifikat. Hier kann man  einfach auswählen "Renew Now" und das Zertifikat wird erneuert.