FW1 Log Dateien: Sieben Millionen Zeilen pro Tag

FW1 Log Dateien

Sieben Millionen Zeilen pro Tag

Rocco Gagliardi
von Rocco Gagliardi
Lesezeit: 12 Minuten

Es gibt eine Vielzahl von Log Analysis Tools die zum downloaden, auspacken und ausführen da sind. Jedes dieser Tools kommt mit seinen eigenen Features und seinem benutzerfreundlichen Interface. In speziellen Fällen kann es aber effizienter sein, Daten mit einem selbst programmierten Tool zu verarbeiten. Dies, weil Sie so ein besseres Verständnis der Daten und die Fähigkeit, sehr spezifischen Output zu generieren, erhalten.

Es ist ziemlich einfach, mit grossen Logfiles zurecht zu kommen. Im folgenden werden wir uns ansehen, wie effizient Informationen aus einer exportierten Firewall-1-Logfile extrahiert werden können und wie die Datei nach unseren Wünschen formatiert werden kann.

Ausmass und Anforderungen

Im vergangenen Jahr haben wir an einem Projekt gearbeitet, das produktive Server vor internen Benutzern schützen sollte. Dabei haben wir das interne Netzwerk in eine Vielzahl verschiedener Teile aufgesplittet und den Datenfluss zwischen diesen Teilen geregelt. Der Plan sah vor, eine Open Firewall zu implementieren, den ganzen Traffic in einer Logfile aufzuzeichenn (das entspricht etwa 6 bis 8 Millionen Zeilen pro Tag) um die Verbindungen im Netzwerk zu finden und darauf basierend zu entscheiden, welche Verbindungen benötigt werden und welche nicht. Wenn sie benötigt werden, dann implementieren wir eine Allow-Regel. Am Ende des Projekt war es dann lediglich das Ändern einer letzten Regel von Allow zu Drop um alle nicht benötigten Verbindungen zu blockieren.

Das Hauptproblem war es, automatisch die analysierten Verbindungen und die Entscheidungen über deren Notwendigkeit, die in einem externen Prozess gefällt wurden, verfolgen zu können. Dies über einen Zeitraum von sechs Monaten hinweg. Darum haben wir entschieden, einige Tools zur Analyse von Firewall-Logs und eine Datenbank zu entwickeln, welche die implementierten Regeln verfolgt und synchronisiert.

Wir stellten folgende Anforderungen an unser Tool:

Ablauf

Der Ablauf der Analyse umfasst folgende Schritte:

  1. Export der Logfiles des vergangenen Tag
  2. Extraktion der Verbindungen: Action-Source-Destination-Service
  3. Import in die Datenbank
  4. Die Datenbank gleicht die Sequenzen mit den bereits gespeicherten am. Wenn diese bereits existieren, werden sie einem Update unterzogen und die Prioritäten angepasst (falls die Entscheidung fehlt); wenn sie nicht existieren, wird ein neuer Fall erstellt, der auf einer Prioritätsbasis untersucht wird.
  5. Erstellung eines täglichen Reports des Zwischenstandes aller Fälle.

Das Logfile

Das Firewall-1-Log ist im Binärformat in einem geschützten Speicher abegelegt. Ein priviligierter Account ist notwendig um das Checkpoint Log Export Utility auf dem Managemen/Log Server auszuführen. Im Normalfall verfügt ein Firewall Engineer nicht über solche Zugriffsrechte, denn in der Regel hat er nur normale Benutzerrechte und Smart Read Access. Damit ist ezwar immer noch möglich, das Logfile vom SmartConsole Tracker zu exportieren, doch das benötigt Zeit und generiert eine grosse Textfile. Dennoch ist das ein guter Kompromiss zwischen Sicherheit und Benutzbarkeit.

Interpretation des Logfiles

Nach dem Export haben wir auf einmal jede Menge Zeilen auszuwerten. Checkpoint Tools exportieren standardmässig folgende Informationen:

num;date;time;orig;type;action;alert;i/f_name;i/f_dir;product;src;dst;proto;rule;service;s_port;icmp-type;icmp-code;message_info;xlatesrc;xlatedst;NAT_rulenum;NAT_addtnl_rulenum;xlatedport;xlatesport;th_flags;Attack Info;attack

Wir nutzen die Programmiersprache Perl aus vielen Gründen aber hauptsächlich deshalb, weil sie in den meisten Systemen standardmässig verfügbar ist. Selbst wenn es möglich wäre, einen CSV-Parser zu verwenden, entschieden wir, dass es einfacher ist, eine Datei zu analysieren, die mit einem “;” getrennt ist. Die Performance ist mit einem normalen Computer nicht wirklich ein Problem.

Das Herz der Extraktion und der Analyse liegt in den folgenden paar Zeilen Code:

038 my @counts = ('rule','src','dst','proto','service');
...
129 while ( $ln=INPUT> ) {
130    chomp;
131    @hdr = split (/;/,$ln);
132    for ($i=0; $i<@hdr; $i++) {
133       chomp @hdr[$i];
134       $header->{@hdr[$i]}=$i;
135    }
136    while ( $line=INPUT> ) {
137       $linecounts++;
...
139       chomp;
140       @content = split (/;/, $line);
...
145       foreach $counter ( @counts ) {
146          $stats->{$content[$header->{action}]}->{$counter}->{$content[$header->{$counter}]}++;
147       }
148       $stats->{$content[$header->{action}]}->{cnn}->{$content[$header->{src}]}->{$content[$header->{dst}]}->{$content[$header->{service}]}++;
149       $date = $content[$header->{date}];
150    }
151    last
152 }</pre>

