Froschs Blog

Computer und was das Leben sonst noch so zu bieten hat

Zur Website | Impressum

Loggen, was iptables wegwirft

4. Dezember 2016 um 20:37 Uhr von Atari-Frosch

Um meine Server gegen diverse Arten von Angriffen abzusichern, habe ich fail2ban installiert und mir eine Reihe von Filtern angepaßt oder selbst neu gebaut. Anhand der Filter meldet fail2ban an iptables, welche IPs wie lange gesperrt werden sollen. Das funktioniert soweit ganz gut.

Trotzdem gibt es eine Reihe von IP-Adressen und -Ranges, die man eigentlich nicht fail2ban überlassen muß. Denn sie werden immer und immer wieder in den Filtern landen und immer und immer wieder erneut gebannt werden müssen. Von diesen IPs und -Ranges kommen nämlich ausschließlich Spamkommentare, aggressives Crawling auf Websites, Suchen nach ausnutzbaren Schwachstellen, Einbruchsversuche in Blogs, auf der Shell und in weitere Dienste sowie Spam-Mails. Also will man sie grundsätzlich blocken. Ist mit iptables auch nicht schwer. Aber …

… andererseits bin ich ja neugierig. Ich möchte nämlich dann trotzdem sehen, ob, wann und in welcher Menge von diesen IPs Kontaktversuche kommen, und mal mindestens, auf welche Ports. Zum einen könnte es ja sein, daß sie mal aufhören; dann könnte ich den Eintrag aus iptables wieder löschen, da müssen ja keine überflüssigen Einträge drinstehen. Zum anderen könnte man darüber erkennen, ob und wann sich das Verhalten dieser Hosts generell ändert, um dann mal nachzugucken, was sie jetzt treiben.

Denn ich sammle ja immer noch Daten zu Spam, Einbruchs- und Angriffsversuchen, um da mal ein Projekt draus zu basteln. Ich komme nur nicht so wirklich dazu. Derzeit jedenfalls nicht. Das hindert mich aber nicht, schonmal die entsprechenden Daten abzugrasen, denn je mehr ich habe, desto besser.

Was fail2ban an iptables schickt, loggt es selbst auch mit. Aus diesem Log erfahre ich nicht nur, was gesperrt wurde, sondern auch, wann und wie oft es weitere Versuche von diesen IPs gibt, trotz der Sperre. iptables dagegen macht das nicht, jedenfalls nicht von Haus aus. Und das wollte ich dann mal ändern.

Ich fand zwar mehrere Hinweise dazu, aber weil ich in Sachen iptables noch Anfänger bin, gab es dabei erstmal ein paar Mißverständnisse – die dazu führten, daß ich mich ein paarmal selbst aus dem Server aussperrte 😉

Nach Hinweisen vor allem von Stefan G. Lesser im Google-Plus-Thread Mal 'ne iptables-Frage: habe ich das Konstrukt jetzt aber fertig.

Zunächst einmal bekommt iptables eine neue Chain namens LOGDROP. Der erklären wir dann, was und wie wir loggen wollen (LOG). Danach wird festgelegt, daß alles, was geloggt wurde, weggeworfen werden soll (DROP). Schließlich wird eine IP-Range in die Chain geworfen, und am Schluß warten wir zur Überprüfung drauf, daß Päckchen aus dieser Range hereinkommen und, ähm, behandelt werden:

# iptables -N LOGDROP

# iptables -A LOGDROP -m limit --limit 1/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

# iptables -A LOGDROP -j DROP

# iptables -A INPUT -s 91.200.12.0/24 -j LOGDROP

# tail -f /var/log/syslog | grep IPTables

Die Ausgaben sehen dann so aus:

Dec 4 17:16:26 seelilie kernel: [3122961.854548] IPTables-Dropped: IN=eth0 OUT= MAC=54:04:a6:8a:66:c0:00:31:46:0d:2e:19:08:00 SRC=91.200.12.97 DST=176.9.63.237 LEN=52 TOS=0x00 PREC=0x00 TTL=119 ID=24145 DF PROTO=TCP SPT=51539 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0

Also:

  • Zeitstempel
  • Systemname
  • Quelle der Meldung (hier: kernel)
  • interner Zeitstempel
  • einleitender String wie in den iptables-Anweisungen für's Logging oben vorgegeben
  • die eigene Schnittstelle, über welche die Daten hereinkommen (hier: eth0)
  • MAC-Adresse der eigenen Netzwerkkarte und direkt dahintergeklebt (vermutlich?) die des Herkunftshosts
  • IP-Adresse des Herkunftshosts
  • IP-Adresse unseres Hosts (der kann ja theoretisch mehrere haben)
  • ein paar technische Daten
  • Protokoll TCP
  • SPT, der Port für mögliche Antworten auf dem Herkunftshost
  • DPT, der Port auf unserem Host, hier 80 = klassisches WWW ohne SSL
  • dann noch ein bißchen Technikkrams.

Für uns relevant sind Zeitstempel, IP des Herkunftshosts sowie der Zielport auf unserer Seite. Nicht ablesbar ist allerdings, was der Herkunftshost von unserem Webserver wollte.

Die hier eingetragene IP-Range eines ukrainischen VPN-Anbieters kann man übrigens wirklich bedenkenlos überall sperren, daher ist sie als Beispiel gut geeignet.

