Q&A Klassiker: /var lÀuft voll

Kategorie: Q&A · Channel: #klassiker

Format: BĂŒhnenspiel – Admin · Angreifer · Kunde


Die Situation

Uhrzeit:  03:47 Uhr
Alarm:    Monitoring schlĂ€gt an – Disk Usage /var > 95%
Website:  HTTP 500, Logs werden nicht mehr geschrieben
Kunde:    ruft um 04:12 Uhr an

đŸ‘šâ€đŸ’» Admin-Perspektive: Was sehe ich, was tue ich?

Schritt 1: Lagebild verschaffen

# Wo ist das Problem genau?
df -h
# Ausgabe:
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/vg0/lv_var  10G  9.9G     0 100% /var

# Was frisst den Platz?
du -sh /var/*
# /var/log     8.2G   ← Treffer!
# /var/cache   420M
# /var/lib     280M
# /var/tmp      18M

# Noch genauer:
du -sh /var/log/*  | sort -rh | head -20
# 7.9G  /var/log/syslog
# 180M  /var/log/syslog.1
# 12M   /var/log/auth.log

Schritt 2: Was fĂŒllt syslog?

# Letzte EintrĂ€ge prĂŒfen:
tail -100 /var/log/syslog

# Wie schnell wÀchst die Datei gerade?
watch -n 2 'ls -lh /var/log/syslog'

# Wer schreibt wie viele Zeilen?
tail -10000 /var/log/syslog | awk '{print $5}' | \
  sort | uniq -c | sort -rn | head -20

# HĂ€ufigste Meldung finden:
tail -10000 /var/log/syslog | \
  sed 's/[0-9]//g' | sort | uniq -c | sort -rn | head -10

Schritt 3: Sofortmaßnahme – Platz schaffen

# ⚠ NIEMALS einfach rm /var/log/syslog!
# Rsyslog hĂ€lt die Datei offen → Platz wird nicht freigegeben

# RICHTIG: Datei leeren (nicht löschen)
> /var/log/syslog                    # Inhalt löschen, Inode bleibt
# oder
truncate -s 0 /var/log/syslog

# Rsyslog Signal senden (neue Datei öffnen)
systemctl kill -s HUP rsyslog
# oder
kill -HUP $(pidof rsyslogd)

# Alte rotierte Logs löschen
ls -lh /var/log/syslog.*
rm /var/log/syslog.2.gz
rm /var/log/syslog.3.gz
# (syslog.1 behalten – noch aktuell)

# Platz prĂŒfen
df -h /var

Schritt 4: Ursache verstehen

# Was hat syslog geflutet?
grep -c "kernel:" /var/log/syslog     # Kernel-Meldungen?
grep -c "iptables" /var/log/syslog    # Firewall-Logs?
grep -c "sshd" /var/log/syslog        # SSH-Brute-Force?
grep -c "CRON" /var/log/syslog        # Cronjob-Loop?

# Typischer Flood: Cronjob der jede Minute einen Fehler wirft
grep "CRON\|cron" /var/log/syslog | tail -20

# Typischer Flood: Kernel-Meldung im Loop
grep "kernel:" /var/log/syslog | tail -20

# Typischer Flood: iptables-LOG Regel ohne Rate-Limit
grep "iptables-DROP" /var/log/syslog | wc -l

Schritt 5: Log-Rotation konfigurieren (PrÀvention)

# /etc/logrotate.d/rsyslog anpassen:
/var/log/syslog {
    daily
    rotate 7           # nur 7 Tage behalten
    size 500M          # auch bei GrĂ¶ĂŸe rotieren!
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

# Sofort rotieren:
logrotate -f /etc/logrotate.d/rsyslog

# rsyslog Rate-Limiting aktivieren:
# /etc/rsyslog.conf:
$SystemLogRateLimitInterval 5
$SystemLogRateLimitBurst 500
# → max 500 Meldungen pro 5 Sekunden pro Quelle

Schritt 6: LVM – LV nachtrĂ€glich vergrĂ¶ĂŸern

# Wenn /var zu klein war – online vergrĂ¶ĂŸern:
lvextend -r -L +5G /dev/vg0/lv_var
# -r = resize2fs / xfs_growfs automatisch

# PrĂŒfen:
df -h /var

đŸŠč Angreifer-Perspektive: Wie hĂ€tte ich das verursacht?

Methode 1: Syslog-Flood via UDP

Angreifer schickt massenhaft UDP-Pakete an Port 514 (Syslog).
Wenn rsyslog remote-logging akzeptiert:
→ Jedes Paket = eine Zeile in syslog
→ Bei 10.000 Paketen/Sekunde: /var/log voll in Minuten

Diagnose:
ss -ulnp | grep 514     → lauscht rsyslog auf UDP 514?
netstat -su             → UDP-Pakete gezĂ€hlt?

Methode 2: Log-Flooding via Applikation

Fehlerhafter API-Call → Applikation loggt jeden Fehler
→ Bei 1000 Requests/Sekunde gegen defekten Endpoint:
  1000 × "ERROR: Database connection failed" / Sekunde
→ /var/log/app/ voll in Minuten

Diagnose:
tail -f /var/log/nginx/error.log  → welcher Endpoint?
tail -f /var/log/app/error.log    → was genau?

Methode 3: iptables LOG ohne Rate-Limit

Eine zu aggressive LOG-Regel:
iptables -A INPUT -j LOG --log-prefix "iptables-DROP: "
→ JEDES verworfene Paket wird geloggt
→ Bei Port-Scan: 65535 Pakete → 65535 Log-Zeilen

Diagnose:
grep "iptables-DROP" /var/log/syslog | wc -l
→ wenn > 100.000: Rate-Limit fehlt!

Fix:
iptables -R INPUT [REGEL-NR] -j LOG \
  --log-prefix "iptables-DROP: " \
  -m limit --limit 5/min --limit-burst 10

Methode 4: Fork-Bomb via Cronjob

Cronjob der sich selbst aufruft oder nicht terminiert:
→ Jeder Prozess schreibt Fehler nach syslog
→ CRON-Entries hĂ€ufen sich

Diagnose:
grep "CRON" /var/log/syslog | \
  awk '{print $6}' | sort | uniq -c | sort -rn
→ wenn ein Job hunderte Male pro Minute auftaucht

Was der Angreifer hofft:

1. Logging fĂ€llt aus → Spuren werden nicht mehr geschrieben
2. Applikation crasht → /var voll = keine neuen Log-Files
3. Denial of Service → Datenbankschreibfehler wenn /var/lib voll
4. Admin ist abgelenkt → eigentlicher Angriff lĂ€uft parallel

👔 Kunden-Perspektive: Was erlebe ich?

04:12 Uhr – Anruf beim Support:

"Unsere Website ist seit etwa einer Stunde down.
 Die Startseite zeigt einen weißen Bildschirm.
 Der Online-Shop funktioniert nicht.
 Wir haben morgen frĂŒh 08:00 Uhr eine wichtige PrĂ€sentation.
 Was ist passiert und wann lÀuft es wieder?"

Was der Kunde sieht (HTTP-Perspektive):

# Browser: weißer Bildschirm / HTTP 500
# Was auf dem Server dahinter passiert:

# PHP/App kann nicht nach /var/log schreiben → Crash
# MySQL kann nicht nach /var/lib/mysql schreiben → Fehler
# nginx error.log voll → nginx wirft 500

# Schnelltest vom Admin:
curl -I https://kunde.example.com
# HTTP/1.1 500 Internal Server Error

# Was nginx sagt:
tail -20 /var/log/nginx/error.log
# "open() "/var/log/nginx/error.log" failed (28: No space left on device)"

Kommunikation mit dem Kunden:

04:15 Uhr:
"Wir haben das Problem identifiziert: 
 Ein Log-File hat den Speicherplatz aufgebraucht.
 Wir beheben das gerade – SchĂ€tzung: 15 Minuten."

04:28 Uhr:
"Die Website lÀuft wieder. Ursache war ein unkontrolliertes
 Log-Wachstum. Wir haben Sofortmaßnahmen getroffen und
 richten jetzt Monitoring und automatische Log-Rotation ein."

🎯 Erkenntnis – Drei Perspektiven zusammen

Perspektive Kernaussage
đŸ‘šâ€đŸ’» Admin du -sh /var/* \| sort -rh ist der erste Befehl. Immer.
đŸŠč Angreifer Log-Flooding ist billig und effektiv – rate-limit alles!
👔 Kunde HTTP 500 um 03:47 = Anruf um 04:12 = schlechte Nacht

🔧 PrĂ€vention – was danach einzurichten ist

# 1. LV-Monitoring (Disk-Alarm bei 80%, nicht erst bei 100%)
#    → Icinga2 / Nagios check_disk

# 2. Log-Rotation mit GrĂ¶ĂŸen-Limit
#    /etc/logrotate.d/* → size 500M fĂŒr alle kritischen Logs

# 3. rsyslog Rate-Limiting
#    $SystemLogRateLimitBurst 500

# 4. iptables LOG immer mit Rate-Limit
#    -m limit --limit 5/min --limit-burst 10

# 5. Separates LV fĂŒr /var/log (vom LVM-Layout)
#    → wenn /var/log voll: /var/lib nicht betroffen!
#    lvcreate -L 5G -n lv_var_log vg0
#    mkfs.ext4 /dev/vg0/lv_var_log
#    mount /dev/vg0/lv_var_log /var/log

# 6. Remote-Syslog absichern
#    UDP 514 nicht von außen erreichbar!
#    iptables -A INPUT -p udp --dport 514 ! -s 10.0.0.0/19 -j DROP

📋 Schnellreferenz: /var voll – Einzeiler

df -h /var                                    # Wie voll?
du -sh /var/* | sort -rh | head -10           # Was belegt Platz?
du -sh /var/log/* | sort -rh | head -10       # Welches Log?
truncate -s 0 /var/log/syslog                 # Log leeren (kein rm!)
systemctl kill -s HUP rsyslog                 # rsyslog neu öffnen
logrotate -f /etc/logrotate.d/rsyslog         # Rotation erzwingen
grep "kernel:\|CRON\|iptables" /var/log/syslog | wc -l  # Flut-Quelle?
lvextend -r -L +5G /dev/vg0/lv_var            # LV vergrĂ¶ĂŸern