Inhalt
1. Theorie - Aufbau eines IDS Systems
1.1 Was ist ein IDS (Intrusion Detection System)?
1.2 Was wird benötigt?
2. Praxis - Aufbau eines IDS Systems
2.1 Firewalling - Entwerfen eines iptables Skrips und einbinden in
das System
2.2 syslog-ng konfigurieren
2.3 Ausgabe mit tail
3. EOF
1. Theorie - Aufbau eines IDS Systems
1.1 Was ist ein IDS (Intrusion Detection System)?
Unter einem IDS versteht man ein System zum Erkennen von Eindringlingen
(Intrusion Detection System). Unter einem Eindringling (Intruder) versteht
man dabei eine Person, welche versucht in ein System einzubrechen um beispielsweise
Daten zu stehlen oder das System für diverse bösartige Dinge
zu missbrauchen. IDS Systeme überprüfen dabei den Netzverkehr
um Angriffe zu erkennen. So könnte ein IDS System beispielsweise auf
sehr häufige SYN Anfragen reagieren und eine entsprechende Meldung
in den Logfiles hinterlassen bzw. den Administrator per Nachricht vor einem
möglichen SYN Flood Angriff warnen. IDS Systeme können sich dabei
relativ stark unterscheiden, je nach Verwendungszweck und gedachtem Aufgabenfeld.
In diesem Text soll ein einfaches (!) IDS System mit Linux Boardmitteln
erstellt werden. Unter 2. wird genannt was genau benötigt wird. Natürlich
existieren bereits "fertige" IDS, welche nur entsprechend konfiguriert
werden müssen. So besteht die Aufgabe des scanlog Daemon beispielsweise
darin, Portscans zu melden und zu protokollieren. Snort hingegen ist ein
"vollwertigeres" IDS System. Snort ermöglicht die Analyse des Netzwerkverkehrs
in Echtzeit. Es können zahlreiche Attacken, wie beispielsweise CGI
Attacken, SMB Probes, OS Fingerprinting, Portscans erkannt und gemeldet
werden. Auf diese Programme soll in diesem Text aber wie bereits erwähnt
nicht näher eingegangen werden.
1.2 Was wird benötigt?
iptables als Grundlage für
das IDS System.
syslog-ng
Daemon zum verarbeiten der von iptables erhaltenen Nachrichten.
tail zum Ausgeben der Logs.
Hinweis: In diesem Tutorial soll nicht näher auf das kompilieren
der genannten Programme eingegangen werden. Den Source Codes liegen Readme's
bei welche dies näher beschreiben.
iptables
iptables ist ein Administrations Tool zum Packet filtern und zur Network
Address Translation (NAT) und ist seit dem 2.4 Kernel integraler Linux
Bestandteil. Wer diesen Text verstehen will, sollte wenigstens schon einmal
ein paar einfache Regeln mit iptables erstellt haben.
Wer von iptables möglicherweise noch nie was gehört hat,
sollte sich vielleicht erstmal das hier...
Einführung
in iptables
Mehr
zu iptables...
...zu Gemüte führen.
Um iptables nutzen zu können, muss der Kernel iptables unterstützen
und iptables als Modul installiert sein, desweiteren muss das Tool iptables
vorhanden sein. Einen aktuellen Linux Kernel findet ihr hier,
das Tool iptables gibts hier.
syslog-ng (syslog New Generation)
syslog-ng ist die "neue Generation" des syslog Daemons.
Der syslog Daemon ist für das Logging auf Linux Systemen zuständig.
syslogd liest System Meldungen vom lokalen System als auch vom Netzwerk
und verarbeitet diese bzw. bereitet diese auf. Dazu wird je nach Konfiguration
beispielsweise /dev/log geöffnet und regelmäßig ausgelesen.
Da der syslog aber relativ unflexibel ist was Logging angeht, wurde der
syslog-ng entworfen. Dieser wird wahrscheinlich früher oder später
(meiner Meinung nach) den syslog ersetzen und bietet wesentlich mehr Möglichkeiten
was das Loggen betrifft.
Man sollte den syslogd deaktivieren, wenn der syslog-ng verwendet wird.
Debian weist bei der Installation des syslog-ng daraufhin. Unter beispielsweise
SuSE hingegen läuft der syslogd weiter, wenn dieser nicht deaktiviert
wird. Des syslogd kann in den Runlevel Skripten deaktiviert werden.
Den syslog-ng gibt es hier.
tail
Wer mit der Konsole arbeitet, kennt auch tail (wer ersteres tut und
letzteres nicht kennt, der lügt... :) ). tail ermöglicht es den
letzten Teil von Dateien auszugeben. tail ohne weitere Option gibt dabei
immer die letzten 10 Zeilen einer Datei aus.
Uns interessiert besonders die tail Option -f bzw. --follow.
Diese erlaubt es neu hinzukommende Einträge in das Logfile, auf der
Konsole zu präsentieren auf der tail läuft.
Aus diesen 3 Programmen soll am Ende ein einfaches IDS System werden.
iptables wird dabei als Firewall benutzt, welche Packete filtert und nach
definierten Regeln loggt. syslog-ng liest die von iptables erzeugten Kernelnachrichten,
verarbeitet und speichert sie in einem Logfile. tail gibt uns das entstandene
Logfile aus.
2. Praxis - Aufbau eines IDS Systems
2.1 Firewalling - Entwerfen eines iptables Skripts und einbinden in das System
Nach dem alles hoffentlich ordnungsgemäß installiert wurde
und läuft, kann es jetzt ans erstellen des Firewall Skripts gehen.
Dieses Skript soll dabei die Grundlage für das Tutorial bilden.
Das Skript wurde mit ausreichend Kommentaren versehen und relativ einfach
gehalten. Das Logging wird im Anschluss erklärt.
#! /bin/bash
echo "Running iptables firewall script ..." # laden wichtiger Module - iptables
Modul und Logging Modul
#Alle TCP Packete die nicht über
eth0 kommen und als Zielport einen der Ports aus der Range
#Alle TCP und UDP Packete die nicht
über eth0 kommen und als Zielport einen der Ports aus der Range
#Alle TCP Packete mit gesetztem
SYN,FIN Flags werden geloggt
#Alle TCP Packete ohne gesetzten
Flag werden geloggt
#Alle TCP Packete mit gesetzten
FIN,PSH,URG Flags werden geloggt
#Alle fragmentierten ICMP Packete
werden geloggt
#Alle TCP Packete mit dem Zielport
1080 bzw. 8080 werden geloggt
#Falls mehr als 40 Packete pro Minute
mit gesetztem SYN Flag (connection request) eingehen
exit 0 |
Nehmen wir uns eine der Regeln:
iptables -A INPUT -i ! eth0 -p TCP --dport 1:1024
-j LOG --log-prefix " Alert! PrivPort "
Was passiert?
Es wird eine Regel gesetzt, welche alle
TCP Packete die nicht über eth0 kommen und als Zielport einen der
Ports aus der Range 1-1024 (privilegierte Ports) besitzen, loggt, da als
Ziel "LOG" angegeben wurde (-j = jump). So würde z.B. ein TCP Packet
mit dem Zielport 80, welches über ein PPP Interface kommt, wie beispielsweise
ppp0 (z.B. ein Modem) geloggt werden.
Wozu soll diese Regel gut sein?
Solch eine Regel wäre z.B. sinnvoll wenn auf unserem Linux Rechner
ein Apache Webserver läuft und wir wöllten, das auf diesen nur
vom lokalen Netzwerk aus Zugriff besteht. Ein Versuch vom Internet aus
auf den Apache zuzugreifen wäre erfolglos und würde geloggt werden.
So verhält es sich mit allen Service die auf unserem Linux Rechner
laufen und auf den Ports 1-1024 "lauschen".
Wie man bei den ersten 3 Regeln sieht, kann man erst verdächtigen
Traffic loggen lassen und anschließend unterbinden.
Würde man hingegen den Traffic erst unterbinden und dann versuchen
zu loggen, würde logischerweise kein Logging stattfinden, da diese
Regel nie zutreffen würde, da die entsprechenden Packete bereits vorher
verworfen wurden wären.
Die anderen Regeln sind gleich aufgebaut. Das Script sollte natürlich
an die Bedürfnisse angepasst werden.
Wie wir bei der Konfiguration des syslog-ng sehen werden, nützt
es uns nicht viel wenn wir nur einfach Loggen lassen würden, ohne
ein log-prefix anzugeben (--log-prefix). Der log-prefix ist nichts anderes
als eine String der unseren Logeintrag ergänzt.
Normalerweise bestehen die Logs aus: Datum, Uhrzeit, Hostname und
einer Nachricht (eine Warnung, ein Fehler..., Beispiele sind unter
/var/log/messages zu finden). Wenn wir aber einen Log Prefix angeben, bestehen
unsere Logs aus: Datum, Uhrzeit, Hostname UND Log-Prefix,
sowie der Nachricht. Wie wir bei der Konfiguration des syslog-ng sehen
werden, ist dieser Log Prefix notwendig um die Firewall Logs von anderen
zu trennen und diese in ein seperates Logfile zu schreiben.
Doch bevor wir mit der Konfiguration des syslog-ng beginnen, soll unser
Firewall Skript bei jedem Neustart des Systems ausgeführt werden.
Damit unser firewall skript bei jedem Neustart ausgeführt wird, müssen
wir unser System entsprechend anpassen. Wir machen folgendes:
chown root firewall.sh
chgrp root firewall.sh
chmod 700 firewall.sh
Besitzer, Gruppe und Rechte des Firewall Skript werden gesetzt. Als nächstes soll das Skript in eines der Startskripte hinzugefügt werden.
Debian/GNU Linux: Kopieren von firewall.sh nach /etc/rc.boot/
SuSE 8.1: Kopieren von firewall.sh nach /usr/sbin/, /usr/sbin/firewall.sh
in /etc/rc.d/boot.local eintragen
RedHat und MDK: Kopieren von firewall.sh nach /usr/sbin/, /usr/sbin/firewall.sh
in /etc/rc.d/rc.local eintragen
Unser Skript wird nun bei jedem Neustart ausgeführt und meldet
sich mit "Running iptables firewall script ...".
2.2 syslog-ng konfigurieren
Unser Firewall Skript wurde nun erstellt und ins System eingebunden.
Eigentlich sind wir damit schon fast am Ende.
Es muss lediglich noch der syslog-ng korrekt konfiguriert werden. Die
Konfigurationsdatei des syslog-ng befindet sich unter /etc/syslog-ng/syslog-ng.conf
. Ihr öffnet diese in eurem Lieblingseditor und fügt die
rot markierten Zeilen hinzu:
#
# /etc/syslog-ng/syslog-ng.conf # # File format description can be found in syslog-ng.conf(5). # options { long_hostnames(off); sync(0); }; source
src { unix-dgram("/dev/log"); file("/proc/kmsg"); internal(); };
# own code ---begin---
filter f_newsnotice
{ level(notice) and facility(news); };
[...] |
Konfiguration des syslog-ng Daemon ist ein relativ komplexes Thema,
deswegen werden hier nur die benötigten Zeilen näher erklärt.
Mehr Informationen zum syslog-ng liefert der man page zum syslog-ng
bzw. das FAQ zum syslog-ng.
Source
source <identifier> { source-driver(params); source-driver(params); ... };
Vom source erhält syslog-ng seine Log Nachrichten. Nachrichten, die von Programmen erstellt wurden, werden an ein solchen Source geschickt, wo syslog-ng sie dann abfängt und weiterverarbeitet. Dabei existiert ein Standardsource wo die System Nachrichten hingeschickt werden, normalerweise ist das /dev/log. Die source Zeile wird bereits in der syslog-ng.conf schon vorhanden sein und kann beibehalten werden, wichtig ist aber das file("/proc/kmsg") hinzugefügt wird, da über diese Datei Kernelmeldungen gelesen werden können (unsere von iptables erstellten Meldungen).
Der Identifier gibt dem Source eine eindeutige Identfikation. In unserem Fall heißt der Identifier "src". Dieser wird im weiteren Konfigurationsfile benötigt. Geholt werden die Logs von /dev/log (System Meldungen)bzw. /proc/kmesg (Kernel Meldungen). Mit Hilfe des source-driver kann man genau festlegen welcher Treiber benutzt werden soll um zwischen Client und syslog zu kommunizieren. Der "unix-dgram" Treiber erlaubt ein Zugriff auf /dev/log über Unix Sockets, mit Hilfe des "file" Treibers können Nachrichten von der angegebenen Datei, in unserem Fall /proc/kmsg, gelesen werden.
Destination
destination <identifier> { destination-driver(params); destination-driver(params); ... };
Destination ähnelt Source. Es gibt wieder eine Identifier, in unserem Fall "d_firewall". Das Destination gibt an wohin die Meldungen geloggt werden sollen. Dies ist bei uns die Datei /var/log/ids, welche von root im Verzeichnis /var/log/ erstellt werden sollte, z.B. mit
touch /var/log/ids
Filter
filter <identifier> { expression; };
Auch hier existiert wieder ein Identifier in unserem Beispiel ist das
"firewall_filter". Filter führen das "log routing" in syslog-ng aus.
Sobald eine Nachricht auf einen Filter passt, sagt der Filter was mit dieser
geschehen soll und wie sie weitergeleitet wird.
Es existieren folgende Filterfunktionen: facility(), level() oder priority(),
program(), host(), match(). Wobei uns nur match() interessieren soll. Per
match() ist es möglich die erhaltene Nachricht auf einen bestimmten
Ausdruck zu überprüfen. Bei uns ist dieser Ausdruck der String
"Alert!". Spätestens hier sollte klar werden wozu der Log-Prefix beim
setzten der Log Regeln im Firewall Skript gebraucht wurde.
Unser Filter "firewall_filter", wird jede erhaltene Nachricht auf den
String "Alert!" durchsuchen.
Log
log { source(source-identifier); filter(filter-identifier); destination(destination-identifier); };
Log ist dafür zuständig Source, Destination und Filter zusammenzuführen.
Alle Nachrichten die von Source "src" kommen (in unserem Beispiel /dev/log
und /proc/kmsg) und auf den Filter "firewall_filter" (in unserem
Beispiel alle Nachrichten die den String "Alert!" enthalten) passen, werden
nach Destination "d_firewall" (bei uns /var/log/ids) geschrieben.
2.3 Ausgabe mit tail
Wie bereits zu Beginn erwähnt, können jetzt die nach
/var/log/ids geschriebenen Logs unter Zunahme von tail angezeigt werden.
tail /var/log/ids würde dabei nur die letzten 10 Zeilen des Logfiles
ausgeben. Ein tail -f /var/log/ids hingegen, gibt aktuelle von syslog-ng
nach /var/log/ids geschriebenen Logs aus.
Ein Eintrag kann beispielsweise so aussehen:
Datum
Uhrzeit Hostname
Log Prefix
Nachricht
Mar 27 18:02:47
deepblack Alert! PrivPort
IN=lo OUT= MAC=****** SRC=192.168.0.1 [...]
3. EOF
Nun sind wir am Ende dieser Einführung ins Thema "Selbstbau IDS"
angekommen. Verbesserungsvorschläge und Hinweise bzw. Fehler jeglicher
Art bitte an die unten genannte Addresse.
So long....
unex
Autor: unex (www.yassp.de)
Kontakt/Verbesserungsvorschläge: unex at gmx dot de
Version: Version 1.0 - 3/2003