Fail2ban Jails

ipod86

Lt. Junior Grade
Registriert
Jan. 2009
Beiträge
448
Hallo,

ich habe heute meinen VM mit Docker mittels Fail2ban für ssh abgesicherte.

Nun würde ich gerne meinen nginx reverse proxy mit aufnehmen.

Dort gibt es ja viele Tutorials die wirklich alle was anderes schreiben.
Habe mir jetzt mit diversen Tutorials und ChatGPT folgendes zusammengestellt.

Was haltet ihr davon?

Code:
[DEFAULT]
# Grundkonfiguration für alle Jails
bantime  = 3600
findtime = 600
maxretry = 5
backend = auto

# Schutz vor Brute-Force-Angriffen auf HTTP-Authentifizierung
[npm-http-auth]
enabled  = true
filter   = nginx-http-auth
logpath  = /data/compose/2/data/logs/proxy-host-*_access.log
           /data/compose/2/data/logs/default-host-access.log
maxretry = 3

# Schutz vor allgemeinen 4xx- und 5xx-Fehlern
[npm-4xx-5xx]
enabled  = true
filter   = nginx-4xx-5xx
logpath  = /data/compose/2/data/logs/proxy-host-*_access.log
           /data/compose/2/data/logs/default-host-access.log
maxretry = 10

# Schutz vor verdächtigem Zugriff auf spezielle URL-Muster (Bad Bots)
[npm-badbots]
enabled  = true
filter   = nginx-badbots
logpath  = /data/compose/2/data/logs/proxy-host-*_access.log
           /data/compose/2/data/logs/default-host-access.log
maxretry = 1
bantime  = 86400

# Schutz vor häufiger Wiederholungsanfragen (DoS-Minderungen)
[npm-all-access]
enabled  = true
filter   = nginx-all
logpath  = /data/compose/2/data/logs/proxy-host-*_access.log
           /data/compose/2/data/logs/default-host-access.log
maxretry = 60
findtime = 60

# Schutz vor gezielten 404-Angriffen (Suchen nach Schwachstellen)
[npm-404]
enabled  = true
filter   = nginx-404
logpath  = /data/compose/2/data/logs/proxy-host-*_access.log
           /data/compose/2/data/logs/default-host-access.log
maxretry = 5
findtime = 300

# Schutz vor wiederholten SSL/TLS-Fehlern
[npm-ssl-errors]
enabled  = true
filter   = nginx-ssl-error
logpath  = /data/compose/2/data/logs/proxy-host-*_error.log
maxretry = 3

# Schutz vor ungültigen Hostnamen (z.B. Host-Header-Angriffe)
[npm-invalid-host]
enabled  = true
filter   = nginx-host-header
logpath  = /data/compose/2/data/logs/proxy-host-*_error.log
maxretry = 5
bantime  = 86400

Code:
# Datei: /etc/fail2ban/filter.d/nginx-http-auth.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST) .*HTTP/.*" 401
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-4xx-5xx.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST|HEAD) .*HTTP/.*" (4\d{2}|5\d{2}) .*
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-badbots.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST|HEAD) .*HTTP/.*" 200 .*"(?:bot|crawl|spider|wget|curl|nikto)"
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-all.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST|HEAD) .*HTTP/.*"
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-404.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST|HEAD) .*HTTP/.*" 404
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-ssl-error.conf
[Definition]
failregex = ^.*\[error\].*SSL_do_handshake\(\) failed:.*peer error SSL
            ^.*\[crit\].*SSL_do_handshake\(\) failed:.*SSL routines.*
ignoreregex =


# Datei: /etc/fail2ban/filter.d/nginx-host-header.conf
[Definition]
failregex = ^<HOST> -.* "(GET|POST|HEAD) .*HTTP/.*" (400|444)
ignoreregex =
 
Wenn es für dich funktioniert ist doch alles top.
Achte nur darauf, dass die Bans auch in der richtigen iptables-kette (oder welche Firewall du sonst nutzt) landet, sonst geht Docker da gerne dran vorbei :)
 
  • Gefällt mir
Reaktionen: Der Lord
Getestet habe ich es noch nicht.
Nur erstmal runtergeschrieben um es hier zu zeigen.

Die ganzen Dockerkontainer erreiche ich über die IP des Host mit entsprechndem Port. Dann müsste das in iptables funzen oder?

