Linux Troubleshooting-Flow: Systematisch Probleme lösen

Linux-Probleme systematisch debuggen: Der strukturierte Troubleshooting-Ansatz mit Logs, Ressourcen, Netzwerk und Services – von 'Was ist kaputt?' bis zur Lösung mit konkreten Befehlen.

9 min Lesezeit

Linux Troubleshooting-Flow: Systematisch Probleme lösen

Der Unterschied zwischen einem guten und einem schlechten Troubleshooter ist nicht das Wissen, sondern die Methode. Blindes Ausprobieren kostet Stunden. Ein strukturierter Ansatz – von der Symptom-Eingrenzung bis zur Ursachen-Analyse – löst die meisten Probleme in Minuten.

Dieser Guide ist dein Playbook für Linux-Problemsituationen.


Der universelle Troubleshooting-Flow

1. Situation erfassen
   ├── Was genau passiert? (Fehlermeldung?)
   ├── Wann hat es aufgehört zu funktionieren?
   ├── Was hat sich geändert?
   └── Wer/was ist betroffen?

2. Logs analysieren
   ├── journalctl (systemd-Logs)
   ├── /var/log/ (klassische Logs)
   └── Anwendungs-Logs

3. Ressourcen prüfen
   ├── Disk voll?
   ├── RAM erschöpft?
   └── CPU überlastet?

4. Services und Prozesse
   ├── Service läuft?
   ├── Fehler-Exit-Code?
   └── Abhängigkeiten?

5. Netzwerk
   ├── Verbindung?
   ├── DNS?
   └── Port offen?

6. Lösung → Test → Dokumentation

Goldene Regel: Ändere immer nur eine Sache auf einmal. Sonst weißt du nicht, was geholfen hat.


Phase 1: Situation erfassen

Die wichtigsten ersten Fragen

# Wie lange läuft das System schon?
uptime
# 10:00:00 up 45 days, 3:20, ...

# Was ist die genaue Fehlermeldung?
# (immer vollständig kopieren, nicht umschreiben!)

# Wann hat das Problem begonnen?
# → Timestamp aus Logs
# → Wann war letztes Deployment, Update, Konfigurationsänderung?

# Letzte Systemänderungen anzeigen
last           # Login-History
lastlog        # letzter Login je User
journalctl --since "2 hours ago" -p warning

# Wer hat was geändert? (falls sudo geloggt wird)
grep "sudo" /var/log/auth.log | tail -30
journalctl _COMM=sudo --since "24 hours ago"

# Letzte Paket-Installationen/-Updates
grep " install \| upgrade " /var/log/dpkg.log | tail -20   # Ubuntu/Debian
dnf history | head -10   # Fedora

System-Schnellcheck

#!/bin/bash
# Systemstatus auf einen Blick

echo "=== SYSTEM STATUS ==="
echo "Hostname:  $(hostname -f)"
echo "Zeit:      $(date)"
echo "Uptime:    $(uptime -p)"
echo ""

echo "=== RESSOURCEN ==="
df -h | grep -v "tmpfs\|udev"
free -h | grep "Mem:"
echo "Load: $(cut -d ' ' -f1-3 /proc/loadavg)"
echo ""

echo "=== FAILED SERVICES ==="
systemctl --failed --no-legend
echo ""

echo "=== LETZTE FEHLER ==="
journalctl -p err -b --no-pager -n 10

Phase 2: Logs analysieren

Das systemd-Journal: Erste Anlaufstelle

# Alle Fehler seit letztem Boot
journalctl -p err -b --no-pager

# Alle Logs live verfolgen
journalctl -f

# Logs seit einer Stunde
journalctl --since "1 hour ago" --no-pager

# Logs eines bestimmten Services
journalctl -u nginx -n 50 --no-pager
journalctl -u nginx -f   # live

# Nur kritische Fehler
journalctl -p crit -b --no-pager

# Alle Fehler + Warnungen
journalctl -p warning -b --no-pager | head -50

