Zum Inhalt springen

LogsAusführungBenutzeraktivität

systemd-Journal: das binäre Systemlog unter Linux

Das binäre Log von systemd-journald: strukturierte Einträge mit vertrauenswürdigen Prozessfeldern und UTC-Zeitstempeln in Mikrosekunden.

Speicherort
/var/log/journal/<machine-id>/
Belegt
Was Dienste, Prozesse, Benutzer und der Kernel protokolliert haben, mit vertrauenswürdiger PID/UID/Programmdatei und Boot-Kontext
Zeitstempel
Mikrosekunden seit der Unix-Epoche (UTC) für Realtime; Mikrosekunden seit dem Boot für Monotonic
Zugriff
root (oder Gruppe systemd-journal, adm bzw. wheel); Benutzer können ihr eigenes Journal (user-UID) lesen
Aufbewahrung
Größenbasiert: standardmäßig 10 % des Dateisystems, höchstens 4G; die flüchtige Kopie geht beim Neustart verloren
Sicherung
UAC, Velociraptor, cp -a, journalctl -o export

Was es ist

systemd-journald sammelt Logdaten aus dem Kernel, dem frühen Boot, syslog-Aufrufen, der nativen Journal-API sowie stdout/stderr jedes systemd-Dienstes und speichert sie in indizierten Binärdateien. Jeder Eintrag besteht aus FIELD=value-Paaren. Felder, deren Name mit einem Unterstrich beginnt, fügt journald selbst anhand der Kernel-Sicht auf den Absender hinzu (PID, UID, Programmdatei, Unit, Boot-ID). Ein Prozess kann sie also nicht fälschen, indem er eine manipulierte Nachricht schreibt.

Auf vielen aktuellen Installationen ist das Journal das primäre oder einzige Systemlog. Debian 12 installiert rsyslog nicht mehr standardmäßig, und Fedora hat es bereits mit Fedora 20 aus den Standardinstallationen entfernt. Fehlt /var/log/auth.log oder /var/log/secure, prüfen Sie zuerst das Journal, bevor Sie auf gelöschte Logs schließen.

Wo es liegt

