Nginx-Proxy absichern (Fail2Ban etc.)

Begonnen von FunkOdyssey, 23 Mai 2018, 18:28:15

Vorheriges Thema - Nächstes Thema

FunkOdyssey

Hallo, ich nutze eine Docker-Umgebung und habe Nginx-Proxy im Einsatz (zzgl. LetsEncrypt). Ich habe die Variante Separate Containers im Einsatz.
Im SSL-Check (ssllabs.com) komme ich mittlerweile auf ein A+ Niveau.

Die Ports 80/443 sind von außen erreichbar.
Aber: Ich habe den Zugriff eigentlich nur über eine Credentials-Abfrage via htpasswd gesichert.
Irgendwie finde ich die Lösung nicht sehr glücklich. Einen Brute-Force-Angriff würde ich nicht mitbekommen.

Es hat nicht zufällig jemand sein System weiter absichern können?
Was könnte man noch davor- bzw. dazwischensetzen?
Macht Fail2Ban Sinn? Hat jemand Fail2Ban in einer solchen Konstellation zufällig schon in Betrieb?

Ich bin über folgenden Thread gestolpert. Bin mir aber nicht sicher, ob das sinnvoll ist:
https://forums.docker.com/t/restricting-external-container-access-with-iptables/2225
https://github.com/SuperITMan/docker-fail2ban

Ich weiß, dass dies nicht wirklich ein FHEM-Thema ist. Aber ich versuche es dennoch. Danke.


ThoTo

Ich hatte dazu Mal iptables/nginx mit GeoIP im Einsatz.
Länder aus dem DACH Raum erlaubt + optional Urlaubsdestinationen, damit kannst du schon viele Script Kiddies aussperren.

LG Thomas
KNX | MQTT | Docker | Sonos | FHEMapp

"Zwei Dinge sind unendlich, das Universum und die menschliche Dummheit, aber bei dem Universum bin ich mir noch nicht ganz sicher." (Albert Einstein)

stefanpf

Da es sich um einen begrenzten Benutzerkreis handelt,
würde eher zu einem Client seitigem Zertifikat tendieren.
Dann sollte da erst einmal Ruhe sein :)

FunkOdyssey

#3
So hatte ich es beim Apache2-ReverseProxy auch.
Bei Nginx habe ich damit so meine Probleme. Ich finde nichts dazu (im Docker-Nginx-Image). Ich müsste demnach wahrscheinlich eine eigene Config erstellen und verliere die Vorteile des automatisch gepflegten Docker-Image.

Wernieman

Wieso .. die IPTables-Regeln kannst Du doch auf dem Host setzen?

Und wenn Du die Logfiles aus dem Container rausgelingt hast, könntest Du auch "fail2ban" einsetzen und damit BrutForce-Attacken umgehen.

Habe jetzt seit ?10? meinen Rechner ssh/http/https per fail2ban geschützt. SSH mäßig sehr sinnvoll, bei http/https hatte ich bis heute in den Jahren nur 3 Angriffe ... und das war 1x Test und 2x "Problem saß vor dem Bildschirm"
Also auf https-Ebene nicht gerade so super sinnvoll,. Eher ... ist Deine Komplette Infrastruktur über http erreichzbar oder ist das "nur" für letsencrypt und Weiterleitung auf https.

- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

FunkOdyssey

#5
Zitat von: Wernieman am 24 Mai 2018, 08:53:18
Wieso .. die IPTables-Regeln kannst Du doch auf dem Host setzen?

Ich habe absolut noch keine fail2ban-Erfahrungen. Beim Einlesen habe ich auch festgestellt, dass der fail2ban-Container im Host-Modus laufen muss. Auch mit "--cap-add=NET_ADMIN", um die IPTables anpassen zu können. Ich muss mich aber noch schlau machen bzgl. der Konfiguration (.jail & Co.).

