Docker mit NGINX-Proxymanager, UFW, Fail2Ban, MariaDB und Nextcloud — Teil 5

Mittlerweile sind wir schon beim fünften Teil meines Dockertutorials angekommen. Sofern ihr quasi von null startet und ein ähnliches Projekt (Nextcloud, Mariadb, ufw, Fail2ban, NPM etc.) umsetzen wollt, empfehle ich hier zu beginnen.

Ich gehe in diesem Teil davon aus, dass bei euch Docker, UFW – mit Adaptierung für Docker,  Portainer, Nextcloud, Mariadb und der Nginx-Proxymanager laufen. Thema dieses Parts wird die Inbetriebnahme von Fail2Ban sein. Fail2Ban überwacht Logdateien des Systems auf gewisse „Muster“ = Fehler und sperrt zb. IP-Adressen die zu oft fehlerhafte Authentifizierungen durchführen. Um die Filterung durchzuführen, werden Filter (=via reguläre Ausdrücke, regexp) genutzt. Ich bin, was die Erstellung eigener regulärer Ausdrücke angeht nicht gut und meistens auf „das Internet“ angewiesen (nur so nebenbei angemerkt).

Fail2Ban wird in einem Docker Container laufen und sowohl den Host, als auch die Container schützen. Wichtig ist, dass sämtliche Logverzeichnisse (Docker und Host) im Fail2Ban-Dockercontainer „read-only“ (nur lesen) eingebunden werden müssen, da Fail2Ban sonst ja keinen Zugriff auf die Logs hätte und seine Arbeit nicht verrichten könnte.

Logverzeichnisse

Ich greife hier etwas vor, obwohl wir den Container  für Fail2Ban noch nicht ausgerollt haben. Es ist wichtig, dass man folgenden Zusammenhang versteht.

  • Die Logverzeichnisse, der zu überwachenden Dienste,  werden als sog. „Bindmounts“ – nur lesend in den Fail2Ban Container eingebunden.
  • Die Einbindung im Fail2Ban-Container erfolgt im Verzeichnis /remotelogs/<name des Containers oder Dienstes>
  • Es sollen der Nginx-Proxy-Manager, Nextlcoud und der SSH-Zugang des Hosts überwacht werden.
  • Bei mir werden alle Dockervolumes nach /var/lib/docker/volumes/<Name des Volumes> gemountet.

Das sieht dann bzgl. Volumes bei mir zb so aus (in Portainer – Container Fail2Ban):

Aufschlüsselung der (Logging)Verzeichnisse

  • SSH loggt am Host in das Verzeichnis /var/log
  • Nextcloud loggt (in meinem Fall) nach /var/lib/docker/volumes/Nextcloud_data/_data/data
  • NPM nach /var/lib/docker/volumes/nginxpm_data/_data/logs
  • das /config Verzeichnis hat mit dem Logging selbst nichts zu tun, sondern enthält die Konfiguration von Fail2ban

Ausrollung von linuxserver/fail2ban

Wie sicher schon gewohnt, wird der Container von Fail2Ban via Portainer ausgerollt. Der Name des Image ist linuxserver/fail2ban.

Volumes

Es muss nur ein Volume für die Konfiguration von Fail2Ban erzeugt werden. Ich nenne es fail2banconfig.

Abgesehen von der Zuordnung des Volumes für die Fail2Ban-Konfiguration, ges es bei der Zuordnung der weiteren Volumes, um das jeweilige Loggingverzeichnis der diversen Dienste (am Host). Wenn ihr euch 1:1 an die Anleitung hier  gehalten habt, sollte das so ausehen. (Kann aber variieren, wenn ihr andere Bezeichnungen für die Volumes gewählt habt!) Achtet auch darauf, dass die Logs via „BIND“ eingebunden werden!

Netzwerk, Ports

Wir benötigen für Fail2Ban weder eine IP-Adresse noch irgendwelche Ports.

