Diese Lösung wird von mir bevorzugt. Sie verwendet `auditd` zur Erfassung der Befehle, ein eigenes Formatter-Skript zum Zusammenführen und Aufbereiten der Audit-Datensätze sowie `rsyslogd` zum Schreiben der fertigen Meldung nach `/var/log/syslog`.
Die übliche Standardlösung leitet die Audit-Meldungen lediglich weiter und schreibt sie beispielsweise nach `/var/log/user-audit.log`. Dort stehen die einzelnen Audit-Datensätze (`SYSCALL`, `EXECVE` und `EOE`) jedoch getrennt und im technischen Rohformat. Ein einzelnes Ereignis verteilt sich dadurch auf mehrere schwer lesbare Logzeilen; Username und Befehlsargumente sind nicht übersichtlich in einer Meldung zusammengefasst.
Die Datei kann beispielsweise mit `ausearch` ausgewertet werden:
sudo ausearch -k user_commands
Diese Standardlösung ist für die nachträgliche technische Analyse geeignet, erzeugt aber keine kompakte Meldung der Form „Zeit, eingeloggter Benutzer, ausführender Benutzer, Befehl“. Deshalb wird in diesem Beitrag die oben beschriebene Formatter-Lösung bevorzugt.
Diese Konfiguration protokolliert ausgeführte Befehle mit folgenden Informationen:
Der Datenfluss ist:
auditd -> Audit-Formatter -> rsyslogd -> /var/log/syslog
Hinweis: Eine reine rsyslogd-Regel kann die getrennten Audit-Datensätze (SYSCALL und EXECVE) nicht zuverlässig zu einem vollständigen Ereignis zusammenführen. Diese Aufgabe übernimmt der Formatter. rsyslogd schreibt anschließend die fertige Meldung in die Syslog-Datei.
Debian/Ubuntu:
sudo apt update sudo apt install auditd audispd-plugins rsyslog
Das Formatter-Skript aus dem Projekt ist:
audit-format-syslog.py
Datei `/etc/audit/rules.d/user-commands.rules` anlegen oder bearbeiten:
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k user_commands -a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k user_commands
Die Regeln überwachen die Ausführung von Programmen durch angemeldete Benutzer. Der Schlüssel `user_commands` erleichtert die spätere Suche mit `ausearch`.
Regeln laden:
sudo augenrules --load sudo auditctl -l
Das Skript installieren:
sudo install -m 0755 \ /path/to/audit-format-syslog.py \ /usr/local/sbin/audit-format-syslog.py
Der Formatter liest die Audit-Meldungen über die Standardeingabe. Er sammelt die zusammengehörigen `SYSCALL`, `EXECVE` und `EOE`-Datensätze, löst die UID-Nummern in Benutzernamen auf und schreibt anschließend eine formatierte Syslog-Meldung.
Der vollständige Quelltext des Formatters:
#!/usr/bin/env python3 import binascii import pwd import re import shlex import sys import syslog import time from functools import lru_cache EVENT_RE = re.compile(r"msg=audit\(([^:]+):(\d+)\)") FIELD_RE = re.compile(r'([A-Za-z_][A-Za-z0-9_]*)=("[^"]*"|[^ ]+)') def fields(line): return {key: value.strip('"') for key, value in FIELD_RE.findall(line)} @lru_cache(maxsize=1024) def username(value): if value in (None, "unset", "4294967295"): return "-" try: return pwd.getpwuid(int(value)).pw_name except (KeyError, ValueError): return value def argument(value): if value is None: return "" if value.startswith('"') and value.endswith('"'): value = value[1:-1] if re.fullmatch(r"[0-9A-Fa-f]+", value) and len(value) % 2 == 0: try: return binascii.unhexlify(value).decode("utf-8", "replace") except (binascii.Error, UnicodeError): pass return value def emit(event): syscall = event.get("syscall") execve = event.get("execve") if not syscall or not execve or syscall.get("key") != "user_commands": return try: timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(event["epoch"]))) except (KeyError, ValueError, OverflowError): timestamp = "-" args = [argument(execve.get(f"a{index}")) for index in range(int(execve.get("argc", 0)))] command = " ".join(shlex.quote(value) for value in args) command = command.replace("\r", "\\r").replace("\n", "\\n") login_user = username(syscall.get("auid") or syscall.get("AUID")) executing_user = username(syscall.get("uid") or syscall.get("UID")) syslog.syslog(syslog.LOG_INFO, f"user-audit: {timestamp}, {login_user}, {executing_user}, {command}") current = {} EVENT_TIMEOUT = 30 syslog.openlog("audit-format", syslog.LOG_PID, syslog.LOG_LOCAL6) for line in sys.stdin: match = EVENT_RE.search(line) if not match: continue epoch, serial = match.groups() event = current.setdefault(serial, {"epoch": epoch}) if line.startswith("type=SYSCALL"): event["syscall"] = fields(line) elif line.startswith("type=EXECVE"): event["execve"] = fields(line) elif line.startswith("type=EOE"): emit(event) current.pop(serial, None) now = time.time() expired = [ key for key, pending in current.items() if now - float(pending["epoch"]) > EVENT_TIMEOUT ] for key in expired: current.pop(key, None)
Die erzeugte Meldung hat dieses Format:
user-audit: 2026-09-09 14:30:01, alice, root, 'apt' 'update'
Die Reihenfolge ist:
Zeit, eingeloggter Benutzer, ausführender Benutzer, Befehl
Datei `/etc/audit/plugins.d/audit-format.conf` anlegen:
active = yes direction = out path = /usr/local/sbin/audit-format-syslog.py type = always format = string
Auch bei neueren Debian- und Ubuntu-Versionen ist `audispd` in `auditd` integriert; die Plugin-Konfiguration bleibt dabei versionsabhängig. Die Werte müssen zur installierten `auditd`-Version passen. Das Skript muss ausführbar sein (`chmod 0755`). Wenn AppArmor oder SELinux aktiv ist, müssen zusätzlich der Zugriff auf den Skriptpfad und der passende Sicherheitskontext geprüft werden.
Das Skript verwendet die Syslog-Facility `local6` und den Programmnamen `audit-format`.
Datei `/etc/rsyslog.d/30-audit-format.conf` anlegen:
module(load="imuxsock")
template(
name="AuditSyslogFormat"
type="string"
string="%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n"
)
if ($programname == "audit-format" and
$syslogfacility-text == "local6") then {
action(
type="omfile"
file="/var/log/syslog"
template="AuditSyslogFormat"
createMode="0640"
)
stop
}
Dadurch werden nur die vom Formatter erzeugten Audit-Meldungen nach `/var/log/syslog` geschrieben.
`imuxsock` ist erforderlich, weil die Python-Syslog-Bibliothek die Meldung an `/dev/log` sendet. Auf Systemen, die zusätzlich oder hauptsächlich `imjournal` verwenden, sollte geprüft werden, dass `imuxsock` geladen ist und keine doppelte Verarbeitung über `journald` entsteht.
Beispiel:
Sep 9 14:30:01 server audit-format[1234]: user-audit: 2026-09-09 14:30:01, alice, root, 'apt' 'update'
Der erste Zeitstempel wird von rsyslogd ergänzt. Der zweite Zeitstempel stammt aus dem Audit-Ereignis.
Zuerst die rsyslogd-Konfiguration prüfen:
sudo rsyslogd -N1
Bei erfolgreicher Prüfung Dienste neu starten:
sudo systemctl restart rsyslog sudo service auditd restart
Auf manchen Distributionen wird ein direkter Neustart von `auditd` über `systemctl` aus Sicherheitsgründen abgelehnt. Verwende dann `service auditd restart` oder lade nach einer Regeländerung zunächst mit `sudo augenrules –load` die Audit-Regeln neu.
Status prüfen:
sudo systemctl status rsyslog sudo systemctl status auditd
Einen Befehl ausführen und Syslog beobachten:
id ls -la /tmp sudo tail -f /var/log/syslog
Bei einem Aufruf über `sudo` kann die Ausgabe beispielsweise so aussehen:
Sep 9 14:35:12 server audit-format[1234]: user-audit: 2026-09-09 14:35:12, alice, root, 'id'
Dabei bedeutet:
Audit-Regeln prüfen:
sudo auditctl -l sudo ausearch -k user_commands
Dienste und Fehlermeldungen prüfen:
sudo journalctl -u auditd -n 50 sudo journalctl -u rsyslog -n 50
Prüfen, ob das Log geschrieben wird:
sudo grep audit-format /var/log/syslog
Die Audit-Regeln können viele Meldungen erzeugen. Die Datei `/var/log/syslog` sollte deshalb regelmäßig rotiert und vor unbefugtem Zugriff geschützt werden.
Bei produktivem Betrieb sollte geprüft werden, ob die vorhandene Logrotate-Konfiguration für `/var/log/syslog` aktiv ist. Zusätzlich sollten die Berechtigungen der Logdatei und des Verzeichnisses kontrolliert werden.
Die Audit-Daten sind sicherheitsrelevant. Benutzer mit Root-Rechten können lokale Logdateien grundsätzlich verändern. Für manipulationsgeschützte Protokollierung ist eine Weiterleitung an einen zentralen Logserver erforderlich.
Linux, auditd, Audit, Benutzeraktionen, execve, sudo, rsyslog, syslog, audispd, Systemprotokoll, Sicherheitsprotokoll, Logdatei