Zitat von: Wernieman am 24 Mai 2018, 08:53:18
Und wenn Du die Logfiles aus dem Container rausgelingt hast, könntest Du auch "fail2ban" einsetzen und damit BrutForce-Attacken umgehen.

Hier habe ich ein viel größeres Problem.
Alle wichtigen Daten liegen im Host und werden über die docker-compose.yml gemountet.
Nur nutze ich https://github.com/nginx/nginx (bzw. mit Docker-Gen und der nginx.tmpl-Datei von https://github.com/jwilder/nginx-proxy/) und hier sind die access.log/error.log nach STDOUT/STDERR umgelenkt. Ich komme von außen also nicht an die Logs.

Alternative 1: Die Symlinks aufheben. Dann müsste ich die Container selber "builden".
Alternative 2: Eigene nginx.conf (und nicht automatisiert auf Basis der nginx.tmpl) und die Logs in eine andere Datei schreiben lassen. Dieses dann als Volume mounten.

Zitat von: Wernieman am 24 Mai 2018, 08:53:18
Also auf https-Ebene nicht gerade so super sinnvoll,. Eher ... ist Deine Komplette Infrastruktur über http erreichzbar oder ist das "nur" für letsencrypt und Weiterleitung auf https.

Diese Aussage verstehe ich noch nicht so richtig.
Mein Port 80 ist nur für letsencrypt (ACME).
Ansonsten läuft die Kommunikation über eine https-Verbindung (inkl. redirect http=>https).
Die Übertragung ist vollständig verschlüsselt. Hier sollte ich mittlerweile sicher sein. Nur diese vermaledeite Anmeldung ist mir noch ein Dorn im Auge.
Fail2Ban und GeoIP stehen bei mir schon länger auf der ToDo-Liste. Aber das ist aus den gegebenen Gründen (s.o.) aktuell ein wenig schwierig.
Entweder weiche ich vom "Standard-NGINX-Separate-Containers-Modell" ab, indem ich ein eigene nginx.conf erstelle oder ich muss mit dem Risiko leben.

Mir der Variante https://github.com/linuxserver/docker-letsencrypt habe ich mich noch gar nicht beschäftigt. Wäre halt auch ne Idee, da fail2ban hier bereits enthalten ist. Ist aber weniger auf Proxies ausgerichtet.




Auch habe ich noch keine Idee, wie ich ein Client-Zertifikat auf Basis der LetsEncrypt-Zertifikate erstellen kann. Soweit ich das in Erinnerung habe, soll das gar nicht gehen. Müsste ich noch einmal recherchieren. [Update]Dem ist wohl so.[/Update]. Dann müsste also wieder eine eigene nginx.conf herhalten.

Wernieman

Also .. wir (auf Arbeit) haben letsencrypt und nginx (als Proxy) auf dem Host laufen. Dann in den Containern per docker-compose.yml die Wichtigen Pfade rausgelinkt. Macht auch denn Container nicht kaputt (ist nur Ergänzung).

Liegt aber auch daran, das längerfristig dieses durch eine "echten" Loadbalaner aufgelöst wird.  Habe hier bei mir es fast gleich laufen, nur ist der "Loadbalancer" ein Pi ;o)
(Man macht sich die Arbeit nur ein mal)

Nur muß ich Dir "echt" gestehen, wie schon geschrieben, das in einem Normalfalle Du einen Angriff BrutForce-Auth auf https Ebene wahrscheinlich nicht haben wirst. Schließlich heist Du nicht google etc. udn hast bestimmt "Tolle" Passwörter ...
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

Christoph Morrison


Aber: Ich habe den Zugriff eigentlich nur über eine Credentials-Abfrage via htpasswd gesichert.
Irgendwie finde ich die Lösung nicht sehr glücklich. Einen Brute-Force-Angriff würde ich nicht mitbekommen.
[/quote]

Die basic auth kannst du noch mit fail2ban gegen brute force schützen. Mehr brauchst du erst mal nicht.

