OE3BLC
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"
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 Manager
filter.d/npm.local
[INCLUDES]
[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 =
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.
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"
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
filter.d/B1_service.local
[INCLUDES]
[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.
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 github
docker image von crazy-max
ubuntuusers