IT-MÜCKE

Apache Logformat für fail2ban anpassen

Beitragsdatum 13.05.2018
Letzte Aktualisierung 30.06.2018
Betrifft apache 2, fail2ban 0.9.x und andere

Bitte beachten Sie: alle IP-Adressen in diesem Beitrag wurden durch ein „x“ anonymisiert (z.B.: 123.456.789.x).

Problem

  • Ich benutze Logwatch, um Aktivitäten auf meinem Server zu beobachten
  • Logwatch meldete mit nun seit längerer Zeit zahlreiche Versuche bekannte Hacks zu benutzen, um in meinen Server einzudringen („Attempts to use known hacks“)
  • Dies konnten auch weit über 1.000 Versuche pro 24 Stunden von der selben IP aus sein
  • Eigentlich sollte Fail2ban genau das verhindern und die selbe IP nach einigen Versuchen per automatischer Firewallregel sperren
  • Dies funktionierte offensichtlich nicht
  • Beispiel:
    • In der Logfile /var/log/apache2/other_vhosts_access.log fanden sich zahlreiche Einträge dieser Art (IP-Adresse aus Datenschutzgründen anonymisiert):
      default-91_250_114_x:443 188.155.69.x - - [12/May/2018:20:14:43 +0200] "-" 408 142 "-" "-"
      default-91_250_114_x:443 188.155.69.x - - [12/May/2018:20:15:04 +0200] "-" 408 142 "-" "-"
      default-91_250_114_x:443 188.155.69.x - - [12/May/2018:20:15:25 +0200] "-" 408 142 "-" "-"
      ...
    • Trotz passenden Jail und Filter und erfolgreichem Test mittels Prüfung mit der Logfile, wurden diese Logfileeinträge nicht durch fail2ban erkannt und daher die IP-Adresse nicht gesperrt

Prüfung und Ermittlung der Ursache

  • Zuerst prüfte ich, ob der richtige Filter von fail2ban genutzt wird
    • Dazu über folgendes Kommando nach einem Teil des regexp des fail2ban-Filters suchen:
      # fail2ban-client -d | grep "[teil der regexp]"
      # z.B.:
      fail2ban-client -d | grep "408 \[0-9\]"
    • Hierbei muss die gewünschte regexp angezeigt werden
    • Ist dies nicht der Fall, so benutzt fail2ban nicht den korrekten Filter
    • Dies kann in der Konfigfile jail.local von fail2ban oder über eine VerwaltungsGUI angepasst werden (z.B. Plesk)
  • Dann prüfte ich, ob die regexp auch richtig funktioniert:
    • Dazu über das folgende Kommando den Filter auf die entsprechende Logile anwenden und sich die matches anzeigen lassen:
      # fail2ban-regex --print-all-matched [logfile] /etc/fail2ban/filter.d/[filter] | less
      # z.B.:
      fail2ban-regex --print-all-matched /var/log/apache2/other_vhosts_access.log /etc/fail2ban/filter.d/apache-408.local | less
      
      # Ausgabe:
      Running tests
      =============
      
      Use   failregex filter file : apache-408, basedir: /etc/fail2ban
      Use         log file : /var/log/apache2/other_vhosts_access.log
      Use         encoding : UTF-8
      
      
      Results
      =======
      
      Failregex: 16 total
      |-  #) [# of hits] regular expression
      |   1) [16] .*:(80|443) <HOST>.* 408 [0-9]{1,4} .*
      `-
      
      Ignoreregex: 0 total
      
      Date template hits:
      |- [# of hits] date format
      |  [41] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
      `-
      
      Lines: 41 lines, 0 ignored, 16 matched, 25 missed
      [processed in 0.01 sec]
      
      |- Matched line(s):
      |  default-91_250_114_x:443 89.13.132.x - - [13/May/2018:06:13:49 +0200] "-" 408 1946 "-" "-"
      |  default-91_250_114_x:443 89.13.132.x - - [13/May/2018:06:20:27 +0200] "-" 408 1946 "-" "-"
      ...
    • Sollten hier keine matches angezeigt werden, so kann der Befehl mit der Option –print-all-missed ausgeführt werden:
      Running tests
      =============
      
      Use   failregex filter file : apache-408, basedir: /etc/fail2ban
      Use         log file : /var/log/apache2/other_vhosts_access.log
      Use         encoding : UTF-8
      
      
      Results
      =======
      
      Failregex: 16 total
      |-  #) [# of hits] regular expression
      |   1) [16] .*:(80|443) <HOST>.* 408 [0-9]{1,4} .*
      `-
      
      Ignoreregex: 0 total
      
      Date template hits:
      |- [# of hits] date format
      |  [42] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
      `-
      
      Lines: 42 lines, 0 ignored, 16 matched, 26 missed
      [processed in 0.01 sec]
      
      |- Missed line(s):
      |  default:80 47.75.6.xx - - [13/May/2018:04:55:54 +0200] "PROPFIND / HTTP/1.1" 403 425 "-" "-"
      ...
    • Tauchen hier die eigentlich gesuchten Einträge auf, dann passt die regexp nicht und muss geändert werden
  • Die genannten Tests verliefen alle positiv - fail2ban nutzte also den korrekten Filter und die Einträge matchten
  • Schließlich brachte mich eine Suche auf die Webseite seleads.com, auf der eine Anpassung des Logformats von Apache2 vorgeschlagen wird
    • Fail2ban kann bestimmte Logfiles, die vom apache Webserver erzeugt werden, nicht korrekt interpretieren
    • Dazu zählt die access-Logfile für vhosts (virtuelle hosts) ohne eigene Access-Logfile: other_vhosts_access.log
    • Dadurch werden bestimmte Angriffe oder Scans nicht von fail2ban erkannt und gesperrt
    • Nachdem ich die auf der genannten Webseite beschriebene Lösung des Problem testete, konnte fail2ban die Logfile korrekt auswerten und diese Art der Angriffe/Scans abwehren
  • Ferner konnte ich ermitteln, wie diese Logeinträge entstehen:
    • Hier wurde mein Server auf bestimmte OpenSSL-relevante Bugs getestet
    • Führe ich von einem externen Client den folgenden Befehl aus, so entsteht dieser identische Logeintrag:
      # openssl s_client -connect [server ip]:443
      # z.B.:
      openssl s_client -connect 91.250.114.x:443
      
      # Eintrag in Logfile other_vhosts_access.log:
      default-91_250_114_x:443 89.13.132.x - - [13/May/2018:06:13:49 +0200] "-" 408 1946 "-" "-"
    • Damit war klar, wie der Angreifer vorgeht und dass ich ihm keine Möglichkeit geben möchte, hundert- bis tausendfach mein System zu testen