Klassische Log-Dateien

# Wichtige Log-Pfade
/var/log/syslog        # System-Messages (Ubuntu)
/var/log/messages      # System-Messages (Fedora/RHEL)
/var/log/auth.log      # Authentifizierung (Ubuntu)
/var/log/secure        # Authentifizierung (Fedora)
/var/log/kern.log      # Kernel-Logs
/var/log/apt/          # APT-History (Ubuntu)
/var/log/nginx/        # Nginx-Logs
/var/log/mysql/        # MySQL-Logs
/var/log/postgresql/   # PostgreSQL-Logs

# Live verfolgen
tail -f /var/log/nginx/error.log

# Nach Zeitstempel suchen
grep "Feb 18 10:" /var/log/syslog

# Fehler der letzten Stunde
grep "$(date -d '1 hour ago' '+%b %e %H')" /var/log/syslog | grep -i error

# Log-Analyse: häufigste Fehlermeldungen
awk '{print $6,$7,$8}' /var/log/nginx/error.log | sort | uniq -c | sort -rn | head -10

Log-Level-System

emerg (0) → System unbrauchbar
alert (1) → Sofortige Aktion nötig
crit  (2) → Kritisch
err   (3) → Fehler ← meist hier suchen
warn  (4) → Warnung
note  (5) → Hinweis
info  (6) → Information
debug (7) → Debug (sehr viel Output)

Phase 3: Ressourcen prüfen (CPU, RAM, Disk)

Disk: Der häufigste stille Killer

# Ist Disk voll?
df -h
# Use% 100% oder 99% → Problem!