Denn aus diesem /24 kommt seit Jahren so ziemlich alles an Spam und generischen Angriffen, wofür es Bots gibt. Der VPN-Anbieter reagierte zwar vor ein paar Jahren mal auf eine Beschwerde von mir, die Reaktion schien aber vor allem darin zu bestehen, daß er von seiner Seite die IP meines (alten) Servers zeitweise in seine ausgehenden Firewall-Regeln eingetragen hatte – was heißt, daß die Bots munter weitermachen konnten. Inzwischen sehe ich sie in den Logs meines alten Servers auch wieder sehr häufig: Spamkommentare, Login-Versuche an Blog-Logins, aggressives Crawling auch auf statischen Websites usw. Dabei ist jede IP auf einen festen Job gedrillt, das heißt zum Beispiel, von der .1 und der .97 (und weiteren) kommen nur Spamkommentare, die .29 und die .113 (und weitere) versuchen sich ausschließlich an Blog-Logins usw. Bei den Login-Versuchen werden als Usernamen teilweise auch Daten vom Blog selbst verwendet, zum Beispiel der Domainname oder auch das erste Wort des Blogtitels. Die Daten wiederum haben natürlich vorher die Crawler des Botnetzes „besorgt“.

OK, das Logging ist jetzt erstmal eingerichtet. Problem ist noch, daß, wie im Thread auf Google+ aufgeführt wird, die Meldungen, da es Kernel-Meldungen sind, nur ins syslog geschrieben werden. Da gehen sie aber neben den ganzen anderen Meldungen unter, und ich will sie ja separat haben. Daher habe ich mir einen Cronjob angelegt, der ein einfaches Bash-Script aufruft. Zunächst das Script:

#!/bin/bash

grep "IPTables-Dropped" /var/log/syslog.1 | mail -s "iptables report" $mailadresse

$mailadresse ist natürlich durch die gewünschte Empfängeradresse zu ersetzen.

Und das ist der eigentliche Cronjob, wobei ich das Script sehr fantasievoll 😉 iptablesdrops.sh genannt habe:

# crontab -e

→ 45 06 * * * /root/iptablesdrops.sh

Daß das als root eingetragen werden muß, ist ja klar, ne? 🙂

Das Script soll täglich um 6:45 Uhr aufgerufen werden. Um 6:25 Uhr wird nämlich täglich das syslog rotiert, das heißt, das laufende syslog wird geschlossen und es wird nach syslog.1 umbenannt (und das vorherige syslog.1 wird zu syslog.2.gz usw.). Somit habe ich in der Datei syslog.1 jeweils das komplette syslog der vorherigen 24 Stunden. Der Vorteil, wenn ich das abgeschlossene syslog der vorherigen 24 Stunden durchsuche, besteht darin, daß ich mich nicht mit möglichen Dupes in meinem separaten Log herumschlagen muß, was mir passieren kann, wenn ich das aktuelle syslog heranziehe und da durchgreppe. Wenn bei Euch die Zeit für die logrotates eine andere ist, muß das natürlich entsprechend angepaßt werden, damit der Cronjob nicht losläuft, bevor das syslog rotiert wurde.

Ja, und wenn mir jetzt bei den Spamkommentaren, den Mailspams oder am Blog-Login etc. IP-Adressen über Wochen und Monate hinweg auffallen, dann wird fail2ban damit jetzt gar nicht mehr belästigt, sondern sie kommen direkt bei iptables in die LOGDROP-Chain.

Ein Kommentar zu “Loggen, was iptables wegwirft”

  1. SackOhneSenf quakte:

    Das mit dem Cronjob kann man machen, aber warum läßt du deinen syslogd nicht die Meldungen direkt an ein kleines Filterprogramm (Script) schicken, das kann dir dann gewünschte Meldungen ausfiltern, auf Wunsch sogar umformatieren (Technik Kram weglassen), in eine Datei schreiben und etwa alle 4 bis 8 Stunden per Mail schicken.

    Die meisten syslogd haben eine Möglichkeit die Ausgabe parallel zur normalen Log-Datei noch an weitere Ziele oder Dateien zu schicken, so auch an eine Pipe. Je nachdem welchen syslogd du einsetz, ist die Konfiguration dafür aber etwas unterschiedlich, ich kann dir daher nicht sagen schau in diese oder jene Datei.

    Sehr einfach kann man die Filter mit AWK schreiben, hat nur den Nachteil, dass bei einer Änderung der Filter der syslogd neu gestartet werden muss, um die neuen Filter zu aktivieren, da AWK keine Reload Funktion bietet.

    … und so nebenbei kann das gleiche Filterprogramm gleich nach Meldungen ausschau halten, die gravierende Probleme auf deinem Server bedeuten und dir dann gleich eine Nachricht schicken oder sonstige Aktionen anstoßen.

    Ich hab mir damit die Meldungen dann auch schon umformatiert, auf Zeilenlänge abgeschnitten und farbig unterschiedlich an ein /dev/ttyXXX ausgeben lassen, dann konnte man auf der (lokalen) Console wichtige Ereignisse live und übersichtlich mitverfolgen … und sag jetzt nicht, der Server steht ja irgendwo in einem Rechenzentrum, es gibt die Möglichkeit sich die aktuelle Ausgabe eines lokalen tty auf ein anderes tty/pty kopieren zu lassen, also auch über ssh. Ich nehme dafür meist den Busybox conspy; also per ssh anmelden, conspy /dev/ttyXXX und schon sehe ich die aktuellen Meldungen (wenn die Zugriffsrechte entsprechend gesetzt sind).

    … aber wie immer, das schöne dran ist, man kann es auf viele Weisen machen.


Kommentieren

Bitte beachte die Kommentarregeln!

XHTML: Du kannst diese Tags verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>