Lösung

  • Das Logformat vom apache für access-logs für vhosts ohne eigene access-logfile muss angepasst werden
  • Dazu wie folgt vorgehen:
    • Konfig des apache2 anpassen:
       vim /etc/apache2/apache2.conf
    • Änderungen:
      # ---
      # mod by richard 2018-05-13:
      # auskommentiert:
      #LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
      # eingefuegt:
      LogFormat "%t %v:%p %h %l %u \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" fail2ban
      # end of mod
      # ---
    • Konfig für die Logfile other_vhosts_access.log anpassen:
      vim /etc/apache2/conf-enabled/other-vhosts-access-log.conf
    • Änderungen:
      # ---
      # mod byrichard 2018-05-13
      # auskommentiert:
      #CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined
      # eingefuegt:
      CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log fail2ban
      # end of mod
      # ---
    • Anschließend den apache neu starten:
      service apache2 restart
    • Danach fail2ban neu starten:
      service fail2ban restart
  • Nun kann getestet werden:
    • Von einem externen Client aus den Angriff durchführen:
      openssl s_client -connect [server ip]:443
    • Auf dem Server die logfile von fail2ban überwachen:
      tail -f  /var/log/fail2ban.log
      
      # Ausgabe:
      2018-05-13 07:46:56,021 fail2ban.filter         [8425]: INFO    [apache-408] Found 89.13.132.x
    • Wenn nun der richtige Filter angezeigt wird und die IP des externen Clients, dann passt es
    • Die Änderung des Logformats wirkt sich übrigens wir folgt dargestellt aus:
      # vorher:
      default-91_250_114_x:443 89.13.132.x - - [13/May/2018:06:13:49 +0200] "-" 408 1946 "-" "-"
      
      # nachher:
      [13/May/2018:07:02:58 +0200] default-91_250_114_x:443 89.13.132.x - - "-" 408 1946 "-" "-"

Anpassung logwatch an neue Struktur

Nachdem man das Logformat des apache2 geändert hat, kann logwatch genau diese Einträge nicht mehr interpretieren. Es fehlt dann in der Logwatch-Mail der Abschnitt - nicht so gut. Daher sollte man nun die Logwatch-Konfiguration anpassen.

# Zu ändernde Datei ins lokale Konfig-Verzeichnis kopieren:
cp /usr/share/logwatch/default.conf/services/http.conf /etc/logwatch/conf/services/

# Ändern:
# Alter Eintrag:
#$LogFormat = "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"|%h %l %u %t \"%r\" %>s %b|%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

# Anpassung/neuer Eintrag (Erweiterung um das oben beschriebene Format-Muster):
$LogFormat = "%t %v:%p %h %l %u \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"|%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"|%h %l %u %t \"%r\" %>s %b|%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

# Um die lokale Konfig komplett zu machen, werden noch zwei Softlinks gesetzt:
ln -s /usr/share/logwatch/scripts/services/http /etc/logwatch/scripts/services/http
ln -s /usr/share/logwatch/default.conf/logfiles/http.conf /etc/logwatch/conf/logfiles/http.conf

# Anschließend testen:
/etc/cron.daily/00logwatch
  • Dann müsste eine Mail mit dem aktuellen Logwatch abgeschickt werden, das die typischen other_vhosts-Einträe wieder enthält:
    --------------------- httpd Begin ------------------------ 
    
     0.06 MB transferred in 582 responses  (1xx 0, 2xx 388, 3xx 18, 4xx 176, 5xx 0) 
        105 Content pages (0.01 MB),
          6 Redirects (0.00 MB),
        471 Other (0.05 MB) 
     
     Attempts to use known hacks by 37 hosts were logged 82 time(s) from:
        x.21.191.213: 6 Time(s)
           ^null$ 6 Time(s) 
        x.134.12.189: 6 Time(s)
           ^null$ 6 Time(s) 
        x.94.66.238: 6 Time(s)
           ^null$ 6 Time(s) 
        x.42.1.206: 5 Time(s)
           ^null$ 5 Time(s) 
    ...

Eine lokale Konfiguration wird einer default-Konfig (in /usr/share/logwatch/…) vorgezogen.


Quellen:


Ähnliche Themen im blog:
fail2ban, openssl, apache


zurück