In meinem letzten Blogartikel habe ich erläutert, wieso ich den Elastic Stack für die beste Variante halte, komfortabel, schnell und mit vielen Möglichkeiten zu analysieren. Jetzt möchte ich euch erklären, wie man das am besten einrichtet.

Check Point hat zur Anbindung von Drittanbietersoftweare das sogenannte OPSEC Framework geschaffen. Mittels dessen LEA (Log Export API) Protokoll können Logmeldungen von Check Point Management Servern ausgelesen werden. Da Logstash leider keine native Unterstützung für LEA mitbringt, sind weitere Tools, z.B. fw1-loggrabber notwendig. Die Konfiguration ist recht komplex.

Eine andere Alternative ist, Logs per Syslog an den Logstash Server zu senden. In den Check Point Knowledge Base Artikeln SK87560 (R77.30) und SK115392 (andere R77 Versionen und R80 bzw. R80.10) ist beschrieben, wie man das konfiguriert. Während bei R77.30 die Konfiguration recht simpel ist, wird bei den anderen R77 bzw. R80 Versionen ebenfalls ein weiteres Tool mit komplexer Konfiguration benötigt. Dazu kommt das grundsätzliche Problem, dass die Logmeldungen mit Syslog unverschlüsselt vom Check Point Management Server an den Logstash Server versendet werden, was es einem Angreifer möglich macht, diese mit tcpdump oder ähnlichen Tools mitzulesen.

Ich gehe daher einen anderen Weg, der mit allen CheckPoint Versionen funktioniert und einen SSH Tunnel nutzt, um die Logmeldungen sicher zu übertragen.

Logs an den Logstash Server senden

Auf dem Check Point Management Server müssen die Logs in Echtzeit an den Logstash Server weitergeleitet werden.
Um das zu tun, loggt man sich im Expert Mode auf dem Check Point Management bzw. Log Server ein und fügt am Ende der Datei /etc/init.d/cpboot diese Zeile ein:

/etc/init.d/cpboot
while true; do fw log -f -t -p -n -l 2>/dev/null | ssh -T cplog@logstash.elk.local; sleep 5; done &

Der Hostname logstash.elk.local ist durch den Hostnamen des Logstash Servers bzw. einer Load Balancer VIP zu setzen.
Danach startet man den Server neu. Das soeben editierte Skript wird beim Systemstart ausgeführt und die neu eingefügte Zeile im Hintergrund gestartet.

Die Zeile startet eine Endlosschleife. Diese ist dafür gedacht, beim Ausfall der Netzwerkverbindung zum Logstash Server oder bei einem Reboot desselben das Logging automatisch wieder zu „reparieren“. Der Befehl fw log gibt mit den oben aufgeführten Optionen alle Check Point Logmeldungen aus und deaktiviert das standardmäßig aktivierte Mapping von IPs und Ports zu Check Point Objektnamen. Die Ausgabe des fw log Kommandos wird unverändert durch SSH gepiped.

Als nächstes führt man den folgenden Befehl aus:

ssh-keygen

Das erzeugt einen SSH Private und Public Key für den Benutzer admin.
Den Public Key in /home/admin/.ssh/id_rsa.pub kopiert man in die Zwischenablage, da er benötigt wird, um den SSH Zugriff auf dem Logstash Server zu erlauben.
Mehr muss auf dem Check Point Management Server nicht konfiguriert werden.

Logs vom Check Point Management Server empfangen

Auf dem Logstash Server richtet man nun einen neuen Benutzer cplog ein:

sudo useradd -m cplog

Dann wechselt man in den Kontext des neuen Benutzers und in sein Home-Verzeichnis:

sudo su cplog
cd /home/cplog

Als Nächstes erzeugt man das SSH-Verzeichnis des Benutzers:

mkdir .ssh
chmod 700 .ssh

Nun wird der admin Benutzer des Check Point Management Servers berechtigt, sich ohne Passwort per SSH einzuloggen:

vi .ssh/authorized_keys

In die Datei fügt man den SSH Public Key ein, den man auf dem Check Point Management Server in die Zwischenablage kopiert hat und speichert die Datei.
Zum Empfang der Logmeldungen und zur Weiterleitung an Logstash wird ein Skript benötigt. Dies editiert man:

touch cplog.sh
chmod 755 cplog.sh
vi cplog.sh

In das Skript fügt man folgenden Code ein und speichert die Datei:

/home/cplog/cplog.sh
#!/bin/sh
/bin/nc 127.0.0.1 51400

Nun wird der Benutzer fertig konfiguriert:

sudo passwd -d cplog
sudo usermod -s /home/cplog/cplog.sh cplog

Das Weiterleitungs-Skript benötigt das Tool Netcat. Falls noch nicht vorhanden, wird es unter Debian installiert mit:

sudo apt-get install netcat-openbsd

Jetzt sollte sich der Check Point Management Server bereits verbinden. Das kann man überprüfen mit:

user@logstash:~$ sudo ps aux | grep /bin/nc
cplog    32152  0.0  0.0   9216   824 ?        S    16:00   0:00 /bin/nc 127.0.0.1 51400

Als Nächstes muss man nun einen Logstash Input konfigurieren. Hierzu legt man im Config Verzeichnis der Logstash Installation die Datei input_checkpoint.conf an:

input_checkpoint.conf
input {
    tcp {
        type => "checkpoint_fwlog"
        host => "127.0.0.1"
        port => 51400
        codec => multiline {
            pattern => "\n"
            what => "next"
        }
    }
}

Da durch die Art der Konfiguration mehrere Logmeldungen in einem TCP Paket transportiert werden, ist der Multiline Codec notwendig. Er splittet Nachrichten am Zeilenende auf und fügt sie auch über Paketgrenzen wieder zusammen.
Nun wird noch ein Filter benötigt. Hierzu legt man im Config Verzeichnis der Logstash Installation die Datei filter_checkpoint.conf an:

filter_checkpoint.conf
filter {
 
    if [type] == "checkpoint_fwlog" {
 
        ## Drop empty log messages caused by the multiline codec
        if [message] == "" {
            drop {
            }
        }
     
        ## Tag all messages
        mutate {
            add_tag => [
                "firewall",
                "checkpoint"
            ]
        }
 
        ## Tag CP firewall messages
        if [message] =~ /product: VPN\-1/ {
            mutate {
                add_tag => [
                    "checkpoint_firewall"
                ]
            }
        }
 
        ## Tag CP syslog messages
        if [message] =~ /product: Syslog/ {
            mutate {
                add_tag => [
                    "checkpoint_syslog"
                ]
            }
        }
 
        ## Drop CP firewall rule hit counter update messages
        if "checkpoint_firewall" in [tags] and [message] =~ /first_hit_time/ {
            drop {
            }
        }
 
        ## Parse CP firewall messages
        if "checkpoint_firewall" in [tags] {
            ## Extract all fields
            grok {
                patterns_dir => [
                    "/etc/logstash/indexer-prod/patterns"
                ]
                match => [
                    "message", "%{CHECKPOINT_FIREWALL}"
                ]
            }
        }
 
        ## Parse CP syslog messages
        if "checkpoint_syslog" in [tags] {
            ## Extract all fields
            grok {
                patterns_dir => [
                    "/etc/logstash/indexer-prod/patterns"
                ]
                match => [
                    "message", "%{CHECKPOINT_SYSLOG}"
                ]
            }
        }
 
        ## Update the host field for messages received from the CP management server
        if [checkpoint_host] {
            mutate {
                replace => {
                    "host" => "%{checkpoint_host}"
                }
            }
        }
 
        ## Parse the CP date field
        date {
            match => [
                "checkpoint_timestamp",
                "ddMMMyyyy HH:mm:ss",
                "ddMMMyyyy  H:mm:ss"
            ]
        }
 
        ## Extract and prefix fields from the message
        kv {
            source => "checkpoint_tokens"
            prefix => "checkpoint_"
            field_split => ";"
            trim_key => " "
            remove_char_key => " "
            transform_key => "lowercase"
            value_split => ":"
            trim_value => " "
        }
 
        ## Normalize field names
        mutate {
            rename => {
                "checkpoint_src" => "src_ip"
                "checkpoint_s_port" => "src_port"
                "checkpoint_dst" => "dst_ip"
                "checkpoint_service" => "dst_port"
                "checkpoint_proto" => "ip_protocol"
                "checkpoint_syslog_severity" => "severity_label"
            }
        }
 
        ## Tag accepted connections
        if [firewall_action] == "accept" {
            mutate {
                add_tag => [
                    "firewall_accept"
                ]
            }
        }
        ## Tag dropped connections
        if [firewall_action] == "drop" or [firewall_action] == "reject" {
            mutate {
                add_tag => [
                    "firewall_drop"
                ]
            }
        }
        ## Tag implied rules
        if [checkpoint_message_info] == "Implied rule" {
            mutate {
                add_tag => [
                    "firewall_implied_rule"
                ]
            }
        }
        ## Tag address spoofing messages
        if [checkpoint_message_info] == "Address spoofing" {
            mutate {
                add_tag => [
                    "address_spoofing"
                ]
            }
        }
        ## Tag NATted connections
        if [checkpoint_nat_rulenum] and [checkpoint_nat_rulenum] != "0" {
            mutate {
                add_tag => [
                    "nat"
                ]
            }
        }
 
    }
 
}

