rsyslog Server unter Ubuntu 12.04 aufbauen

Posted on Sun 06 July 2014 in ubuntu

In größeren Netzwerken mit vielen Linux-Servern, Firewalls und sonstigen Geräten oder Applikationen kommt man an einen Punkt, an dem ein Syslog-Server nahezu unerlässlich wird.

Das mag im ersten Moment nicht realistisch erscheinen. Allerdings sollte man einmal überlegen was man damit erreichen kann. Dabei darf man nicht vergessen, dass der CISO eines Tages mit Ideen daherkommt. Punkt.

  • Linux Server

Logging der Authentifizierungsversuche und Herkunft. Angriffe können im Nachhinein durch Muster festgestellt werden. Fehlgeschlagene Authentifizierungsversuche können umgehend "gemeldet" werden.

  • Mail Server

Malware, welche versendet werden sollte, kann auf Accounts zurückgeführt und entsprechende Aktionen ergriffen werden. Z.B. bei der Nutzung von Postfix in Verbindung mit ClamAV und clamsmtp.

  • Firewall

Wie beim Linux Server könnten auch hier Authentifizierungsversuche geloggt und gemeldet werden. Zusätzlich dürfte bei einem hohen Trafficaufkommen die Untersuchung der freizuschaltenden Ports und Hosts Mithilfe der Weboberfläche serh schwer sein. So zum Beispiel beim Einsatz von NetScreen Firewalls.

Voraussetzungen

In diesem Szenario wird Ubuntu 12.04 verwendet. Die Syslog-Nachrichten werden von den Clients über OpenVPN versendet, sodass keine Verschlüsselung zum Einsatz kommt. Bei Bedarf von Verschlüsselung sollte man sich das Paket rsyslog-gnutls einmal näher ansehen. Die empfangenen Syslog-Nachrichten sollen auf Muster untersucht und in verschiedenen Dateien abgelegt werden.

Grundeinrichtung

Standardmäßig verwendet Ubuntu 12.04 rsyslog, um Syslog-Nachrichten des Systems zu schreiben. Eine Installation entfällt damit.

rsyslog.conf

Zuerst sollten wir einen Blick in die Konfiguration unter /etc/rsyslog.conf werfen.

In diesem Fall soll der rsyslog-Server auf UDP-Pakete mit dem Standardport 514 lauschen:

# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

Außerdem interessant sind folgende Optionen. In diesem Fall soll die Gruppe rico Zugriff auf die Logs haben. Den Besitzer belasse ich bei syslog.

$FileOwner syslog
$FileGroup rico
$FileCreateMode 0640
$DirCreateMode 0755
$PrivDropToUser syslog
$PrivDropToGroup rico

Außerdem wird am Ende der rsyslog.conf definiert, dass auch Konfigurationsdateien auf dem Verzeichnis /etc/rsyslog.d/ verwendet werden.

Zusätzliche Konfigurationsdateien

Im Ordner /etc/rsyslog.d/ sollten sich nur wenige Dateien befinden:

20-ufw.conf 50-default.conf postfix.conf

In der 20-ufw.conf findet man schon den Grundbaustein, um später eigene Filter zu schreiben:

:msg,contains,"[UFW " /var/log/ufw.log

Da ich iptables nutze und ufw deinstalliert habe entferne ich die Datei.

Die postfix.conf ist für uns nicht interessant.

Selbstverständlich sollte man einen Blick in die 50-default.conf werfen. Änderungen sind allerdings nicht notwendig.

Log-Verzeichnis und Firewall-Regel

Um zu erreichen, dass die Logs auf unserem Server sauber voneinander getrennt sind, erstellt man eine zusätzliche Konfigurationsdatei namens /etc/rsyslog.d/01-loglocation.conf in /etc/rsyslog.d/. Die Pfadangabe muss auf die eigenen Bedürfnisse angepasst werden. Der Ordner muss vorhanden sein und die Rechte aus der rsyslog.conf aufweisen.