Command & Logging

  • Interactive & TTY

Environment

  • PUID 1000 (die ID eures Standardusers, der ganz am Anfang angelegt worden ist. Seht ihr wenn ihr in /etc/passwd des Hosts reinschaut)
  • PGID 1000 (Gruppe des Standardusers. Seht ihr auch, wenn ihr in /etc/passwd des Hosts reinschaut)
  • TZ Europe/Berlin
  • SSMTP_HOST (Hostname eures SMTP-Servers) -> OPTIONAL: Nur wenn ihr Mailbenachrichtigungen erhalten wollt!
  • SSMTP_PORT (normalerweise 587)
  • SSMTP_HOSTNAME – Der Hostname eures Dockerhosts (ich hab hier den FQDN meines Dockerhosts eingetragen)
  • SSMTP_USER (Der Benutzer zur Benutzerauthentifizierung am Mailserver)
  • SSMTP_PASSWORD (Das Passwort, des Benutzers am Mailserver)
  • SSMTP_TLS (Normalerweise auf YES zu setzen)
  • SSMTP_STARTTLS (Normalerwese auf YES zu setzen)

Restart Policy

  • Always

Capabilities

  • Hier muss zusätzlich „NET_ADMIN“ und „NET_RAW“ aktiviert werden.

Ausrollen

  • Nun kann der Container ausgerollt werden „Deploy the Container“.

Anpassung der Konfiguration von fail2ban

Fail2Ban läuft jetzt zwar, jedoch ohne Konfiguration der sog. „Jails“. In den Jails, werden Dienste definiert, die überwacht werden sollen. Ebenso muss eine „Action“ (also Aktion) definiert werden, um Festzulegen, wie denn mit „bösen“ Anfragen umgegangen werden soll.

Die Konfiguration erledigen wir via SSH am HOST (im Konfigurationsverzeichnis von Fail2Ban).

/var/lib/docker/volumes/fail2banconfig/_data/fail2ban

WICHTIG: Alle *.conf Dateien werden bei einem Restart des Containers überschrieben. Deshalb ist für jede Adaptierung einer .conf-Datei eine .local Datei zu erstellen.

Am Besten ist es, neue Dateien mit der „Endung“ .local zu erstellen, oder bestehende Dateien zu kopieren, wenn man den Inhalt benötigt.

fail2ban.conf -> fail2ban.local

An der.conf-Datei wird KEINE ÄNDERUNG durchgeführt.

Wir kopieren die Datei (vorbeugend) und erstellen so eine .local Datei:

cp fail2ban.conf fail2ban.local

jail.conf -> jail.local

An der.conf-Datei wird KEINE ÄNDERUNG durchgeführt.

Wir kopieren die Datei (vorbeugend) und erstellen so eine .local Datei:

cp jail.conf jail.local

Der Inhalt der Datei jail.local sieht in meinem Fall so aus:

[DEFAULT]
bantime = 21600
findtime = 120
maxretry = 3

[DEFAULT]
mta = sendmail
action = %(action_)s
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at

Filter für NPM und Nextcloud erstellen

Wir wechseln am Host in das Verzeichnis /var/lib/docker/volumes/fail2banconfig/_data/fail2ban/filter.d

Dort erstellen wir eine Datei mit Namen: npm.local

Inhalt des NPM Filters (npm.local)

[INCLUDES]
before = common.conf

[Definition]
failregex = ^\s*(?:\[\]\s+)?- 401 \d+ - [A-Z]+ \w+ \S+ "[^"]+" \[Client <ADDR>\]
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 403
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 444

Weiters erstellen wir eine Datei für Nextcloud mit Namen nextcloud.local

Inhalt des Nextcloud Filters (nextcloud.local)

