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:
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:
#!/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 {
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 {
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_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_accep
t 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
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.
RIP
kein Teil 3? Schade 🙂