Was der Inhalt macht? Im Grundpfad für die Logfiles, in diesem Fall /mnt/data/syslog/, wird für jeden Host ein Unterverzeichnis erstellt. Die Dateinamen beinhalten dann den Hostnamen_Jahr-Monat-Tag.log.

# Logfile for each host in a separate folder with date & time
$template DynFile,"/mnt/data/syslog/%HOSTNAME%/%HOSTNAME%_%$YEAR%-%$MONTH%-%$DAY%.log"
*.* -?DynFile

Außerdem sollte iptables den eingehenden Traffic zulassen. In meinem Fall auf dem Interface tap0

iptables -A INPUT -i tap0 -m state --state NEW -p udp --dport 514 -j ACCEPT

Anschließend kann man den rsyslog-Dienst neustarten und den ersten Client auf dem System loggen lassen.

Ersten Client verbinden

Auf dem Client sollte das Verzeichnis /var/spool/rsyslog/ existieren und die Rechte aus der rsyslog.conf (syslog:adm) besitzen.

Sind diese Voraussetzungen erfüllt kann man die Datei /etc/rsyslog.d/remote.conf erstellen. Die IP-Adresse des Zielservers muss angepasst werden.

$WorkDirectory /var/spool/rsyslog # default location for work (spool) files
$ActionQueueType LinkedList # use asynchronous processing
$ActionQueueFileName srvrfwd # set file name, also enables disk mode
$ActionResumeRetryCount -1 # infinite retries on insert failure
$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down
*.* @10.20.30.1

Auf dem Client kann man nun den rsyslog-Dienst ebenfalls neustarten.

Dabei sollte man allerdings auf die Syslog-Aufgaben achten, da man möglicherweise auf diesen Fehler stößt:

Jul 6 14:00:51 server rsyslogd-2039: Could no open output pipe '/dev/xconsole': No such file or directory [try http://www.rsyslog.com/e/2039 ]/

Bug oder Feature?

An dieser Stelle ist es Zeit sich den Inhalt des syslog-Ordners einmal genauer anzusehen:

# ls -hal /mnt/data/syslog/
total 24K
drwxr-xr-x 5 syslog rico 4.0K Jul 6 14:01 .
drwxr-xr-x 10 root root 4.0K Jul 6 13:34 ..
drwxr-xr-x 2 syslog rico 4.0K Jul 6 13:59 10.20.30.1
-rw-r----- 1 syslog rico 48 Jul 6 13:59 _2014-07-06.log
drwxr-xr-x 2 syslog rico 4.0K Jul 6 13:50 erinnerungsfragmente
drwxr-xr-x 2 syslog rico 4.0K Jul 6 14:01 server

In der Datei _2014-07-06.log landen Nachrichten die keinem Host zugeordnet werden können. Beispielsweise, wenn rsyslog last message repeated 2 times in das Log schreibt. Da mir bisher kein Workaround hierfür bekannt ist, lasse ich diese Dateien über einen cronjob löschen.

Der Ordner 10.20.30.1 zeigt, dass der Hostname nicht aufgelöst werden konnte. Abhilfe schafft, falls keine DNS Auflösung sichergestellt werden kann, ein Eintrag in der hosts-Datei.

Erweiterte Filter

Der Syslog Server verrichtet seinen Dienst und alle Clients können loggen.

Allerdings besteht der Bedarf bestimmte Aktionen in zusätzlichen Dateien loggen zu lassen, um sicherzustellen, dass diese Informationen schnell aufzufinden sind. Zusätzlich sollen für bestimmte Ereignisse Emails versendet werden. Die nachfolgenden Konfigurationsdateien müssen alle im Ordner /etc/rsyslog.d/ erstellt werden.

Die folgenden rsyslog-Konfigurationen für den Server sind beliebig erweiterbar. Informationen dazu finden man unter Anderen auf der rsyslog Website.

Email-Benachrichtigungen

Damit Email-Benachrichtigungen versendet werden können kann man diese ganz allgemein definieren.

Der Empfänger wird in den weiteren Filtern definiert und nicht an dieser Stelle, um ggf. verschiedene Teams bei verschiedenen Events zu benachrichtigen. Die zusätzlichen Mail Templates können sowohl zentral als auch in den Filtern definiert werden.

Leider unterstützt rsyslog keine Mail Server Authentication, sodass sichergestellt sein muss, dass das Mail Relay die Emails auch ohne Authentifizierung absendet.

Konfigurationsdatei: 02-mail.conf

# 02-mail.conf - rsyslog Mail configuration
# ---------------------------------------------------------------------------------------------
# Changelog:
#
# 6-Jul-2014 - Initial version / Rico Ullmann
# ---------------------------------------------------------------------------------------------
# Load the needed Module
$ModLoad ommail
# Define the smtp server, from snd to address
$ActionMailSMTPServer 127.0.0.1
# SMTP Server Port to use
$ActionMailSMTPPort 25
# Define the senders address
$ActionMailFrom rsyslog@example.org
# The standard mail subject
$template mailSubject,"rsyslog notification for %hostname%"
# Standard mail template
$template mailBody,"Alert sent from rsyslog-Server\r\----------------------------------------\r\nmsg='%msg%'"
# Another mail template
$template mailBodyWhatever,"Whatever alert sent from rsyslog-Server\r\----------------------------------------\r\nmsg='%msg%'\r\----------------------------------------\r\This is another template."
# Let's use the mail subject template as mail subject. ;)
$ActionMailSubject mailSubject
# Define how often a mail may arrive if an event reoccurs in seconds.
$ActionExecOnlyOnceEveryInterval 60

UFW Logs in einer separaten Datei

Um noch einmal zurück zu dem UFW Log zu kommen folgt eine Konfiguration, welche UFW Logs zusätzlich in einer zweite Datei schreibt.

Konfigurationsdatei: 20-ufw.conf

# 20-ufw.conf - rsyslog ufw rule
# ---------------------------------------------------------------------------------------------
# Changelog:
#
# 6-Jul-2014 - Initial version / Rico Ullmann
# ---------------------------------------------------------------------------------------------
# Define a template for the Logfile
$template UfwLog,"/mnt/data/syslog/%HOSTNAME%/ufw_%$YEAR%-%$MONTH%-%$DAY%.log"
# Every message that contains "[UFW " will be logges to a separate file per host
:msg,contains,"[UFW " -?UfwLog

SSH Logs und Benachrichtigungen

Welcher Bösewicht möchte sich denn dort per SSH einloggen? Natürlich verrät uns das auch Logwatch, aber wer möchte schon täglich eine Email von jedem Server erhalten?

Beim Logging der Events verweist man auf das zuvor erstellte Template SshdLog: then -?SshdLog.

Am Ende der Konfigurationsdatei findet sich Folgendes: then :ommail:;mailBody. mailBody ist das Template aus der zuvor erstellten 02-mail.conf. Statt mailBody kann man also auch mailBodyWhatever verwenden.

Konfigurationsdatei: 10-sshdlog.conf

# 10-sshdlog.conf - rsyslog sshd logging
# Log all ssh security alerts to a separate file and report a security breach via email
# ---------------------------------------------------------------------------------------------
# Changelog:
#
# 6-Jul-2014 - Initial version / Rico Ullmann
# ---------------------------------------------------------------------------------------------
$ActionMailTo someone@example.org
# First we create a template for the log location
$template SshdLog,"/mnt/data/syslog/%HOSTNAME%/sshd_%$YEAR%-%$MONTH%-%$DAY%.log"
# Followed by the actual logging of all sshd events
if $programname == 'sshd' then -?SshdLog
# Now send an email if an event contains a possible security breach
if $programname == 'sshd' and ($msg contains 'Received disconnect from' or $msg contains 'Failed' or $msg contains 'Invalid user' or $msg contains 'Did not receive identification string' or $msg contains 'Permission denied' or $msg contains 'ROOT LOGIN REFUSED') and not ($msg contains 'disconnected by user') then :ommail:;mailBody

Juniper ScreenOS

Nachfolgend ein kleiner Beispiel für eine Juniper NetScreen mit ScreenOS.

Diese Events sollen nicht nur an someone@example.org gehen, sondern auch noch an das Firewall Team. Das erriecht man unter someoneelse@example.org.

Konfigurationsdatei: 15-screenos.conf

# 15-screenosauth.conf - rsyslog Juniper ScreenOS auth logging
# Log all auth events to a separate file and report a security breach via email
# ---------------------------------------------------------------------------------------------
# Changelog:
#
# 6-Jul-2014 - Initial version / Rico Ullmann
# ---------------------------------------------------------------------------------------------
$ActionMailTo someone@example.org
$ActionMailTo someoneelse@example.org
# First we create a template for the log location
$template ScreenosAuth,"/mnt/data/syslog/%HOSTNAME%/auth_%$YEAR%-%$MONTH%-%$DAY%.log"
# Followed by the actual logging of all Netscreen Auth events
if ($msg contains 'has been accepted via the Radius server' or $msg contains 'has been rejected via the Radius server' or $msg contains 'login attempt for Web(https) management' or $msg contains 'XAuth login was passed' or $msg contains 'logged in for Web' or $msg contains 'SSH: Password authentication successful' or $msg contains 'has logged on' or $msg contains 'has logged out' or $msg contains '[Root]system-warning' or $msg contains '[Root]system-critical') then -?ScreenosAuth
# Now send an email if an event contains a possible security breach
if ($msg contains 'has been rejected via the Radius server' or $msg contains 'failed.' or $msg contains '[Root]system-critical') and not ($msg contains 'Connection refused by the DNS server' or $msg contains 'fails to authenticate the packet') then :ommail:;mailBody

Postfix

Wie oben bereits angesprochen kann man Postfix mit ClamAV und clamsmtp verbinden, um Emails auf Malware zu untersuchen.

Darüber sollen ebenfalls Informatioinen versendet werden. Allerdings nicht, wenn ein bestimmter Hostname in der Nachricht vorhanden ist: and not ($msg contains 'badhostname')

Konfigurationsdatei: 13-postfix.conf

# 13-postfix.conf - rsyslog Postfix logging
# Log all postfix events to a separate file and report rejected and infected messages via email
# ---------------------------------------------------------------------------------------------
# Changelog:
#
# 6-Jul-2014 - Initial version / Rico Ullmann
# ---------------------------------------------------------------------------------------------
$ActionMailTo someone@example.org
# First we create a template for the log location
$template PostfixLog,"/mnt/data/syslog/%HOSTNAME%/postfix_%$YEAR%-%$MONTH%-%$DAY%.log"
# Followed by the actual logging of all Postfix events
if $programname == 'postfix' then -?PostfixLog
# Now send an email if a message is rejected or infected by malware
if ($msg contains 'reject:' or $msg contains '250 Virus Detected') and not ($msg contains 'badhostname') then :ommail:;mailBody

Hinweise und Sonstiges

Das Sammeln von Logdateien benötigt ggf. sehr viel Speicher. Die Logs sollten daher in regelmäßigen Abständen durch ein Script komprimiert werden, wenn diese älter als x Tage sind.

Ob ein Client tatsächlich Logs schreibt sollte ebenfalls über ein Script überprüft werden.

Niemals sollte der Syslog-Server die remote.conf erhalten. Rsyslog sendet in diesem Fall alle Nachrichten immer und immer wieder an sich selbst!

Ein Blockwart Bundle folgt noch.

Ansonsten wünsche ich euch viel Spaß mit eurem Syslog-Server und beim Bauen von Filtern.