[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"messag>
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"messag>
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

Jail für SSH (des Hosts) NPM und Nextcloud erstellen

Ganz wichtig ist bezüglich „JAILS“ der Parameter chain = 

  • Ist es ein Dockercontainer, den wir schützen wollen, müssen wir bei chain = DOCKER-USER verwenden!
  • Ist es der Host, den wir schützen wollen, müssen wir bei chain = INPUT verwenden!

Für die Anpassungen müssen wir (wieder am Host) in  das Verzeichnis:

/var/lib/docker/volumes/fail2banconfig/_data/fail2ban/jail.d

wechseln.

Jail für Nextcloud (nextcloud.local)

Via nano nextcloud.local erstellen wir eine Datei,  mit Folgendem Inhalt.

[nextcloud]
backend = auto
enabled =
port = 80,443
chain = docker-user
protocol = tcp
filter = nextcloud
logpath = /remotelogs/nextcloud/nextcloud.log
action = %(known/action)s

Jail für Nextcloud-auth (nextcloud-auth.local)

Via nano nextcloud-auth.local erstellen wir eine Datei,  mit Folgendem Inhalt.

[nextcloud-auth]
enabled = true
chain = docker-user
port = http,https
logpath = %(remote_logs_path)s/nextcloud/nextcloud.log
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban

Jail für den NPM (npm.local)

Via nano npm.local erstellen wir eine Datei,  mit Folgendem Inhalt.

[npm]
enabled = true
chain = docker-user
logpath = /remotelogs/npm/fallback_error.log
/remotelogs/npm/default-host_access.log
/remotelogs/npm/proxy-host-*_error.log
/remotelogs/npm/default-host_error.log
/remotelogs/npm/fallback_access.log

destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban

Jail für SSH des Hosts (sshd.local)

Via nano sshd.local erstellen wir eine Datei,  mit Folgendem Inhalt.

[sshd]
enabled=true
chain = INPUT
logpath = /remotelogs/authloghost/auth.log
backend = %(sshd_backend)s

destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban

Restart von Fail2Ban bzw. des Containers

Fail2ban kann mit dem Befehlt fail2ban-client restart neu gestartet werden. Hier hat es bei mir allerdings immer wieder ein wenig „gehakelt“.

Am Besten ist es, einfach den Fail2Ban-Container neu zu starten. Nach einem Neustart des Containers, sollte nun auch Fail2Ban ordnungsgemäß funktionieren und sowohl Host, als auch Container schützen.

Beobachten kann man das Verhalten im Fail2Ban – Log. Das Logging findet allerdings im Container statt. Entweder verwendet ihr die Shell, die via Portainer erreichbar ist, oder greift einfach über die Konsole des Hosts darauf zu.

Der Zugriff auf die Container-Konsole gelingt mit:

docker exec -it fail2ban bash

fail2ban = hierbei der Name des Containers.

Das Prompt sieht so aus (bis auf das was vor dem : steht:

root@vps2348723:/# docker exec -it fail2ban bash
root@8ddbafffbff4:/#

Das Logverzeichnis befindet sich hier: /config/log/fail2ban

Die Datei heißt: fail2ban.log

Am Besten ist es ihr lasst mittels tail -f /config/log/fail2ban/fail2ban.log das Log live mitlaufen und gebt bei den übewachten Diensten zb. mehrfach ein falsches Passwort ein. Das Log sollte darauf reagieren. (Bitte drauf achten, dass ihr euch nicht selbst aussperrt!)

Diskussionsforum zum Thema

Docker mit NGINX-Proxymanager, UFW, Fail2Ban, MariaDB und Nextcloud — Teil 4

MariaDB installieren

Um Nextcloud mit einer  Datenbank versorgen zu können, greife ich auf MariaDB (innerhalb eines Dockercontainers) zurück. MariaDB wird -wie alle anderen Container- die eine fixe IP benötigen, eine manuelle IP, aus dem von uns erstellten „Docker-Netzwerk“ erhalten. Wie immer wird das Image via Portainer ausgerollt.

Volume erstellen

MariaDB benötigte ein Volume, um persistente Daten zu speichern (ich nenne es mariadb_lib).

 

 

Ports und Imagename

  • Image: mariadb:latest
  • Port 3306:3306

Netzwerk

Beim Netzwerk wählen wir unser benutzerdefiniertes Netzwerk und vergeben dem Container eine statische IP, (Gateway, DNS sind optional).

Volume zuordnen

Das erstellte volume wird dem Verzeichnis

/var/lib/mysql

zugeordnet.

Environment Variablen

  • MYSQL_ROOT_PASSWORD -> bei Value ein Rootpasswort für MariaDB setzen

Restart Policy

  • Always

Command and Logging

  • Console -> Interactive & TTY

Container ausrollen

  • via Klick auf „Deploy the container“

Bestenfalls sieht das dann bei euch so aus (bis auf die Netzwerkadresse, die ihr lt. euren Netzwerk vergeben könnt)

Standardabsicherung von Mariadb

Via Portainer und nach Auswahl des Containers „MariaDB“ wechseln wir in die Konsole, des MariaDB-Containers.

Wir tippen: mariadb_secure_installation

um ein paar grundlegende Basiseinstellungen bzgl. Sicherheit zu tätigen. Das Rootpasswort = das Passwort, das wir vorhin bei den Umgebungsvariablen für den MariaDB-Root-User gesetzt haben!

  • switch to unix_socket authentication: Y
  • Passwort für Root setzen: haben wir schon, also N
  • Remove anonymous users: Y
  • Disallow root remotly: Y
  • Remove Testdatabase: Y
  • Reload privileges tables now: y

Datenbank für Nextcloud erstellen

Von den Containern her, wird es wie folgend laufen.

  • MariaDB hat eine fixe IP (10.0.0.100)
  • Nextcloud wird die IP 10.0.0.200 bekommen
  • Wir müssen nun auf unserer Mariadb
    • Eine Datenbank erstellen
    • Einen User erstellen, der via 10.0.0.200 Vollzugriff auf die erstellte Datenkbank hat

Folgende Aktionen sind in der Konsole des MariaDB-Dockercontainers durchzuführen.

Verbinden mit MariaDB

mariadb

User „nextcloud“ erstellen, der von 10.0.0.200 aus auf die DB zugreifen darf

CREATE USER 'nextcloud'@'10.0.0.200' IDENTIFIED BY 'geheimespasswort';

Datenbank erstellen

CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

Dem oben erstellten User den Zugriff gewähren

GRANT ALL PRIVILEGES on nextcloud.* to 'nextcloud'@'10.0.0.200';

FLUSH PRIVILEGES;

quit

Nextcloud installieren

Ich gehe davon aus, dass ihr bereits einen DNS-Namen (FQDN) für eure Cloud -bei eurem Provider- eingerichtet habt. Ich nehme für dieses Beispiel hier meine Test(sub)domain nc.it-networker.at

Volume einrichten

Wie mittlerweile schon gewohnt, ist ein Volume zu erstellen. (Name: nextcloud_data). Ich gehe hier jetzt nicht nochmals ins Detail, wie man via Portainer ein Volume erstellt.

Container erstellen

Netzwerkkonfiguration (Ports)

Hier müsst ihr darauf achten, dass ihr hostseitig kein Port verwendet, das bereits vergeben ist. Ich wähle hier in meinem Fall, Port 88 am Host -> Port 80 im Container.

Command and Logging

  • Interactive & TTY

Volumes

  • /var/www/html -> volume Nextcloud_data

Network

Da wir unserem MariaDB Benutzer „nextcloud“@“10.0.0.200“ den Zugriff auf die Nextcloud Datenbank gestattet haben, bekommt der Nextcloudcontainer IP 10.0.0.200 in unserem Dockernetzwerk.

Umgebungsvariablen

Hier ist an sich nichts hinzuzufügen, da die Konfiguration ja erst beim Aufruf der FQDN eurer Nextcloudinstallation startet (zb. nc.euredomain.com). Später kann jedenfalls der Parameter PHP_UPLOAD_LIMIT und PHP_MEMORY_LIMIT angepasst werden.

Restart Policy

  • Always

Container ausrollen

  • Mit Klick auf „Deploy the container“. Bei Erfolg:

NGINX-Proxy-Manager anpassen

Damit wir unsere Nextcloudinstallation ansprechen können, muss nun im NPM ein Host hinzugefügt werden. Wie oben erwähnt, soll meine Nextcloud Installation unter der Subdomain nc.it-networker.at erreichbar sein. Das Ganze soll via SSL erfolgen.

SSL muss sein

Deshalb erstelle ich mir via NPM ein SSL Zertifikat.

  • Login in den NPM
  • Oben SSL-Certificates -> Add SSL Certificate -> Letsencrypt
  • Domain: nc.it-networker.at (add unterhalb anklicken)
  • Eure Mailaddresse angeben
  • I Agree to…. anklicken
  • Save

Host erstellen

  • Login in den NPM
  • Oben Hosts -> Proxy Host
  • Rechts -> Add Proxy Host
  • Domain Namen eingeben
  • Port eingeben (80)
  • Block Common Exploits -> aktivieren  (ist im Screenshot fälschlicherweise inaktiv)

  • Reiter SSL -> das zuvor erstellte SSL – Zertifikat wählen
  • Force SSL
  • ggf. HTTP/2 Support
  • HSTS Enabled
  • Save

Weitere Schritte via GUI von Nextcloud

Nun sollte die Adresse eurer Nextcloud aufrufbar sein.

Folgend die Einstellungen lt. meinem Tutorial

Nach  Klick auf installieren dauert es nun ggf. ein wenig bis ihr in Nextcloud landet.

Nun könnt ihr User anlegen und die Cloud nutzen.

Optimierungen

Vor Allem die Warnung „Du greifst über eine sichere Verbindung auf deine Instanz zu, deine Instanz generiert jedoch unsichere URLs….“ muss ernst genommen werden. Um die Warnung los zu werden ist die config.php von nextcloud anzupassen. Wir erinnern uns, dass wir während dem Setup von Nextcloud ein Volume erstellt haben. Sofern ihr die Konfiguration von Docker nicht adaptiert habt, landen alle erstellten Volumes (im Dateisystem des Hosts) auf /var/lib/docker/volumes/<Containername>/_data.

Die Nextcloud-Konfiguration liegt bei mir auf : /var/lib/docker/volumes/Nextcloud_data/_data/config

Die Datei config.php muss bearbeitet werden.

nano config.php

Nach der Zeile

'version' => '25.0.2.3',

muss Folgendes ergänz werden. (Natürlich mit eurer Domain bzw. eurer Docker-IP des NPM)

'overwritehost' => 'nc.it-networker.at',
'overwrite.cli.url' => 'http://nc.it-networker.at',
'overwriteprotocol' => 'https',
'trusted_proxies' =>
array (
0 => '10.0.0.3',
),

Nach dem Restart des Nextcloud Containers, ist die Warnung dann verschwunden.

Caldav/ Carddav

Eventuell (naja, eigentlich ziemlich sicher) seht ihr auch noch folgende Meldungen, wenn ihr als Administrator in NC (=Nextcloud) einsteigt und „Verwaltung / Übersicht“ aufruft.

Dein Webserver ist nicht richtig konfiguriert, um „/.well-known/caldav“ aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ?.
Dein Webserver ist nicht richtig konfiguriert, um „/.well-known/carddav“ aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ?.

Um dieses Problem zu lösen, muss der Host von Nextcloud im NPM angepasst werden.

Konkret gesprochen, müsst ihr diese Werte im Fenster (Reiter Advanced des NC-Proxy-Hosts) einfügen.

location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav
{
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/webdav
{
return 301 $scheme://$host/remote.php/dav;
}

und speichern.

Dann verschwindet die Meldung.

Hier gehts zu Teil 5

Diskussionsforum zum Thema

Docker mit NGINX-Proxymanager, UFW, Fail2Ban, MariaDB und Nextcloud — Teil 3

Willkommen zum dritten Teil meiner Docker-Serie. Bitte lest unbedingt auch die vorhergehenden Teile!

Der NPM ist nun via Full-Qualified-Domain-Name und einem offiziellem SSL Zertifikat von Let’s Encrypt erreichbar. Der nächste Schritt wäre nun, auch Portainer mittels offiziellem SSL Zertifikat und über HTTPS (ohne Port 9443) erreichbar zu machen.

Portainer erhält ein zusätzliches Netzwerk

Da unser NPM sich in einem 10.0.0.x Netzwerk befindet, Portainer aber noch immer mit der Docker-Standard-IP 172.17.0.x läuft, muss unser Netzwerk (10.0.0.x — bei mir mit Namen „it-yourself“) mit Portainer verbunden werden.

Dies ist mit wenigen Klicks erledigt.

  • Einloggen in Portainer
  • Auswahl von Containers (links)
  • Danach Portainer wählen (den Container)
  • Ganz nach unten scrollen
  • Bei Connected Networks das Dropdownmenü öffnen und das selbst erstellte Netzwerk auswählen (it-networker bei mir)
  • Abschließend auf Join network klicken

Von nun an, ist der Portainer mit 2 Netzwerken verbunden. Der Standardbridge (172.17.0.x) und dem benutzerdefinierten Netzwerk (10.0.0.x).

NPM – SSL Zertifikat erstellen und Host eintragen

Wir müssen jetzt via NPM einerseits ein SSL-Zertifikat erstellen und andererseits einen Hosteintrag für portainer.it-networker.at (ihr nehmt natürlich euren Sub(domainnamen) den ihr gewählt habt).

Auch das ist in wenigen Schritten erledigt.

  • Einloggen in den NPM
  • Menü SSL Certificates
  • Add SSL Certificate -> Letsencrypt (rechts)
  • Domain im „Domain Names“ Feld angeben. (nicht Return drücken, sondern unterhalb der eingabe auf „Add <……>“ klicken
  • Email-Address for Letsencrypt eintragen
  • Den „Terms of Service“ zustimmen
  • Auf Save klicken
  • Nach rund 30 Sekunden erscheint nun auch dieses SSL Zertifikat in der Übersicht

Einen Hosteintrag erstellen

Wieder befinden wir uns im NPM-Backend.

  • Auswahl von Hosts -> Proxyhost
  • Rechts auf „Add Proxy Host“ gehen
  • Domain Names: Eure Sub(Domain) bei mir portainer.it-networker.at
  • Scheme: HTTPS
  • Forwart Hostname/IP: IP oder Containername von Portainer. Bestenfalls immer den Namen nehmen. In meinem Fall: portainer
  • Forward Port: 9443
  • Block Common Exploits
  • Reiter SSL: Auswahl des zuvor erstellten SSL Zertifikates für Portainer.
  • Force SSL
  • Save

Testlauf

Nach Eingabe von https://portainer.it-networker.at (ohne Port) gelangen wir jetzt direkt zum Portainer-Login. Wie immer müsst ihr hier natürlich eure Sub(domain) nehmen.

Absicherung und eine kurze Zusammenfassung

Von außen ist nur unser NPM auf Port 80 und 443 erreichbar. Wir prüfen das mittels den aktuellen UFW-Firewallregeln. Wichtig ist, dass alle Regeln die ALLOW FWD als Action hinterlegt haben sich ausschließlich auf den Zugriff auf die Docker-Container beziehen. Standardregeln – Action: ALLOW IN, beziehen sich auf den Host und nicht auf die Container.

Nachdem wir uns via ssh auf unseren Server eingeloggt haben, tippen wir:

ufw status verbose

Abgesehen von einer ALLOW IN Regel, die uns den Zugriff auf SSH erlaubt, sollte es hier nur 2 weitere Regeln geben.

  • 10.0.0.3 ist in dem Fall mein NPM-Container (bei euch könnte der Container eine andere IP haben)
  • ALLOW FWD = Action
  • Anywhere = From
  • Also: Erlaube den Zugriff von überall her auf Port 80 und 443 des Containers mit der IP 10.0.0.3

Mehr sollte in unseren Firewallregeln nicht enthalten sein!

Zugriffssteuerung per NPM

Der NPM erlaubt es uns, den Zugriff auf die angebotenen Services einzuschränken. Dies gelingt mit sogenannten Access-Lists, die direkt im NPM angelegt werden können.

Einschränkung

Es ist NICHT möglich, Seiten die bereits eine Benutzerauthentifizierung druchführen zusätzlich via NPM-Accesslists mit User/Passwort zu schützen.  Eine Einschränkung auf IP-Adressen ist möglich. (Funktioniert nur dann, wenn man eine statische öffentliche IP hat!)

Der Grund hierfür ist:

Having an Access Control List (ACL) with username and password requires the browser to always send this username and password in the Authorization header on each request. If your proxied app also requires authentication (like Nginx Proxy Manager itself), most likely the app will also use the Authorization header to transmit this information, as this is the standardized header meant for this kind of information. However having multiples of the same headers is not allowed in the internet standard and almost all apps do not support multiple values in the Authorization header. Hence one of the two logins will be broken. This can only be fixed by either removing one of the logins or by changing the app to use other non-standard headers for authorization.

Quelle: https://nginxproxymanager.com/faq/#do-i-have-to-use-docker

Das heißt soviel wie, dass man – sofern eine Website hat – die bereits eine Autorisierung mittels Benutzername und Passwort durchführt, nicht noch eine zweite Authorisierung mit Benutzername und Passwort (in dem Fall von NPM aus) erfolgen kann. Man hätte dann nämlich mehrfache sogenannte Authorization Headers, die bei jeder Anfrage mitgeschickt werden müssten. Dies widerspricht den Internetstandards und funktioniert somit nicht!

Sofern ihr also nicht die Möglichkeit habt, die Anfragen zu kritischen Bereichen euerer Infrastruktur zumindest auf eure statische öffentliche IP einzuschränken, wäre dies, wenn man auf Nummer sicher gehen will, eventuell per VPN zu lösen.

Zugriff auf die IP Adresse einschränken

Durch einen Klick auf das Menü Access Lists und folgend die Auswahl von „Add Access List“ kann der Zugriff auf angelegte Hosts eingeschränkt werden. Dies geschieht entweder mittels Username / Passwort (wenn möglich! siehe oben!), oder direkt via eurer öffentlichen IP. Natürlich können beide Einschränkungen auch kombiniert werden. Hier hat man dann eine Differenzierung vorzunehmen. Gemeint ist mit Differenzierung der Parameter Satify Any, im Zuge der Erstellung einer Access-List.

Wie oben ersichtlich, will ich eine IP Zugriffsliste erstellen. Der Parameter Satisfy Any ist deaktiviert. Was bedeutet das?

Angenommen, ihr würdet hier nur einen Benutzer&Passwort anlegen und die IP-Settings auf den Standardeinstellungen belassen. IP Seitig wären dann alle IPs auf „Deny“ = verweigern. Selbst wenn ihr Usernamen und Passwort korrekt angebt, könnt ihr euch deshalb nicht einloggen. (Es müssen beide Kriterien zutreffen)

Setzt man aber den Parameter Satisfy Any auf ON (Eingeschaltet), so reicht es, wenn entweder Username und Passwort angegeben werden, oder die IP Regel stimmt.

Das heißt also: Sobald die User/Passwortkombination ok ist, funktioniert der Einstieg.

Wir wollten aber eine Einschränkung auf IP-Addresse vornehmen und belassen den Schalter „satisfy any“ auf aus / off.

  • Im Reiter „Access“ fügen wir im Feld „allow“ unsere öffentliche statische IP hinzu.
  • Und klicken auf Save

Die angelegte Access-List kann dann einem Host hinzugefügt werden.

  • Im Reiter Hosts -> Proxyhost des NPM, bearbeiten wir einen bereits angelegten Host (=Drei Punkte rechts des Hosteintrages anklicken -> EDIT).
  • Gleich im ersten erscheinenden Fenster (Edit Proxy Host) ist nun unten unsere Access-Liste zu wählen. (Dropdown-Menü)

 

  • Abschließend mit „Save“ speichern

Schon ist der Zugriff auf unseren NPM-Container auf unsere IP eingeschränkt. Somit kann niemand (mit anderer IP) auf die Seiten zugreifen.

Hier  geht’s zu Teil 4…

Diskussionsforum zum Thema

Docker mit NGINX-Proxymanager, UFW, Fail2Ban, MariaDB und Nextcloud — Teil 1

Willkommen zum ersten Teil meiner Docker-Serie. Ich versuche in diesem mehrteiligen Tutorial darzustellen, wie man Docker auf einem VServer verwenden kann. Wenn ihr so etwas vor habt, müsst ihr euch dessen bewusst sein, dass dieser Server 24/7 im Internet steht. Der Server muss also laufend aktualisiert und auch überwacht werden. Dies gilt für den Host selbst, aber natürlich auch für die Dockercontainer! Wo immer möglich, solltet ihr Zugriffe einschränken, auf IPtables (ufw) zurückgreifen und ein Monitoring und Update-tool installieren.

 💡 WICHTIG: Das hier ist KEINE Docker-Rootless-Installation! D.h. die Prozesse innerhalb der Dockercontainer laufen mit dem User root. Selbst wenn man Container mit einem Standarduser ausrollt, heißt es nicht, dass somit alle anderen Prozesse (der Container) „rootless“ laufen.

Ich habe den Zugriff auf die Dienste, die vom Internet aus zugreifbar sind, auf meine 2 statischen öffentlichen IPs eingeschränkt. Sofern ihr aus Sicherheitsgründen Docker ohne Root verwenden wollt, gibt es hier eine ganz gute Anleitung (allerdings auf englischer Sprache). Ich werde mich dem Thema später zuwenden, jedoch nicht innerhalb dieser Artikelserie.

Zielsetzung

  • Auf einem Server, der im Internet steht, oder aus dem Internet erreichbar ist, wird -basierend auf Ubuntu Server – Docker installiert.
  • Es ist bereits ein Full-Qualified-Domain-Name (eine Domain) registriert, die auf den Dockerhost zeigt. In meinem Fall ist das portainer.it-networker.at
  • Als Verwaltungstool kommt Portainer zum Einsatz.
  • Zum Schutz von Host und Client wird UFW eingesetzt.
  • Nachdem die gesamte Netzwerkkonnektivität von Docker via iptables gesteuert wird, wird UFW adapiert, damit die – mittels UFW- gesetzten Regeln greifen.
    ACHTUNG: Eine nicht-adaptierte Konfiguration von UFW hat zur Folge, dass -sofern man Containerports „exposed“ = nach außen öffnet- jeder von überall aus  darauf Zugriff hat! (Mehr dazu unten in der Anleitung)
  • Es wird NGINX-Proxy-Manager installiert, der die Verbindungen von außen zu den angebotenen Webseiten / Services „verwaltet“.
  • Über den NGINX-Proxy-Manager werden via Letsencrypt SSL Zertifikate zur Verfügung gestellt.
  • Fail2Ban (im Dockercontainer) sorgt für die zusätzliche Absicherung von Host und Container.

Weiterlesen