fail2ban
Es handelt sich hierbei weder um eine Anleitung noch um eine Empfehlung.
Die folgenden Konfigurationsbeispiele sind in ähnlicher Weise im Einsatz und beruht auf gefährlichem Halbwissen.
Es gibt Absolut keine Garantie das die Beispiele korrekt funktionieren oder überhaupt zur Sicherheit eines Netzwerkes beitragen!
Infrastruktur
Server A
fail2ban - docker-compose.yml
name: fail2ban
services:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
depends_on:
- msmtpd
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
F2B_DB_PURGE_AGE: 30d
F2B_LOG_TARGET: /data/fail2ban.log
F2B_LOG_LEVEL: INFO
volumes:
- /path_to/fail2ban:/data
- /path_to_logfile/A1_service:/monitorlogs/A1_service:ro
- /path_to_logfile/A2_service:/monitorlogs/A2_service:ro
- /path_to_logfile/nginx-proxy-manager/data/logs:/monitorlogs/npm:ro
network_mode: "host"
privileged: true
cap_add:
- NET_ADMIN
- NET_RAW
msmtpd:
image: crazymax/msmtpd:latest
container_name: fail2ban_msmtpd
restart: unless-stopped
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
SMTP_HOST: >smtp-host<
SMTP_PORT: 587
SMTP_TLS: on
SMTP_STARTTLS: on
SMTP_TLS_CHECKCERT: on
SMTP_AUTH: on
SMTP_USER: >smtp-user<
SMTP_PASSWORD: >smtp-passwort<
SMTP_FROM: >absender<
ports:
- "127.0.0.1:2500:2500"
services:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
depends_on:
- msmtpd
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
F2B_DB_PURGE_AGE: 30d
F2B_LOG_TARGET: /data/fail2ban.log
F2B_LOG_LEVEL: INFO
volumes:
- /path_to/fail2ban:/data
- /path_to_logfile/A1_service:/monitorlogs/A1_service:ro
- /path_to_logfile/A2_service:/monitorlogs/A2_service:ro
- /path_to_logfile/nginx-proxy-manager/data/logs:/monitorlogs/npm:ro
network_mode: "host"
privileged: true
cap_add:
- NET_ADMIN
- NET_RAW
msmtpd:
image: crazymax/msmtpd:latest
container_name: fail2ban_msmtpd
restart: unless-stopped
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
SMTP_HOST: >smtp-host<
SMTP_PORT: 587
SMTP_TLS: on
SMTP_STARTTLS: on
SMTP_TLS_CHECKCERT: on
SMTP_AUTH: on
SMTP_USER: >smtp-user<
SMTP_PASSWORD: >smtp-passwort<
SMTP_FROM: >absender<
ports:
- "127.0.0.1:2500:2500"
jail.d/jail.local
[DEFAULT]
chain = INPUT
maxretry = 3
bantime = -1
findtime = 10m
ignoreip = 127.0.0.0/8 172.16.0.0/12 10.0.0.0/24
action = %(action_)s
smtp.py[host=localhost:2500, sendername=Fail2Ban, sender=<absender>, dest=<empfänger>]
[npm]
enabled = true
port = http,https
logpath = /monitorlogs/npm/*error.log
chain = DOCKER-USER
[A1_service]
enabled = true
port = http,https
logpath = /monitorlogs/A1_service/A1_service.log
chain = DOCKER-USER
[A2_service]
enabled = true
port = http,https
logpath = /monitorlogs/A2_service/A2_service.log
chain = DOCKER-USER
[npm-attack]
enabled = true
maxretry = 4
port = http,https
logpath = /monitorlogs/npm/*access.log
chain = DOCKER-USER
npm = Nginx Proxy Managerchain = INPUT
maxretry = 3
bantime = -1
findtime = 10m
ignoreip = 127.0.0.0/8 172.16.0.0/12 10.0.0.0/24
action = %(action_)s
smtp.py[host=localhost:2500, sendername=Fail2Ban, sender=<absender>, dest=<empfänger>]
[npm]
enabled = true
port = http,https
logpath = /monitorlogs/npm/*error.log
chain = DOCKER-USER
[A1_service]
enabled = true
port = http,https
logpath = /monitorlogs/A1_service/A1_service.log
chain = DOCKER-USER
[A2_service]
enabled = true
port = http,https
logpath = /monitorlogs/A2_service/A2_service.log
chain = DOCKER-USER
[npm-attack]
enabled = true
maxretry = 4
port = http,https
logpath = /monitorlogs/npm/*access.log
chain = DOCKER-USER
filter.d/npm.local
[INCLUDES]
[Definition]
failregex = \[error\].*client:\s
ignoreregex =
[Definition]
failregex = \[error\].*client:\s
ignoreregex =
filter.d/A1_service.local bzw. filter.d/A2_service.local
[INCLUDES]
before = common.conf
[Definition]
failregex = <RegEx zum Durchsuchen des Logfiles>.*$
ignoreregex =
before = common.conf
[Definition]
failregex = <RegEx zum Durchsuchen des Logfiles>.*$
ignoreregex =
filter.d/npm-attack.local
[INCLUDES]
[Definition]
failregex = (301|302|401|404|422).*\".+\"\s\[Client\s\]
ignoreregex = (301|302|401|404|422).*\"/\"\s\[Client\s\]
404.*a1.example.com \"/locales/de/translation.json\" \[Client\s\]
404.*a2.example.com \"/notification\" \[Client\s\]
401.*npm.example.com \"/api/tokens\" \[Client\s\]
Zugriffsversuchen auf bekannte Schwachstellen, z.B. Konfigurationsdateien.
Findet alle zurückgewiesenen Zugriffsversuche.
Mögliche berechtigte Ablehnungen müssen über ignoreregex ausgenommen werden damit man sich nicht selbst aussperrt.[Definition]
failregex = (301|302|401|404|422).*\".+\"\s\[Client\s
ignoreregex = (301|302|401|404|422).*\"/\"\s\[Client\s
404.*a1.example.com \"/locales/de/translation.json\" \[Client\s
404.*a2.example.com \"/notification\" \[Client\s
401.*npm.example.com \"/api/tokens\" \[Client\s
Nginx Proxy Manager
proxy_set_header X-Forwarded-For $remote_addr;

Die IP des Angreifers muss an den Server B weitergeleitet werden um sie dort ggf. mit fail2ban blockieren zu können. Siehe dazu die Konfiguration von action.local am Server B.
Server B
fail2ban - docker-compose.yml
name: fail2ban
services:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
depends_on:
- msmtpd
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
F2B_DB_PURGE_AGE: 30d
F2B_LOG_TARGET: /data/fail2ban.log
F2B_LOG_LEVEL: INFO
volumes:
- /path_to/fail2ban:/data
- /path_to_logfile/B1_service:/monitorlogs/B1_service:ro
network_mode: "host"
privileged: true
cap_add:
- NET_ADMIN
- NET_RAW
msmtpd:
image: crazymax/msmtpd:latest
container_name: fail2ban_msmtpd
restart: unless-stopped
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
SMTP_HOST: >smtp-host<
SMTP_PORT: 587
SMTP_TLS: on
SMTP_STARTTLS: on
SMTP_TLS_CHECKCERT: on
SMTP_AUTH: on
SMTP_USER: >smtp-user<
SMTP_PASSWORD: >smtp-passwort<
SMTP_FROM: >absender<
ports:
- "127.0.0.1:2500:2500"
services:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
depends_on:
- msmtpd
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
F2B_DB_PURGE_AGE: 30d
F2B_LOG_TARGET: /data/fail2ban.log
F2B_LOG_LEVEL: INFO
volumes:
- /path_to/fail2ban:/data
- /path_to_logfile/B1_service:/monitorlogs/B1_service:ro
network_mode: "host"
privileged: true
cap_add:
- NET_ADMIN
- NET_RAW
msmtpd:
image: crazymax/msmtpd:latest
container_name: fail2ban_msmtpd
restart: unless-stopped
environment:
TZ: Europe/Vienna
PUID: 1000
PGID: 1000
SMTP_HOST: >smtp-host<
SMTP_PORT: 587
SMTP_TLS: on
SMTP_STARTTLS: on
SMTP_TLS_CHECKCERT: on
SMTP_AUTH: on
SMTP_USER: >smtp-user<
SMTP_PASSWORD: >smtp-passwort<
SMTP_FROM: >absender<
ports:
- "127.0.0.1:2500:2500"
jail.d/jail.local
[DEFAULT]
maxretry = 3
bantime = -1
findtime = 10m
ignoreip = 127.0.0.0/8 172.16.0.0/12 10.0.0.0/24
action = %(action_)s
smtp.py[host=localhost:2500, sendername=Fail2Ban, sender=<absender>, dest=<empfänger>]
[B1_service]
enabled = true
port = http,https,1234
logpath = /monitorlogs/B1_service/B1_service.log
maxretry = 3
bantime = -1
findtime = 10m
ignoreip = 127.0.0.0/8 172.16.0.0/12 10.0.0.0/24
action = %(action_)s
smtp.py[host=localhost:2500, sendername=Fail2Ban, sender=<absender>, dest=<empfänger>]
[B1_service]
enabled = true
port = http,https,1234
logpath = /monitorlogs/B1_service/B1_service.log
filter.d/B1_service.local
[INCLUDES]
[Definition]
failregex = <RegEx zum Durchsuchen des Logfiles>.*$
ignoreregex =
[Definition]
failregex = <RegEx zum Durchsuchen des Logfiles>.*$
ignoreregex =
action.d/action.local
[Definition]
actionban = iptables -I DOCKER-USER -m string --algo bm --string 'X-Forwarded-For:' -j DROP
actionunban = iptables -D DOCKER-USER -m string --algo bm --string 'X-Forwarded-For:' -j DROP
Die IP des Angreifers muss vom npm auf Server A an den Server B weitergeleitet werden, um sie hier ggf. mit fail2ban blockieren zu können.
Siehe dazu die Konfiguration des Proxy Hosts im npm auf Server A.
actionban = iptables -I DOCKER-USER -m string --algo bm --string 'X-Forwarded-For:
actionunban = iptables -D DOCKER-USER -m string --algo bm --string 'X-Forwarded-For:
nützliche Kommandos
am Host
sudo iptables -nL
Gibt eine Liste aller Regeln in den iptables aus. Zeigt damit die gesperrten IPs an.im fail2ban Container
fail2ban-client banned
Zeigt alle gebannten IPs zu jails an.fail2ban-client reload
Liest geänderte Konfigurationen neu ein. ACHTUNG: Funktioniert nicht, wenn eine neue Datei (jail, filter, action) hinzugefügt wird.
Hier am besten den Container neu starten.fail2ban-client unban --all
Alle banns entfernen.fail2ban-client set npm banip 123.123.123.123
In einem gestimmten jail eine IP manuell bannen.fail2ban-regex -v --print-all-matched --print-no-missed monitorlogs/npm/proxy-host-14_access.log "\[error\].*client:\s"
Eine RegEx manuell gegen ein Logfile ausprobieren.fail2ban-regex --print-all-matched --print-no-missed monitorlogs/npm/proxy-host-14_access.log /etc/fail2ban/filter.d/npm-attack.local
Eine Filterkonfiguration gegen ein Logfile ausprobieren.Sicherheitshinweise
Nochmals der Hinweis, dass diese Seite im besten Falle als Inspiration angesehen werden darf und keine Anleitung darstellt.
Es ist unerlässlich sich selbst mit Netzwerksicherheit auseinander zu setzen.
Eine einzelne isolierte Maßnahme wird zu keinem sicheren Netzwerk führen.
Links
fail2ban auf githubdocker image von crazy-max
ubuntuusers