SpeicherortPfadHinweise
Persistent/var/log/journal/<machine-id>/Übersteht Neustarts. <machine-id> entspricht /etc/machine-id
Flüchtig/run/log/journal/<machine-id>/tmpfs, geht beim Herunterfahren verloren. Nur vom laufenden System oder aus dem Arbeitsspeicher zu gewinnen
Aktive Systemdateisystem.journalDie Datei, in die aktuell geschrieben wird
Benutzerdateienuser-<UID>.journalStandard SplitMode=uid: eigene Dateien für reguläre UIDs (keine System-UIDs), weiterhin im Besitz der Journal-Gruppe, nicht des Benutzers
Archivierte Dateiensystem@<id>-<seqnum>-<time>.journalRotiert, schreibgeschützt
Unsaubere Dateien*.journal~Umbenannt nach einem unsauberen Stopp von journald oder bei erkannter Beschädigung
Konfiguration/etc/systemd/journald.conf, /etc/systemd/journald.conf.d/*.conf, /usr/lib/systemd/journald.conf.d/Storage=, SystemMaxUse=, MaxRetentionSec=, ForwardToSyslog=

Wohin die Daten geschrieben werden, hängt von Storage= ab. volatile hält sie in /run, persistent schreibt nach /var/log/journal, none verwirft sie, und auto schreibt nur dann nach /var, wenn /var/log/journal bereits existiert. auto war jahrelang der Upstream-Standard; mit systemd 259 wurde der einkompilierte Standard auf persistent geändert (Distributionen können das beim Build überschreiben). Lesen Sie die tatsächliche Konfiguration im Image aus, statt von einem der beiden Werte auszugehen.

Die Struktur ist bei Debian/Ubuntu, RHEL/Fedora, SUSE und Arch gleich. Die Unterschiede zwischen Distributionen liegen darin, ob persistente Speicherung aktiviert ist und ob zusätzlich rsyslog läuft.

Was es belegt

  • Welche Unit oder welcher Prozess eine Nachricht erzeugt hat, mit vertrauenswürdigen Werten für _PID, _UID, _COMM, _EXE, _CMDLINE und _SYSTEMD_UNIT.
  • Start, Stopp und Fehlschläge von Diensten (etwa eine bösartige Unit, die beim Boot startet, oder das Beenden von rsyslog/auditd).
  • Meldungen von sshd, sudo, su, PAM und cron, auch wenn kein Textlog existiert.
  • Kernel-Meldungen (_TRANSPORT=kernel): angeschlossene USB-Geräte, geladene Module, Firewall-LOG-Zeilen, OOM-Kills, Segfaults.
  • Boot-Grenzen über _BOOT_ID, die unerwartete Neustarts und Uhrsprünge sichtbar machen.
  • Es belegt nicht, dass eine Nachricht wahr ist: MESSAGE, SYSLOG_IDENTIFIER und PRIORITY liefert der Client, und jeder lokale Benutzer kann mit logger oder systemd-cat Einträge schreiben. Stützen Sie die Zuordnung auf die Felder mit Unterstrich.
  • In einer Shell eingegebene Befehle werden nicht erfasst, sofern sie nicht von etwas anderem protokolliert werden.

Wichtige Felder

FeldBedeutung
MESSAGELesbarer Text (vom Client geliefert)
PRIORITYSyslog-Level 0 (emerg) bis 7 (debug)
SYSLOG_IDENTIFIER, SYSLOG_FACILITYTag und Facility, wie vom Client gesendet
_PID, _UID, _GIDAbsenderprozess, Benutzer und Gruppe (vertrauenswürdig)
_COMM, _EXE, _CMDLINEProzessname, Pfad der Programmdatei, Befehlszeile (vertrauenswürdig)
_SYSTEMD_UNITUnit, zu der der Absender gehört
_BOOT_ID, _MACHINE_ID, _HOSTNAMEIdentität von Boot, Maschine und Host
_TRANSPORTEingangsweg: journal, syslog, stdout, kernel, audit, driver
_AUDIT_SESSION, _AUDIT_LOGINUIDAudit-Sitzung und Login-UID des Absenders
_SOURCE_REALTIME_TIMESTAMPFrühester vertrauenswürdiger Zeitstempel der Nachricht an der Quelle
__REALTIME_TIMESTAMP, __MONOTONIC_TIMESTAMPZeitpunkt, zu dem journald den Eintrag empfangen hat
__CURSOROpake Position des Eintrags, nützlich, um einen Datensatz exakt zu zitieren

Die Datei auf dem Datenträger beginnt mit der Signatur LPKSHHRH. Zu den Header-Feldern gehören machine_id, tail_entry_boot_id, head_entry_realtime und tail_entry_realtime; Datenobjekte können mit XZ, LZ4 oder ZSTD komprimiert sein.

Zeitstempel

Alle Zeiten im Journal werden in Mikrosekunden gespeichert. __REALTIME_TIMESTAMP zählt ab der Unix-Epoche in UTC; __MONOTONIC_TIMESTAMP zählt ab dem Boot und ist nur zusammen mit _BOOT_ID aussagekräftig. journalctl zeigt Zeiten in der lokalen Zeitzone des Analysesystems an, sofern Sie nicht --utc übergeben.

# 1789874047512345 usec -> UTC
date -u -d @$((1789874047512345 / 1000000))
journalctl -D "$J" --utc -o short-iso-precise --since "2026-09-20 03:00" --until "2026-09-20 04:00"

Realtime-Werte folgen der Systemuhr, eine manipulierte Uhr führt also zu irreführenden Wanduhrzeiten. Vergleichen Sie die monotone Reihenfolge innerhalb eines Boots und suchen Sie nach Anpassungsmeldungen von systemd-timesyncd oder NTP.

Aufbewahrung

Die Aufbewahrung ist standardmäßig größenbasiert. SystemMaxUse= steht per Default auf 10 % des Dateisystems, höchstens 4G; SystemKeepFree= auf 15 %, ebenfalls höchstens 4G. Einzelne Dateien rotieren bei einem Achtel von SystemMaxUse= (maximal 128M) oder nach MaxFileSec= (ein Monat). MaxRetentionSec= ist standardmäßig deaktiviert. Auf einem stark ausgelasteten Server reicht das Journal unter Umständen nur wenige Tage zurück, eine ruhige VM kann dagegen Jahre enthalten. Löschwege sind unter anderem journalctl --vacuum-time/--vacuum-size/--vacuum-files, --rotate mit anschließendem Vacuum, Storage=volatile oder none oder einfach das Entfernen der Dateien als root.

Sicherung

Kopieren Sie das gesamte Verzeichnis einschließlich der .journal~-Dateien und erhalten Sie dabei Besitzer und Zeitstempel. Sichern Sie auf einem laufenden System vor dem Herunterfahren zusätzlich /run/log/journal, denn es übersteht keinen Neustart.

# Live, as root
journalctl --flush                       # push /run data to /var if persistent
tar -C / -cpf /media/ir/journal.tar var/log/journal run/log/journal etc/systemd/journald.conf etc/systemd/journald.conf.d
journalctl -o export > /media/ir/journal.export   # lossless serialisation

# Dead box (read-only mount)
cp -a /mnt/evidence/var/log/journal /cases/2026-017/

UAC sammelt *.journal und *.journal~ unter /var/log (das flüchtige /run/log/journal deckt nur das separate Artefakt run_log ab, das in ir_triage und full enthalten ist) und führt journalctl --list-boots aus; das Velociraptor-Artefakt Linux.Forensics.Journal parst die Dateien direkt auf dem Endpunkt.

Auswertung

journalctl auf einem Analysesystem ist das Referenzwerkzeug. Verwenden Sie eine aktuelle Version: Dateien, die mit neueren, inkompatiblen Funktionen (etwa dem Compact-Modus) geschrieben wurden, lehnen ältere Versionen ab.

J=/mnt/evidence/var/log/journal
journalctl -D "$J" --list-boots --utc
journalctl -D "$J" --header | less                # file ranges, boot IDs, state
journalctl -D "$J" -b all _TRANSPORT=kernel --utc # kernel messages from every boot
journalctl -D "$J" SYSLOG_IDENTIFIER=sshd SYSLOG_IDENTIFIER=sshd-session -o json > sshd.json
journalctl -D "$J" -F _SYSTEMD_UNIT               # every unit that ever logged
journalctl --file "$J/<machine-id>/system@*.journal~" --utc
journalctl -D "$J" --verify

Der Plaso-Parser systemd_journal übernimmt die Einträge in eine Super-Timeline, und Velociraptors parse_journald() stellt sie in VQL bereit. Linux Log Parser liest auth.log / secure, syslog, Journal-Dateien, audit.log und wtmp / btmp / lastlog im Browser und führt sie in einer Zeitleiste mit rekonstruierten Login-Sitzungen zusammen; es wird nichts hochgeladen.

Tipps für die Untersuchung

  • Übergeben Sie jedes Mal -D oder --file. Ohne diese Option liest journalctl stillschweigend das Journal des Analysesystems selbst.
  • -k impliziert den aktuellen Boot; verwenden Sie bei Offline-Beweismitteln stattdessen _TRANSPORT=kernel -b all.
  • Viele .journal~-Dateien, --verify-Fehler rund um den Vorfall oder eine Boot-Liste, die abrupt ohne Shutdown-Sequenz endet, sind Ansatzpunkte für Manipulation oder ein hartes Ausschalten. Ohne Forward Secure Sealing erkennt --verify nur Beschädigungen, kein sauberes Neuschreiben.
  • Korrelieren Sie _AUDIT_LOGINUID und _AUDIT_SESSION mit den auid/ses-Werten aus auditd und mit Sitzungen in wtmp.
  • Auch eine Unit, die nur über stdout protokolliert, erhält _SYSTEMD_UNIT und _EXE. Damit ist das Journal der beste Ort, um zu sehen, was eine verdächtige systemd-Unit tatsächlich ausgegeben hat.
  • Läuft zusätzlich rsyslog, vergleichen Sie beide: Eine Zeile, die im Journal steht, aber in auth.log/secure fehlt, deutet auf eine Bearbeitung des Textlogs hin.

Siehe auch