Im Grunde genommen lesen wir hier eine Zeile aus und teilen sie mit dem “;” in Kolonnen auf und erhalten so ein Array von Werten. Nun können wir jede benötigte Information in einer relationären Form speichern, indem wir ein Hash ($stats) verwenden. Das ist eine sehr flexible und starke Funktion in Perl.

Zeilen Beschreibung
131-135 Um das Tool benutzerfreundlich zu machen (die Sequenz der Informationen kann sich von Version zu Version unterscheiden) bevorzugen wir es, die Elemente nicht nach Position im Array zu codieren, sondern den Header separat auszulesen und so die Position der Information mittels Kolonnennamen zu lokalisieren.
145-147 Um einfache Statistiken zu schaffen, fügen wir einen Schlüssel zu jeder Aktion hinzu, in dem wir Zähler, Zähler-Wert und erhöhen diesen um 1 für jede gefundene Instanz der Sequenz.
148 Für die Statistik der Verbindungen fügen wir jeder Aktion einen Schlüssel hinzu, der source-ip, destination-ip und Service ausliest. Zudem erhöhen den Wert um 1 für jede gefundene Instanz der Sequenz.

Mit nur zwei Zeilen Code erhalten wir nach erfolgreichem Parsing des Logfiles ein Hash mit all unseren Statistiken unter Berücksichtigung von rules/sources/destination/protocol/services und einer Verkehrsmatrix, die aufzeigt, wer mit wem spricht, in unserem Speicher.

print Dumper($stats)
$VAR1 = {
   'accept' => {
      'proto' => {
         'tcp' => 4
      },
      'src' => {
         '192.168.2.1' => 3,
         '192.168.3.1' => 1
      },
      'rule' => {
         '1' => 4
      },
      'service' => {
         'http' => 3,
         'https' => 1
      },
      'dst' => {
         '192.168.20.1' => 3,
         '192.168.10.1' => 1
      },
      'cnn' => {
         '192.168.2.1' => {
            '192.168.20.1' => {
               'http' => 3
            }
         },
         '192.168.3.1' => {
            '192.168.10.1' => {
               'https' => 1
            }
         }
      }                         
   }
};

Generierung des Outputs

Wie in den Spezifikationen festgelegt, ist es nötig eine Tabelle mit den täglichen Verbindungen zu generieren. Das ist einfach. Im Grunde wiederholen wir die Hash(es) und lesen Resultate aus:

167 %actions = %$stats;
168 foreach $action (keys %actions) {
169   print OUTPUT "-"x20 ."\n"." Action: $action"."\n"."+"."-"x19 ."\n";
170   foreach $counter ( @counts ) {
171     foreach $count ($stats->{$action}->{$counter}) {
172       %hs = %$count;
173       print OUTPUT "+- $action - $counter" ."\n";
174       foreach $k ( (sort { $hs{$b} <=> $hs{$a} } keys %hs) ) {
175         printf(OUTPUT ("%6s => %s\n", $hs{$k}, $k)) if $hs{$k} > $filter;
176       }
177     }
178   }
179 }

Das Resultat im Textformat:

--------------------
 Action: accept
+-------------------
+- accept - rule
     4 => 1
+- accept - src
     3 => 192.168.2.1
     1 => 192.168.3.1
+- accept - dst
     3 => 192.168.20.1
     1 => 192.168.10.1
+- accept - proto
     4 => tcp
+- accept - service
     3 => http
     1 => https

Das CSV-File für den Export:

date,rulenr,accept,drop
20121128,1,4,0
date,rulenr,src,dst,proto,service,accept,drop
20121128,1,192.168.2.1,192.168.20.1,http,3,0
...

Andere Funktionen können und sind hinzugefügt worden, damit die Effizienz des Tools erhöht wird. Aber mit diesen Funktionen können Sie mehrere Millionen Zeilen Code lesen, interpretieren und zusammenfassen.

Nutzung im Alltag

Die tägliche Extraktion von fast sieben Millionen Zeilen Code nimmt pro Tag etwa eine Stunde in Anspruch (inklusive Export, Transfer und Parsing). Das Parsing selbst nimmt etwa 20 Minuten in Anspruch.

Sobald das CSV-File generiert worden ist, wurde es in eine Microsoft Access Datenbank importiert, die wir zur Speicherung (etwa 1 GB Grösse am Ende des Projekts) verwenden. Mittels einer separaten Front-End Access-Datenbank war es möglich, die Information zu analysieren, sie nachzuverfolgen und nötige Daten in einem Report zusammenzufassen.

Fazit

Sobald wir klar und genau definiert haben, welche Informationen wir woher in welcher Form benötigen, ist die Analyse der Daten einfacher als sie zunächst scheint. Das Handling grosser Mengen Daten ist mit heutiger Rechenleistung von Computern und einigen Zeilen Code ebenfalls keine grosse Sache. Manchmal ist es besser, technologisch einfache Mechanismen zu verwenden, die aber sehr flexibel und in einem existenten Prozess eingesetzt werden können als einen Prozess an ein gutes Tool anzupassen. Und: Hashes sind grossartig!

Quellen

Über den Autor

Rocco Gagliardi

Rocco Gagliardi ist seit den 1980er Jahren im Bereich der Informationstechnologie tätig. In den 1990er Jahren hat er sich ganz der Informationssicherheit verschrieben. Die Schwerpunkte seiner Arbeit liegen im Bereich Security Frameworks, Routing, Firewalling und Log Management.

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Übergang zu OpenSearch

Übergang zu OpenSearch

Rocco Gagliardi

Graylog v5

Graylog v5

Rocco Gagliardi

auditd

auditd

Rocco Gagliardi

Security Frameworks

Security Frameworks

Rocco Gagliardi

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv