Seit der ersten Version habe ich mehrere Verbesserungen am Fortigate Log Parser vorgenommen. Das Python Skript ist auf Github: http://github.com/oelu/fg_log_parser/.
Eines der Hauptprobleme war die Performance. Ich habe festgestellt, dass die erste Version viel RAM benötigt um Logfiles grösser als 100MB zu parsen. Zudem dauerte es ca. 25 Minuten, bis ein 600MB Logfile komplett geparst war. In mehreren Schritten wurde die Performance optimiert. Die wichtigste Änderung dabei ist, dass der Log Parser nicht mehr die komplette Datei in den RAM liest, sondern diese Zeile für Zeile bearbeitet. So benötigt er auch bei grösseren Dateien mit einer umfangreichen Matrix nicht mehr als 10MB RAM.
Zudem verwendet die Funktion, welche eine Logzeile in
key
und value
Paare umwandelt nun nicht mehr
das Python Modul shlex
, sondern einen Regex. Damit dauert
die Bearbeitung eines 600MB Logfiles ca. 2 Minuten.
Mehrere CLI Optionen wurden angepasst oder erweitert.
-b --countbytes
:Die Option countbytes
summiert die Bytes pro Verbindung
auf.
-v --verbose
:Verbose gibt nun mehr Informationen zur Programmausführung aus. So
werden z.B. neu gefundene srcip
und dstip
Tupel ausgegeben.
-n --noipcheck
:Es wird nicht getestet, ob das srcipfield
und das
dstipfield
im Logfile vorhanden sind.
Mit neuen Log Format Optionen, kann das Log Format flexibel angepasst
werden. Es ist damit auch möglich Logfiles von anderen Herstellern zu
lesen. Voraussetzung dafür ist, dass diese ein key=value
Format aufweisen.
Im Folgenden sind die Log Format Optionen kurz beschrieben:
--srcipfield=<srcipfield>
:Feld für die Source IP Adresse.
--dstipfield=<dstipfield>
:`Feld für die Destination IP Adresse.
--dstportfield=<dstportfield>
:Feld für den Destination Port.
--protofield=<protofield>
:Feld für das Protokoll.
Wird die Option --countbytes
gewählt, müssen zusätzlich
noch die folgenden Felder angegeben werden.
--sentbytesfield=<sentbytesfield>
:Feld für die gesendeten Bytes.
--rcvdbytesfield=<rcvdbytesfield>
:Feld für die empfangenen Bytes.
Damit kann nun z.B. auch ein Iptables Log geparst werden:
$ fg_log_parser.py -f filter --srcipfield=SRC \
--dstportfield=DPT --protofield=PROTO --dstipfield=DST
Die Zuordnung der Felder aus der Logzeile wird nun über die Python
Dictionary Funktion logline.get(key)
vorgenommen und nicht
mehr über logline[key]
. Die get()
Funktion hat
den Default Rückgabewert None
. Es ist nun möglich, Dateien
ohne dstportfield
und protofield
zu parsen.
Die fehlenden Werte werden mit None
ergänzt.
Mit der Option --noipcheck
ist es theoretisch möglich
eine beliebige Datei zu parsen, und folgende Ausgabe zu erhalten:
None
None
None
None
count: Anzahl Zeilen in der Datei.
Die Hilfe Funktion wurde angepasst und um Beispiele erweitert.
» python fg_log_parser.py -h
Fortigate Log Parser
Parses a Fortigate logfile and presents a
communication matrix.
Usage: fg_log_parser.py
fg_log_parser.py (-f <logfile> |
--file <logfile>) [options]
Options:
-b --countbytes Count bytes for each
communication quartet
-h --help Show this message
-v --verbose activate verbose messages
--version Shows version information
-n --noipcheck Do not check if src and dst
ip are present
Log Format Options (case sensitive):
--srcipfield=<srcipfield> Src ip address
field [default: srcip]
--dstipfield=<dstipfield> Dst ip address
field [default: dstip]
--dstportfield=<dstportfield> Dst port field
[default: dstport]
--protofield=<protofield> Protocol field
[default: proto]
If countbytes options is set you may have to specify:
--sentbytesfield=<sentbytesfield> Field for sent bytes
[default: sentbyte]
--rcvdbytesfield=<rcvdbytesfield> Field for rcvd bytes
[default: rcvdbyte]
Examples:
Parse Fortigate Log:
fg_log_parser.py -f fg.log
Parse Iptables Log:\
$ fg_log_parser.py -f filter --srcipfield=SRC
--dstipfield=DST --dstportfield=DPT --protofield=PROTO
Parse Fortianalyzer Log:\
$ fg_log_parser.py -f faz.log --srcipfield=src --dstipfield=dst
Mit dem Doctest Modul wurden mehrere Testfälle erstellt, welche die einzelnen Funktionen und das Parsen von verschiedenen Logfiles testen.