Zu beachten ist, dass in der Datei mehrfach das Pattern-Verzeichnis mit patterns_dir angegeben wird. Der Wert muss natürlich auf die konkrete Installation angepasst werden.
Als letzten Schritt muss noch die Pattern-Datei angelegt werden. Hierzu erstellt man im Pattern-Verzeichnis die Datei checkpoint.grok mit diesem Inhalt:

checkpoint.grok
CHECKPOINT_FIREWALL %{CHECKPOINT_TIMESTAMP:checkpoint_timestamp}%{SPACE}%{CHECKPOINT_FIREWALL_ACTION:firewall_action}%{SPACE}%{IPV4:checkpoint_host}%{SPACE}%{CHECKPOINT_FIREWALL_INTERFACE}%{SPACE}%{GREEDYDATA:checkpoint_tokens}
CHECKPOINT_FIREWALL_ACTION (accept|drop|reject)
CHECKPOINT_FIREWALL_INTERFACE %{CHECKPOINT_FIREWALL_SRC_INTERFACE}|%{CHECKPOINT_FIREWALL_DST_INTERFACE}
CHECKPOINT_FIREWALL_SRC_INTERFACE >%{INTERFACE_NAME:src_interface}
CHECKPOINT_FIREWALL_DST_INTERFACE <%{INTERFACE_NAME:dst_interface}
 
CHECKPOINT_SYSLOG %{CHECKPOINT_TIMESTAMP:checkpoint_timestamp}%{SPACE}%{IPV4:checkpoint_host}%{SPACE}>%{SPACE}default_device_message:%{SPACE}%{DATA:checkpoint_syslog_message};%{SPACE}facility:%{SPACE}%{DATA:checkpoint_facility};%{SPACE}%{GREEDYDATA:checkpoint_tokens}
 
CHECKPOINT_MONTH (?:[Jj]an(?:uary|uar)?|[Ff]eb(?:ruary|ruar)?|[Mm](?:a|ä)?r(?:ch|z)?|[Aa]pr(?:il)?|[Mm]a(?:y|i)?|[Jj]un(?:e|i)?|[Jj]ul(?:y)?|[Aa]ug(?:ust)?|[Ss]ep(?:tember)?|[Oo](?:c|k)?t(?:ober)?|[Nn]ov(?:ember)?|[Dd]e(?:c|z)(?:ember)?)
CHECKPOINT_TIMESTAMP %{MONTHDAY}%{CHECKPOINT_MONTH}%{YEAR}%{SPACE}%{TIME}
 
CHECKPOINT_SYSLOG ^<%{POSINT:syslog_pri}>{GREEDYDATA:checkpoint_syslog_message}

Als letzten Schritt muss man nur noch die Logstash Instanz(en) neu starten.

Logeinträge mit Kibana analysieren

Nachdem die vorherigen Schritte abgeschlossen wurden, sollten in Kibana nun Check Point Logmeldungen erscheinen:

Mit dem Filter tags: checkpoint_firewall AND tags: firewall_accept sollte man dabei alle akzeptierten Verbindungen über die Check Point Firewalls (die gelogged werden) sehen.
Nun kann man damit beginnen, sich spezielle Filter zu bauen und ggf. mit Visualisierungen weiter zu analysieren.

Wie man mit ELK Check Point Regelwerke einfach konsolidieren / aufräumen kann, erkläre ich im nächsten Blog Post.

Florian Wiethoff

Florian Wiethoff

CEO

Der Beweis das Schwaben auch hochdeutsch können liefert der Co-Gründer von Braintower jeden Tag aufs Neue. Wenn nicht auf der Suche nach unassignten Jira-Tasks, frönt dieser Code Enthusiast einer unnatürlichen Liebe für alles Digitale. Träumt bestimmt von elektrischen Schafen und würde ganz sicher auch Kobayashi Maru bestehen. Für Braintower bloggt er über IOT, SMS Gateway und Next Generation Technologien.

Gefällt dir der Artikel? Bitte teile ihn!
Share on Facebook
Facebook
0Share on LinkedIn
Linkedin
Email this to someone
email
Tweet about this on Twitter
Twitter