Log-Dateien verwalten: Unterschied zwischen den Versionen
| Zeile 293: | Zeile 293: | ||
Der eigentliche Grund, warum rsyslog auch heute noch gebraucht wird: Logs mehrerer Maschinen an einer Stelle sammeln. Im Kurs wird die '''Rocky-Maschine zum Server''' und die '''Debian-Maschine zum Client'''. | Der eigentliche Grund, warum rsyslog auch heute noch gebraucht wird: Logs mehrerer Maschinen an einer Stelle sammeln. Im Kurs wird die '''Rocky-Maschine zum Server''' und die '''Debian-Maschine zum Client'''. | ||
| − | == | + | == Zentraler Logserver – rsyslog-Konfiguration == |
| − | + | Die folgende Konfiguration macht aus einem Rechner einen zentralen Logserver: Er nimmt Syslog-Meldungen anderer Hosts über das Netz entgegen und legt sie pro Host und pro Dienst in einer eigenen Datei ab. | |
| − | + | <syntaxhighlight lang="bash"> | |
| − | + | module(load="imudp") | |
| − | + | input(type="imudp" port="514") | |
| − | + | module(load="imtcp") | |
| − | + | input(type="imtcp" port="514") | |
| − | + | ||
| − | + | $template FernLog,"/var/log/hosts/%HOSTNAME%/%PROGRAMNAME%.log" | |
| − | + | :fromhost-ip, !isequal, "127.0.0.1" ?FernLog | |
| + | & stop | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Zeile für Zeile === | ||
| + | |||
| + | ; <code>module(load="imudp")</code> | ||
| + | : Lädt das Eingangsmodul für UDP. Das Modul wird nur einmal geladen, unabhängig davon, wie viele Ports später geöffnet werden. | ||
| + | |||
| + | ; <code>input(type="imudp" port="514")</code> | ||
| + | : Öffnet den UDP-Port 514 (der klassische Syslog-Port). UDP ist verbindungslos: schnell und ressourcenschonend, aber Meldungen können bei Last oder Paketverlust verlorengehen. | ||
| + | |||
| + | ; <code>module(load="imtcp")</code> / <code>input(type="imtcp" port="514")</code> | ||
| + | : Dasselbe für TCP. TCP quittiert die Übertragung, Meldungen gehen also nicht einfach verloren. UDP und TCP dürfen gleichzeitig auf Port 514 lauschen, weil es zwei getrennte Protokolle sind. | ||
| + | |||
| + | ; <code>$template FernLog,"/var/log/hosts/%HOSTNAME%/%PROGRAMNAME%.log"</code> | ||
| + | : Definiert eine Vorlage für den Dateinamen. Die Prozentzeichen sind Platzhalter für Eigenschaften der jeweiligen Meldung: | ||
| + | :* <code>%HOSTNAME%</code> – der Name des sendenden Rechners, wie er '''in der Meldung''' steht | ||
| + | :* <code>%PROGRAMNAME%</code> – der Dienst, der die Meldung erzeugt hat (z. B. <code>sshd</code>, <code>sudo</code>, <code>kernel</code>) | ||
| + | : Aus einer sshd-Meldung von <code>web01</code> wird damit <code>/var/log/hosts/web01/sshd.log</code>. Fehlende Verzeichnisse legt rsyslog selbst an (<code>$CreateDirs</code> ist standardmäßig aktiv). | ||
| + | |||
| + | ; <code>:fromhost-ip, !isequal, "127.0.0.1" ?FernLog</code> | ||
| + | : Ein Property-Filter. Er prüft die Eigenschaft <code>fromhost-ip</code>, also die IP-Adresse, von der das Paket tatsächlich kam. Trifft der Vergleich „ist '''nicht''' 127.0.0.1“ zu, wird die Meldung über die Vorlage weggeschrieben. Das <code>?</code> vor dem Namen bedeutet: dynamischer Dateiname aus einem Template (ein <code>/</code> stünde für eine feste Datei). | ||
| + | : Lokal erzeugte Meldungen haben immer <code>127.0.0.1</code> und fallen deshalb durch – sie landen weiter in den üblichen lokalen Logdateien. | ||
| + | |||
| + | ; <code>& stop</code> | ||
| + | : Das <code>&</code> hängt eine weitere Aktion an '''denselben''' Filter an, die Bedingung wird also nicht wiederholt. <code>stop</code> beendet die Verarbeitung dieser Meldung. Ohne diese Zeile würden die Fremd-Meldungen zusätzlich in <code>/var/log/syslog</code> bzw. <code>/var/log/messages</code> laufen und dort alles vermischen. | ||
| + | |||
| + | === Hinweise für die Praxis === | ||
| + | |||
| + | * '''Reihenfolge beachten:''' Dateien in <code>/etc/rsyslog.d/</code> werden alphabetisch eingelesen. Die Konfiguration muss vor den Standardregeln greifen, also z. B. als <code>/etc/rsyslog.d/10-remote.conf</code>. | ||
| + | * '''Firewall:''' Port 514/udp und 514/tcp müssen freigegeben sein. | ||
| + | * '''%HOSTNAME% ist Inhalt der Meldung''' und damit fälschbar. Wer die Trennung fest an die Herkunft binden will, nimmt <code>%FROMHOST-IP%</code> im Template. | ||
| + | * '''Keine Authentisierung, keine Verschlüsselung.''' Plain-Syslog auf 514 gehört nur ins vertrauenswürdige Netz. Für den produktiven Einsatz: RELP (<code>imrelp</code>) oder Syslog über TLS. | ||
| + | * '''Alte und neue Syntax gemischt:''' <code>$template</code> und der <code>:filter</code> sind Legacy-Schreibweise, funktionieren aber weiterhin. Modern wäre <code>template(name="FernLog" type="string" string="…")</code> zusammen mit <code>action(type="omfile" dynaFile="FernLog")</code>. | ||
| + | * '''Logrotation:''' Für <code>/var/log/hosts/*/*.log</code> eine eigene logrotate-Regel anlegen, sonst wächst das Verzeichnis unbegrenzt. | ||
*mkdir /var/log/hosts | *mkdir /var/log/hosts | ||
Version vom 27. August 2026, 06:19 Uhr
Log-Dateien verwalten
Auf modernen Linux-Systemen gibt es zwei Log-Welten, die nebeneinander existieren:
- systemd-journald – sammelt alles zentral in einem Binärformat, abgefragt mit
journalctl - rsyslog – der klassische Syslog-Dienst, schreibt Textdateien nach
/var/logund kann Meldungen über das Netz verschicken
Wichtiger Unterschied zwischen den Kursmaschinen:
| System | journald | rsyslog |
|---|---|---|
| Rocky Linux | aktiv | installiert und aktiv, schreibt /var/log/messages und /var/log/secure |
| Debian (ab 12) | aktiv | nicht installiert, muss bei Bedarf nachinstalliert werden |
Deshalb findet man auf der Debian-Maschine kein /var/log/syslog mehr – die Meldungen sind trotzdem da, nur im Journal.
Ausgangslage prüfen
Zuerst auf beiden Maschinen nachsehen, wer überhaupt loggt.
- systemctl status systemd-journald
- systemctl status rsyslog
- ls -l /var/log
Aufgabe 1
- Vergleiche den Inhalt von
/var/logauf Rocky und auf Debian. - Welche Dateien gibt es nur auf Rocky? Woher kommen sie?
- Prüfe auf beiden Systemen, ob der Dienst
rsyslogexistiert.
Das Journal abfragen
Das Journal wird nicht mit cat oder tail gelesen, sondern immer über journalctl.
Übersicht über die Optionen
| Option | Bedeutung |
|---|---|
-n |
nur die letzten n Zeilen |
-e |
ans Ende springen, zu den neuesten Meldungen |
-b |
nur ein Bootvorgang, -b -1 der vorherige
|
-u |
nur Meldungen einer bestimmten Unit |
-f |
mitlaufen lassen (wie tail -f)
|
-g |
Volltextsuche im Meldungstext (grep, Regex) |
-k |
nur Kernel-Meldungen (entspricht dmesg)
|
-p |
nach Priorität filtern, 0 (emerg) bis 7 (debug) |
--since |
ab einem Zeitpunkt |
--until |
bis zu einem Zeitpunkt |
-o |
Ausgabeformat |
Grundlegende Aufrufe
- Das gesamte Journal, älteste Meldung zuerst
- journalctl
- Nur die letzten 20 Zeilen
- journalctl -n 20
- Ans Ende springen, also zu den neuesten Meldungen
- journalctl -e
- Nur der aktuelle Bootvorgang
- journalctl -b
- Der vorherige Bootvorgang – wichtig nach einem Absturz
- journalctl -b -1
Nach Dienst und Inhalt filtern
- Alles, was der SSH-Dienst gemeldet hat
- journalctl -u sshd
- Dasselbe live mitlaufend – neue Meldungen erscheinen sofort
- journalctl -u sshd -f
- Alle Meldungen, in denen der Text vorkommt, egal von welchem Dienst
- journalctl -g "Failed password"
- Nur Kernel-Meldungen
- journalctl -k
- Kernel-Meldungen des vorherigen Bootvorgangs
- journalctl -k -b -1
Zeitliche Eingrenzung
- Ab einem festen Zeitpunkt
- journalctl --since "2026-08-25 08:00"
- Relative Angabe, hier die letzte Stunde
- journalctl --since "1 hour ago"
- Ein abgeschlossener Zeitraum, hier der gestrige Tag
- journalctl --since yesterday --until today
Nach Priorität filtern
Angegeben wird die Stufe oder ihr Name; gezeigt wird sie und alles Wichtigere.
- Warnungen und alles darüber
- journalctl -p warning
- Nur Fehler und schlimmer, im aktuellen Boot
- journalctl -p err -b
Kombinieren
Die Optionen lassen sich beliebig mischen – sie wirken als UND-Verknüpfung.
- Erfolgreiche SSH-Anmeldungen von heute
- journalctl -u sshd -g "Accepted" --since today
- Fehlgeschlagene SSH-Anmeldungen live mitverfolgen
- journalctl -f -u sshd -g "Failed"
- Fehler eines Dienstes im aktuellen Boot
- journalctl -u sshd -p err -b
Andere Ausgabeformate
- Alle Felder eines Eintrags, nicht nur den Meldungstext – zeigt PID, UID, Unit, Quelldatei
- journalctl -u sshd -o verbose
- Dasselbe als JSON, eingerückt – für die Weiterverarbeitung
- journalctl -u sshd -o json-pretty
- Standardausgabe, aber mit vollständigem Zeitstempel inklusive Datum und Zeitzone
- journalctl -u sshd -o short-iso
Aufgabe 2
- Melde dich von der anderen Maschine per SSH an – einmal erfolgreich, einmal mit falschem Passwort.
- Lass dir auf der Zielmaschine in einem zweiten Terminal die SSH-Meldungen live mitlaufen.
- Finde alle fehlgeschlagenen Anmeldungen des heutigen Tages mit einer einzigen Zeile.
- Zeige alle Kernel-Meldungen des letzten Bootvorgangs an.
- Suche im Journal nach dem Namen einer deiner Netzwerkkarten.
Größe des Journals begrenzen
Das Journal rotiert sich selbst. Es braucht kein logrotate.
Aktuelle Belegung anzeigen:
- journalctl --disk-usage
Grenzen setzen:
- vim /etc/systemd/journald.conf
[Journal] SystemMaxUse=200M SystemMaxFileSize=20M MaxRetentionSec=1month
| Einstellung | Bedeutung |
|---|---|
SystemMaxUse= |
Obergrenze für das gesamte Journal. Wird sie erreicht, löscht journald die ältesten Dateien. |
SystemMaxFileSize= |
Maximale Größe einer einzelnen Journaldatei. Ist sie voll, wird rotiert und eine neue angelegt. |
MaxRetentionSec= |
Höchstalter der Einträge. Ältere werden gelöscht, auch wenn noch Platz wäre. |
Nach jeder Änderung:
- systemctl restart systemd-journald
- journalctl --disk-usage
Aufräumen von Hand
- Alles löschen, was älter als 7 Tage ist
- journalctl --vacuum-time=7d
- Löschen, bis das Journal höchstens noch 100 MB belegt
- journalctl --vacuum-size=100M
- Die Journaldateien auf Beschädigungen prüfen
- journalctl --verify
rsyslog
rsyslog holt sich die Meldungen aus dem Journal und schreibt sie in Textdateien. Auf Debian muss er erst installiert werden:
- apt install rsyslog
Auf Rocky ist er bereits vorhanden:
- rpm -q rsyslog
- systemctl status rsyslog
Facility und Severity
Jede Syslog-Meldung hat zwei Merkmale: woher sie kommt (Facility) und wie dringend sie ist (Severity).
| Facility | Bedeutung |
|---|---|
| kern | Kernel |
| auth, authpriv | Anmeldung, Rechte |
| daemon | Systemdienste |
| Mailsystem | |
| cron | Zeitsteuerung |
| local0–local7 | frei verwendbar für eigene Zwecke |
| Nr. | Severity | Bedeutung |
|---|---|---|
| 0 | emerg | System unbrauchbar |
| 1 | alert | sofortiges Eingreifen nötig |
| 2 | crit | kritischer Zustand |
| 3 | err | Fehler |
| 4 | warning | Warnung |
| 5 | notice | normal, aber bemerkenswert |
| 6 | info | Information |
| 7 | debug | Fehlersuche |
Die Regeln stehen in der Form facility.severity Ziel, wobei die angegebene Severity und alles dringendere zutrifft.
Konfiguration ansehen
- less /etc/rsyslog.conf
- ls -l /etc/rsyslog.d/
Eigene Regel schreiben
- vim /etc/rsyslog.d/99-kurs.conf
local3.* /var/log/kurs.log local3.err /var/log/kurs-fehler.log
- systemctl restart rsyslog
Testmeldungen erzeugen:
- logger -p local3.info "Das ist eine Testmeldung"
- logger -p local3.err "Das ist ein Testfehler"
- cat /var/log/kurs.log
- cat /var/log/kurs-fehler.log
Aufgabe 4
- Installiere rsyslog auf der Debian-Maschine und sieh nach, welche Dateien jetzt in
/var/logentstehen. - Lege eine Regel an, die alle Meldungen der Facility
local5nach/var/log/uebung.logschreibt. - Erzeuge mit
loggerje eine Meldung der Severity info, warning und err. - Ändere die Regel so, dass nur noch Meldungen ab Severity
warninggeschrieben werden, und weise nach, dass die info-Meldung nicht mehr ankommt. - Suche dieselbe Meldung anschließend im Journal mit
journalctl -g. Warum ist sie dort trotzdem zu finden?
logrotate
Textlogs wachsen unbegrenzt – dafür gibt es logrotate, das per Timer einmal täglich läuft.
- systemctl status logrotate.timer
- cat /etc/logrotate.conf
- ls -l /etc/logrotate.d/
Eigene Rotation für die selbst angelegte Logdatei:
- vim /etc/logrotate.d/kurs
/var/log/kurs.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root adm
postrotate
systemctl kill -s HUP rsyslog.service
endscript
}
Testlauf ohne Änderungen (Trockenlauf):
- logrotate -d /etc/logrotate.d/kurs
Rotation erzwingen:
- logrotate -f /etc/logrotate.d/kurs
- ls -l /var/log/kurs.log*
Zustand nachsehen:
- cat /var/lib/logrotate/logrotate.status
Achtung Rocky: Dort lautet die Gruppe der Logdateien root statt adm, die create-Zeile muss angepasst werden.
Aufgabe 5
- Schreibe eine logrotate-Konfiguration für
/var/log/uebung.logaus Aufgabe 4. - Es sollen 4 Generationen aufgehoben und komprimiert werden, Rotation wöchentlich oder ab 1 MB.
- Prüfe die Konfiguration erst im Trockenlauf, rotiere dann von Hand.
- Erzeuge danach eine neue Meldung und weise nach, dass sie in der neuen Datei landet.
Zentraler Loghost
Der eigentliche Grund, warum rsyslog auch heute noch gebraucht wird: Logs mehrerer Maschinen an einer Stelle sammeln. Im Kurs wird die Rocky-Maschine zum Server und die Debian-Maschine zum Client.
Zentraler Logserver – rsyslog-Konfiguration
Die folgende Konfiguration macht aus einem Rechner einen zentralen Logserver: Er nimmt Syslog-Meldungen anderer Hosts über das Netz entgegen und legt sie pro Host und pro Dienst in einer eigenen Datei ab.
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")
$template FernLog,"/var/log/hosts/%HOSTNAME%/%PROGRAMNAME%.log"
:fromhost-ip, !isequal, "127.0.0.1" ?FernLog
& stop
Zeile für Zeile
module(load="imudp")- Lädt das Eingangsmodul für UDP. Das Modul wird nur einmal geladen, unabhängig davon, wie viele Ports später geöffnet werden.
input(type="imudp" port="514")- Öffnet den UDP-Port 514 (der klassische Syslog-Port). UDP ist verbindungslos: schnell und ressourcenschonend, aber Meldungen können bei Last oder Paketverlust verlorengehen.
module(load="imtcp")/input(type="imtcp" port="514")- Dasselbe für TCP. TCP quittiert die Übertragung, Meldungen gehen also nicht einfach verloren. UDP und TCP dürfen gleichzeitig auf Port 514 lauschen, weil es zwei getrennte Protokolle sind.
$template FernLog,"/var/log/hosts/%HOSTNAME%/%PROGRAMNAME%.log"- Definiert eine Vorlage für den Dateinamen. Die Prozentzeichen sind Platzhalter für Eigenschaften der jeweiligen Meldung:
%HOSTNAME%– der Name des sendenden Rechners, wie er in der Meldung steht%PROGRAMNAME%– der Dienst, der die Meldung erzeugt hat (z. B.sshd,sudo,kernel)
- Aus einer sshd-Meldung von
web01wird damit/var/log/hosts/web01/sshd.log. Fehlende Verzeichnisse legt rsyslog selbst an ($CreateDirsist standardmäßig aktiv).
:fromhost-ip, !isequal, "127.0.0.1" ?FernLog- Ein Property-Filter. Er prüft die Eigenschaft
fromhost-ip, also die IP-Adresse, von der das Paket tatsächlich kam. Trifft der Vergleich „ist nicht 127.0.0.1“ zu, wird die Meldung über die Vorlage weggeschrieben. Das?vor dem Namen bedeutet: dynamischer Dateiname aus einem Template (ein/stünde für eine feste Datei). - Lokal erzeugte Meldungen haben immer
127.0.0.1und fallen deshalb durch – sie landen weiter in den üblichen lokalen Logdateien.
& stop- Das
&hängt eine weitere Aktion an denselben Filter an, die Bedingung wird also nicht wiederholt.stopbeendet die Verarbeitung dieser Meldung. Ohne diese Zeile würden die Fremd-Meldungen zusätzlich in/var/log/syslogbzw./var/log/messageslaufen und dort alles vermischen.
Hinweise für die Praxis
- Reihenfolge beachten: Dateien in
/etc/rsyslog.d/werden alphabetisch eingelesen. Die Konfiguration muss vor den Standardregeln greifen, also z. B. als/etc/rsyslog.d/10-remote.conf. - Firewall: Port 514/udp und 514/tcp müssen freigegeben sein.
- %HOSTNAME% ist Inhalt der Meldung und damit fälschbar. Wer die Trennung fest an die Herkunft binden will, nimmt
%FROMHOST-IP%im Template. - Keine Authentisierung, keine Verschlüsselung. Plain-Syslog auf 514 gehört nur ins vertrauenswürdige Netz. Für den produktiven Einsatz: RELP (
imrelp) oder Syslog über TLS. - Alte und neue Syntax gemischt:
$templateund der:filtersind Legacy-Schreibweise, funktionieren aber weiterhin. Modern wäretemplate(name="FernLog" type="string" string="…")zusammen mitaction(type="omfile" dynaFile="FernLog"). - Logrotation: Für
/var/log/hosts/*/*.logeine eigene logrotate-Regel anlegen, sonst wächst das Verzeichnis unbegrenzt.
- mkdir /var/log/hosts
- systemctl restart rsyslog
- ss -tulpn | grep 514
Firewall öffnen:
- firewall-cmd --add-port=514/tcp --permanent
- firewall-cmd --add-port=514/udp --permanent
- firewall-cmd --reload
SELinux prüfen – Port 514 ist als syslogd_port_t bereits bekannt:
- semanage port -l | grep syslog
Client einrichten (Debian)
- vim /etc/rsyslog.d/20-client.conf
*.* action(type="omfwd"
target="192.168.1.10"
port="514"
protocol="tcp"
queue.type="linkedlist"
queue.filename="fwdqueue"
action.resumeRetryCount="-1"
queue.saveOnShutdown="on")
- systemctl restart rsyslog
- logger -p local3.info "Hallo vom Client"
Auf dem Server nachsehen:
- ls -l /var/log/hosts/
- tail -f /var/log/hosts/*/*.log
Aufgabe 6
- Richte die Rocky-Maschine als Loghost ein und die Debian-Maschine als Client.
- Weise nach, dass der Server auf Port 514 lauscht.
- Erzeuge auf dem Client eine Meldung und finde sie auf dem Server wieder.
- Melde dich per SSH falsch am Client an – landet die Meldung ebenfalls auf dem Server?
- Stoppe rsyslog auf dem Server, erzeuge auf dem Client Meldungen, starte den Server wieder. Sind die Meldungen nachgeliefert worden? Warum?
- Trage in die logrotate-Konfiguration des Servers ein Verzeichnis mit Wildcard ein, damit auch die eingesammelten Logs rotiert werden.
Zusammenfassung
- Alles läuft zuerst durch journald –
journalctlist das Werkzeug erster Wahl bei der Fehlersuche - Merkhilfe für den Alltag:
-uwelche Unit,-flive mitlesen,-gsuchen,-kKernel - Das Journal ist nicht automatisch persistent und rotiert sich selbst
- rsyslog wird gebraucht für Textdateien, klassische Auswertungswerkzeuge und vor allem für zentrale Logsammlung
- logrotate verwaltet nur Textdateien, nicht das Journal
- Ein zentraler Loghost ist die Vorstufe zu einem SIEM