Zitat von: FunkOdyssey am 23 Mai 2018, 18:28:15
Es hat nicht zufällig jemand sein System weiter absichern können?
Was könnte man noch davor- bzw. dazwischensetzen?

Warum ist dein FHEM übers Internet erreichbar? Wenn das nicht wirklich zwingend sein muss, mach lieber VPN ins lokale Netz und spar dir die zusätzliche Angriffsfläche aus dem Netz.

buchner51

hallo zusammen,

ich habe meinen Zugang von außerhalb mit dieser https://wiki.fhem.de/wiki/HTTPS-Absicherung_%26_Authentifizierung_via_nginx_Webserver#Beim_Aufruf_http:.2F.2F.3Cfhempi.3E_wird_nur_eine_.22Wilkommen_bei_nginx.22-Seite_angezeigt.2C_statt_der_erwartete_Login-Screen  Anleitung abgesichert, wenn ich das hier lese sicherlich nur ein Grundschutz.

Ich möchte aber nicht nur auf FEHM :8083/fhem sondern auch auf die SMARTVISU :80/sv zugreifen.

kann mir jemand den Code anpassen?

server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {

    listen 443;
    server_name fhempi;

    # check user agent
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows Phone)') {
    set $ua_type "@mobile";
    }

    ssl_certificate           /etc/nginx/cert.crt;
    ssl_certificate_key       /etc/nginx/cert.key;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/fhem.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_http_version      1.1;

      # Gehe zu FHEMWEB wenn kein mobiler Browser
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:8083;
      }
      # Gehe zu FHEMWEB smallscreen wenn mobiler Browser
      if ($ua_type = "@mobile"){
          proxy_pass          http://localhost:8084;
      }
      proxy_read_timeout  90;
      #proxy_read_timeout  20736000;
      #proxy_buffering     off;

      # User Sickboy's Erweiterung für verschlüsselte Websocket-Kommunikation (siehe Diskussionsseite)
      # Für normale Benutzer derzeit kommentiert, vom Autor Andremotz noch bisher ungetestet
      #  ... daher derzeit auskommentiert
      # Wird für 'longpoll' benötigt (z.B. bei FTUI)
      #set $my_http_upgrade "";
      #set $my_connection "Connection";

      #if ($http_upgrade = "websocket") {
      #  set $my_http_upgrade $http_upgrade;
      #  set $my_connection "upgrade";
      #}
     
      #proxy_set_header Upgrade $my_http_upgrade;
      #proxy_set_header Connection $my_connection;

      auth_basic "Restricted Content";
      auth_basic_user_file /etc/nginx/.htpasswd;

      # proxy_redirect      http://localhost:8083 https://localhost;
    }
  }


Danke
Raspberry pi 3+
KNX mit TUL, FHEM mit SMARTVISU 2.9

Wernieman

- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

buchner51

Keine Ahnung, aber deshalb frage ich. ;D
Raspberry pi 3+
KNX mit TUL, FHEM mit SMARTVISU 2.9

Wernieman

Sorry aber ich mache gerne Hilfe zur Selbsthilfe:

was passiert wohl, wenn dort stehen würde:
location /fhem
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

buchner51

dann komme ich nur auf FHEM, aber ich möchte auf FHEM und SV
Raspberry pi 3+
KNX mit TUL, FHEM mit SMARTVISU 2.9

Wernieman

- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

buchner51

#14
... diesem?
# Gehe zu Smartvisu
      if ($ua_type != "@mobile"){
          proxy_pass          http://localhost:80/sv;
      }

Das ist echt nicht meine Welt.

Oder so?
location /smartVISU {
        auth_basic "Restricted Area: smartVISU";
        auth_basic_user_file /etc/nginx/.smartvisu;

        # Zugreifendes Land erlaubt?
        if ($allowed_country = no)  {
                return 403;
        }

        proxy_pass http://<SmartVISU Server LAN IP>/smartVISU;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }


aber es führt zum Fehler.
Raspberry pi 3+
KNX mit TUL, FHEM mit SMARTVISU 2.9