# Welches Verzeichnis ist groß?
du -sh /* 2>/dev/null | sort -rh | head -10
ncdu /   # interaktiv

# Inodes voll? (Dateien obwohl Disk "voll" zeigt 0)
df -i
# IUse% 100% → Inode-Problem

# Gelöschte aber noch offene Dateien (unsichtbarer Speicher!)
sudo lsof | grep deleted | awk '{print $1, $7}' | sort -k2 -rn | head -10

RAM: Knappheit erkennen

# RAM-Status
free -h
# "available" ist die wichtige Zahl (nicht "free")

# Swap-Nutzung
free -h | grep Swap
# Wenn Swap > 50% genutzt: Speicherproblem

# Speicherhungrige Prozesse
ps aux --sort=-%mem | head -10

# OOM-Killer war aktiv?
journalctl -k | grep -i "oom\|killed process"
dmesg | grep -i "oom\|killed"

CPU: Last einschätzen

# Systemlast
uptime
# load average: 12.5, 8.3, 5.2
# Auf einem 4-Kern-System: > 4 = Überlast

# CPU-Fresser finden
ps aux --sort=-%cpu | head -10
top -bn1 | head -15

# I/O-Wait (CPU wartet auf Disk)
iostat -x 1 3   # wenn %iowait > 20%: I/O-Bottleneck

Phase 4: Services und Prozesse prüfen

Service-Status-Workflow

# 1. Service-Status
sudo systemctl status nginx

# Typische Ausgaben:
# Active: active (running)   → OK
# Active: failed             → Fehler! Exit-Code prüfen
# Active: inactive (dead)    → Service nicht gestartet
# Active: activating         → Startet noch...

# 2. Warum ist der Service fehlgeschlagen?
journalctl -u nginx -n 50 --no-pager

# 3. Service manuell starten und Fehler sehen
sudo systemctl start nginx
sudo journalctl -u nginx -f   # in zweitem Terminal

# 4. Alle fehlgeschlagenen Services
systemctl --failed

# 5. Abhängigkeiten prüfen
systemctl list-dependencies nginx.service

Service startet nicht: Checklist

# a) Konfigurationsdatei korrekt?
sudo nginx -t               # nginx
sudo apache2ctl configtest  # apache

# b) Port bereits belegt?
sudo ss -tlnp | grep :80

# c) Berechtigungen korrekt?
ls -la /etc/nginx/nginx.conf   # gehört root?
ls -la /var/www/html/          # gehört www-data?

# d) ExecStart-Pfad existiert?
sudo systemctl cat nginx | grep ExecStart
ls -la /usr/sbin/nginx

# e) Umgebungsvariablen gesetzt?
sudo systemctl cat mein-service | grep EnvironmentFile
sudo cat /etc/mein-service/environment

# f) Service manuell als Service-User starten
sudo -u www-data /usr/sbin/nginx -g "daemon off;" -c /etc/nginx/nginx.conf

Phase 5: Netzwerk und Konnektivität

Schicht für Schicht debuggen

# Layer 1/2: Interface vorhanden und aktiv?
ip link
# eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>  ← UP = ok

# Layer 3: IP vorhanden?
ip addr
# 192.168.1.100/24 auf eth0 ← ok

# Layer 3: Route vorhanden?
ip route
# default via 192.168.1.1  ← Default-Gateway ok

# Layer 3: Gateway erreichbar?
ping -c4 $(ip route | awk '/default/ {print $3}')

# Layer 3: Internet erreichbar?
ping -c4 8.8.8.8

# Layer 7: DNS funktioniert?
dig google.com +short @8.8.8.8
nslookup google.com

# Layer 4: Port offen?
sudo ss -tlnp | grep :80

# Layer 7: HTTP-Request klappt?
curl -I http://localhost
curl -I https://meine-seite.de

Netzwerkprobleme: Typische Szenarien

# "kein Internet, aber LAN ok"
ping 8.8.8.8   # klappt? → DNS-Problem
dig google.com @8.8.8.8   # direkt → lokaler DNS kaputt

# "Port offen, aber keine Verbindung"
sudo ufw status   # Firewall?
sudo iptables -L | grep DROP   # iptables-Regeln?

# "DNS schlägt fehl"
cat /etc/resolv.conf   # welcher DNS-Server?
resolvectl status      # systemd-resolved

# DNS-Cache leeren
sudo resolvectl flush-caches

# "Verbindung bricht ab"
mtr --report server   # Packet-Loss auf Route?
ping -c100 server | tail -3   # Paketverlust?

Phase 6: Änderungen rückgängig machen

# Paket auf alte Version zurückrollen (apt)
apt list --installed nginx   # aktuelle Version
sudo apt-get install nginx=1.24.0-2   # alte Version erzwingen
sudo apt-mark hold nginx   # Version einfrieren

# Konfigurationsdatei zurücksetzen
sudo cp /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf
sudo systemctl restart nginx

# Timeshift-Snapshot zurückrollen (System)
sudo timeshift --restore

# Docker-Container auf altes Image zurückrollen
docker pull meine-app:v1.2.3
docker-compose up -d   # nach Image-Tag-Änderung in compose.yaml

# Git: Code-Stand zurücksetzen
git log --oneline -10   # welcher Commit war gut?
git checkout COMMIT_HASH -- src/   # nur bestimmte Dateien
git revert COMMIT_HASH   # sauber rückgängig machen

# Datenbankstand (wenn Dump vorhanden)
mysql -u root -p meinedatenbank < backup_20260217.sql

Häufige Problem-Szenarien

Szenario 1: Webseite antwortet nicht (502 Bad Gateway)

# 1. Ist nginx aktiv?
sudo systemctl status nginx
# Active: active ← nginx läuft

# 2. Was sagen nginx-Logs?
sudo tail -50 /var/log/nginx/error.log
# 502 connect() failed ... php8.4-fpm.sock

# 3. Ist PHP-FPM aktiv?
sudo systemctl status php8.4-fpm
# Active: failed ← PHP-FPM ist kaputt!

# 4. Warum ist PHP-FPM kaputt?
journalctl -u php8.4-fpm -n 30 --no-pager
# "no space left on device" ← Disk voll!

# 5. Disk prüfen und freigaben
df -h
sudo journalctl --vacuum-time=7days
sudo apt clean

# 6. PHP-FPM neu starten
sudo systemctl start php8.4-fpm
curl -I http://localhost   # Test

Szenario 2: Server reagiert sehr langsam

# 1. Systemlast prüfen
uptime
# load: 45.3, 38.7, 28.2 auf 8-Kern-System → massiv überlastet

# 2. CPU-Fresser finden
ps aux --sort=-%cpu | head -5
# www  12345 99.9 15.2 ... php-fpm

# 3. I/O-Wait prüfen
iostat -x 1 3
# %iowait = 85% → Disk ist Flaschenhals

# 4. Disk-I/O prüfen
iotop   # interaktiv (sudo apt install iotop)
# oder:
iostat -dx 1 3

# 5. Hängende Prozesse finden
ps aux | awk '$8 == "D"' | head -10
# D-State = wartet auf I/O

# 6. Was schreibt auf die Disk?
sudo lsof | awk '$5 == "REG" && $6 > 100000000' | sort -k6 -rn | head -10

Szenario 3: Service startet nicht nach Neustart

# 1. Service-Logs
journalctl -u mein-service -b --no-pager
# "EnvironmentFile: no such file or directory"

# 2. Fehlende Datei erstellen
sudo nano /etc/mein-service/environment

# 3. Oder: Permission-Problem?
ls -la /var/lib/mein-service/
# drwx------ root root  ← www-data hat keinen Zugriff!

sudo chown -R www-data:www-data /var/lib/mein-service/

# 4. Service neu starten
sudo systemctl start mein-service
sudo systemctl status mein-service

# 5. Nächsten Boot prüfen (wenn möglich)
# systemd-analyze blame  ← Boot-Zeit-Analyse
# systemctl list-units --failed  ← nach Neustart

Troubleshooting-Checkliste

TROUBLESHOOTING CHECKLISTE
══════════════════════════

☐ Fehlermeldung vollständig notiert (exakter Wortlaut)
☐ Zeitpunkt des Auftretens bekannt
☐ Letzte Änderungen identifiziert:
   ☐ Updates: grep "upgrade\|install" /var/log/dpkg.log | tail -20
   ☐ Konfigurationsänderungen: git log -20 (falls versioniert)
   ☐ Deployments: Deployment-Log prüfen

Logs gecheckt:
   ☐ journalctl -p err -b
   ☐ journalctl -u SERVICE -n 50
   ☐ Anwendungs-spezifische Logs in /var/log/

Ressourcen gecheckt:
   ☐ df -h  → Disk nicht voll?
   ☐ free -h → RAM ausreichend?
   ☐ uptime  → Last normal?
   ☐ sudo lsof | grep deleted (Ghosts?)

Services gecheckt:
   ☐ systemctl --failed
   ☐ sudo systemctl status SERVICE
   ☐ Konfiguration korrekt?

Netzwerk gecheckt:
   ☐ ip addr → IP vorhanden?
   ☐ ping gateway → Gateway erreichbar?
   ☐ ping 8.8.8.8 → Internet erreichbar?
   ☐ dig domain.de → DNS funktioniert?

Änderung gemacht:
   ☐ NUR eine Änderung auf einmal
   ☐ Änderung dokumentiert
   ☐ Test nach Änderung
   ☐ Monitoring danach

Fazit

Systematisches Troubleshooting spart Zeit und Nerven. Der Schlüssel liegt darin, nicht zu raten, sondern von den Symptomen zur Ursache zu navigieren:

  1. Logs sind dein bester Freundjournalctl -p err -b als erstes
  2. Disk full ist häufiger als gedacht – immer früh df -h prüfen
  3. Eine Änderung auf einmal – sonst weißt du nicht, was geholfen hat
  4. Dokumentiere die Lösung – für den nächsten Vorfall

Die meisten Linux-Probleme sind in einer der fünf Kategorien: Disk voll, Service crashed, Rechte falsch, Netzwerk broken, Konfigurationsfehler.

War dieser Artikel hilfreich?