Da hab ich nie was manuell angepasst.
 
Genau das funktioniert leider nicht. Docker nimmt nicht ganz unwesentliche Änderungen an den Ketten in iptables vor und routet da hin und her.
Wenn du verhindern willst dass Ports, die Docker aufmacht, nicht erreichbar sein sollen muss das in eine bestimmte Kette: DOCKER-USER.

Folgende Aktion nutze ich dafür (erfolgreich) direkt in der jail.conf:

Code:
action = iptables-allports[actname=name4, chain=DOCKER-USER]
         iptables-allports[actname=name6, iptables=ip6tables, chain=DOCKER-USER]

Der "actname" ist dabei wichtig, da er sonst der Meinung ist das wäre dieselbe Action zwei mal und funktioniert dann nicht. Ich habe da den Namen meines zu schützenden Dienstes drin, für dich wäre das zb nginx4/nginx6. Ist aber grundsätzlich frei zu wählen.
 
Muss ich die action in diesem Abschnitt einfügen?
Screenshot_20240813_151341_RaspController.jpg

Edit
Eher im Default Bereich oder?

Edit 2
Dann wird es aber auch bei nicht Docker bezogenen Dingen ausgeführt wie bei ssh, ist das schlimm?

Sonst in jedem jail separat hinzufügen was mit docker zu tun hat?
 
Zuletzt bearbeitet:
In der config gibt es so gesagt eigentlich keine "Bereiche" das ist nur per Kommentar etwas gegliedert. Wo die action landet ist afaik egal, es greift überall solange es im Jail steht.

Wie meinst du
ipod86 schrieb:
Dann wird es aber auch bei nicht Docker bezogenen Dingen ausgeführt wie bei ssh, ist das schlimm?

Sonst in jedem jail separat hinzufügen was mit docker zu tun hat?
Mit SSH hat das ganze ja nichts zu tun, das Jail konfigurierst du ja Pro dienst und die Action zählt dann auch nur für diesen.

Wenn du nun 1 nginx-jail baust, welches die Logs deines Containers einliest, muss diese Action dort auftauchen.

Wenn du ein ssh-jail benutzt braucht es diese angabe nicht, da geht alles "normal".
 
Ah, ich dachte es muss alles in meine jail.local
Kann ich in den Ordner einfach noch eine jail2.local legen?

Oder eine npm.local und eine ssh.local

Edit
Dieser Bereich/Überschrift gibt also nicht vor was dahin kommt
Screenshot_20240813_155714_RaspController.jpg
 
Da muss ich ein Stück weit passen, da ich die jail.local gar nicht nutze.

Mein Konstrukt ist folgendermaßen:

Eine dienst.conf in /etc/fail2ban/jail.d/
Hier habe ich nur einmal ein "[]" drin, welcher aber nur der jail-name ist (bsp "nginx").
Diese hat verweise auf
  • die action (iptables-allports), welche aus dem default mitgeliefert ist in /etc/fail2ban/action.d/iptables-allports.conf.
  • den filter (dienst.conf in /etc/fail2ban/filter.d/) in der ich meine regex-matcher habe.

Die iptables-allports.conf habe ich nicht verändert, ich gebe ihr aus dem jail nur neue Parameter mit (chain, actname) da sonst in die Standard-Chain (INPUT) genutzt würde.

Nachteil bei deiner jail.local wäre auch, dass du dir damit alles kaputtmachst, wenn deine Konfig nicht stimmt. Mit getrennten Jails kannst du diese aktivieren/deaktiveren und modifizieren ohne dass die anderen Jails davon beeinflusst werden.
 
An sich könnte es jetzt laufen. Hab die Filter in filter.d angelegt und die jails für npm in jails.d abgelegt.

Leider meckert er bei all meinen filtern.
Magst du mir mal deine jails für npm und die Filter senden?
 
Ich keine npm-jails oder Filter ;)

Meine sind für meinen Mailserver, aber ist alles ja nur Regex, gerade bei den Filtern.

Ich mache die immer so, dass ich mir einen mittelgroßen Ausschnitt des logs bei https://regex101.com/ reinkopiere und dann damit meinen Filter baue. <HOST> ersetze ich da temporär mit (\d+\.\d+\.\d+\.\d+) was ein ziemlich dummer matcher für eine ip-adresse (und ggf. mehr) ist.
 
Zurück
Oben