Kolorowy kod i komunikaty bezpieczeństwa na ekranie terminala Linux
Źródło: Pexels | Autor: Pixabay
Rate this post

Nawigacja:

Po co w ogóle są logi: perspektywa administratora i audytora

Kluczowe funkcje logów w Linuksie

System logów w Linuksie to nie „kosz na śmieci” dla komunikatów, ale podstawowe narzędzie kontroli nad środowiskiem. Z perspektywy administratora i audytora logi pełnią kilka wyraźnych funkcji, które trzeba stale mieć z tyłu głowy przy projektowaniu systemu logowania.

Po pierwsze, diagnoza i debugowanie. Gdy usługa się wywraca, system się wiesza, a aplikacja przestaje odpowiadać – logi są pierwszym źródłem prawdy. Informują o błędach, wyjątkach, crashach, niedostępności zasobów, timeoutach. Bez poprawnie zorganizowanych logów każdy incydent kończy się zgadywaniem i odtwarzaniem zdarzeń na podstawie częściowych obserwacji.

Po drugie, audyt i zgodność. W wielu środowiskach – od bankowości po administrację publiczną – logi są wymagane przez polityki bezpieczeństwa i normy (np. ISO 27001). Muszą pokazywać kto, kiedy i co wykonał w systemie. Tu liczy się nie tylko sam fakt logowania, ale też spójność, nienaruszalność, odpowiednia retencja oraz możliwość powiązania zdarzeń z konkretnymi kontami i procesami.

Po trzecie, forensic i analiza powłamaniowa. Gdy dochodzi do incydentu bezpieczeństwa, logi są jednym z nielicznych źródeł danych, które pozwalają odtworzyć ścieżkę atakującego. Braki w logach, dziury czasowe, niestandardowe miejsca zapisu – to wszystko bezpośrednio utrudnia analizę. Audytor patrzy tu krytycznie: czy z logów da się bez domysłów odtworzyć przebieg kluczowych akcji?

Po czwarte, metryki i obserwowalność. Komunikaty logów są bazą wielu systemów monitoringu aplikacyjnego. Błędy 5xx, powtarzające się ostrzeżenia, piki w ilości logów – to sygnały, które da się zautomatyzować i zamienić w alerty. Bez dobrego systemu logów metryki są dziurawe albo oparte na cząstkowych danych.

Jeżeli logi pełnią którąś z powyższych funkcji „tylko czasem”, jest to wyraźny sygnał ostrzegawczy dla audytora: system logowania istnieje, ale nie realizuje roli narzędzia kontroli i dowodowego.

Cechy dobrego systemu logowania

Dobry system logowania w Linuksie ma kilka mierzalnych cech. Nie chodzi o to, jakie konkretnie narzędzia są użyte (journald, rsyslog, syslog-ng), ale jak są skonfigurowane i czy spełniają minimum wymagań produkcyjnych.

Po pierwsze, kompletność. Logi z jądra, usług systemd, demonów, aplikacji i komponentów bezpieczeństwa muszą trafiać do jednego przewidywalnego strumienia. Dla audytora sygnałem ostrzegawczym jest sytuacja, gdy nie da się odpowiedzieć, gdzie loguje dana usługa i jak te logi są utrzymywane. Brak kompletności często wychodzi na jaw dopiero przy incydencie.

Po drugie, spójność i struktura. Logi powinny mieć przewidywalny format: znaczniki czasu, poziomy priorytetu, identyfikator jednostki/usługi, PID, użytkownik. journald daje to „z pudełka” przez pola strukturalne, a rsyslog może narzucić format tekstowych plików. Jeżeli każde źródło loguje inaczej, analiza jest kosztowna i mało niezawodna.

Po trzecie, odporność na awarie. System logowania musi wytrzymać gwałtowny wzrost ilości logów (np. pętla błędów), awarię sieci, pełny dysk w docelowym katalogu. Tu pojawiają się ustawienia takie jak limitowanie tempa logów w journald czy kolejki dyskowe w rsyslog. Brak takich zabezpieczeń prowadzi do kaskadowych awarii.

Po czwarte, łatwe i jednoznaczne przeszukiwanie. Zespół musi mieć uzgodnione narzędzia i standardy (journalctl z określonymi filtrami, grep na tekstowych logach, centralny system SIEM). Jeśli każdy szuka inaczej, rośnie ryzyko przeoczenia kluczowych zdarzeń.

Wreszcie, kontrolowana retencja. Logi powinny mieć jasno określony cykl życia: jak długo są przechowywane lokalnie, kiedy rotowane, co trafia na zewnętrzny serwer logów. Brak polityki retencji to klasyczny punkt krytyczny: albo logi znikają zbyt szybko, albo zapychają dyski.

Skutki braku spójnej polityki logowania

Typowy scenariusz z praktyki: na serwerze produkcyjnym pada krytyczna usługa – np. system billingowy. Restart nie pomaga, użytkownicy zgłaszają błędy, presja rośnie. Administrator sprawdza journalctl – cisza. Sięga do /var/log/messages – nic istotnego. Dopiero po kilkunastu minutach ktoś przypomina, że aplikacja ma własny katalog /opt/app/logs/, a część komponentów loguje wyłącznie do stdout, przechwytywanego przez inny demona.

Po kolejnej godzinie okazuje się, że logi utrzymywane są tylko w pamięci (journald w trybie volatile), więc poprzedni restart systemu „wyczyścił” historię problemów. Audytor w takiej sytuacji stwierdzi wprost: system nie jest audytowalny, bo kluczowe informacje nie są ani kompletne, ani trwałe.

Brak spójnej polityki logowania skutkuje też dublowaniem logów (te same komunikaty lądują i w journalu, i w licznych plikach), chaosem w retencji (niektóre logi są rotowane co dzień, inne nigdy) oraz brakiem jasnej odpowiedzialności za konfigurację. Każda zmiana w aplikacji może przypadkowo wyłączyć logowanie, co wychodzi na jaw dopiero po incydencie.

Minimalne wymagania wobec logów w środowisku produkcyjnym

Dobrym podejściem jest zdefiniowanie punktów kontrolnych, które musi spełniać każdy host produkcyjny z Linuksem.

  • journald skonfigurowany w trybie persistent z kontrolą wykorzystania dysku.
  • Uzgodniona integracja journald z rsyslog (lub innym daemonem syslog) – jednoznaczne ścieżki przepływu logów.
  • Jedno centralne miejsce zapisu logów systemowych (np. /var/log) z rotacją przez logrotate.
  • Wspólny standard formatowania logów aplikacyjnych lub przynajmniej obowiązkowe pola: timestamp, poziom, kontekst.
  • Konfiguracja wysyłki kluczowych logów na zdalny serwer (SIEM, log-serwer) w krytycznych środowiskach.
  • Procedura testowa: regularne sprawdzenie, czy dla losowo wybranej usługi da się znaleźć kompletne logi z ostatnich dni.

Jeśli choć jeden z powyższych punktów kontrolnych wypada słabo, system logowania nie spełnia minimum do bezpiecznej eksploatacji. Taki stan „działa, ale” prędzej czy później przełoży się na incydent, którego nie będzie jak rzetelnie przeanalizować.

Architektura logowania w nowoczesnym Linuksie: od aplikacji do dysku

Źródła logów: jądro, usługi, demony i aplikacje

Nowoczesny Linux zbiera logi z wielu, często niezależnych źródeł. Zrozumienie ich roli to pierwszy krok do ogarnięcia całości architektury logowania.

Podstawowym źródłem jest jądro. Komunikaty kernela (np. o błędach sprzętowych, problemach z dyskami, sterownikami, siecią) trafiają przez pierwotny bufor dmesg do journald, a w starszych konfiguracjach również do demonów syslog. To fundamentalne informacje z punktu widzenia stabilności platformy.

Drugą rodzinę stanowią usługi zarządzane przez systemd. Każda jednostka systemd (unit) może logować na stdout/stderr, które są automatycznie przechwytywane przez systemd-journald. Dzięki temu nawet prosta aplikacja bez własnej obsługi logów, uruchomiona jako usługa systemd, staje się częścią scentralizowanego systemu logowania.

Kolejna kategoria to demony działające w tle (sshd, cron, nginx, postfix itd.). Część z nich loguje bezpośrednio do journald, inne używają klasycznego interfejsu syslog() i gniazda /dev/log. Rola journald i rsyslog w tym obszarze zależy od dystrybucji i konfiguracji.

Na końcu są aplikacje użytkownika. Niektóre logują do własnych plików w /var/log/app lub /opt/app/logs, inne wypisują logi na standardowe wyjście, licząc na to, że systemd lub inny mechanizm przechwyci te komunikaty. Z punktu widzenia audytora i utrzymania szczególnie krytyczne jest to, żeby aplikacje nie „chowały” logów w nietypowych miejscach bez jasnej dokumentacji.

Ścieżka komunikatów: od syslog() do journald i rsyslog

Architekturę logowania można zobaczyć jako łańcuch etapów. Typowy przepływ w nowoczesnych dystrybucjach z systemd wygląda następująco:

  1. Aplikacja lub demon generuje komunikat, np. za pomocą funkcji syslog(), wypisując go na stdout/stderr lub korzystając z API systemd.
  2. Komunikat trafia:
    • do gniazda /dev/log (dla klasycznego sysloga),
    • bezpośrednio do journald (stdout/stderr jednostek systemd, kernel, API systemd),
    • do zewnętrznego demona logów (rzadziej w standardowej konfiguracji).
  3. systemd-journald odbiera większość komunikatów, wzbogaca je o metadane (PID, UID, GID, UNIT, cgroup), przypisuje im poziom priorytetu i zapisuje do binarnych plików dziennika (w pamięci lub na dysku).
  4. rsyslog (lub inny daemon syslog) może:
    • odbierać komunikaty bezpośrednio z /dev/log,
    • pobierać je z journald poprzez moduł imjournal,
    • przetwarzać, filtrować, a następnie zapisywać do /var/log/*.log lub wysyłać przez sieć.

Kluczowa jest tu rola journald jako pierwszego odbiorcy w wielu dystrybucjach: nawet jeśli później logi trafiają do rsyslog i plików tekstowych, to journald jest pierwszą stacją pośrednią. Sygnałem ostrzegawczym jest sytuacja, gdy zespół nie potrafi narysować tej ścieżki dla krytycznej usługi – wtedy każda zmiana (np. wyłączenie rsyslog) może nieświadomie wyłączyć część logowania.

Relacja journald i rsyslog: kiedy wystarcza journald

Pozycja journald (systemd-journald) i rsyslog jest częstym źródłem nieporozumień. W uproszczeniu:

  • journald – zbiera, buforuje i przechowuje logi w formie binarnej, oferując bogate metadane i integrację z systemd,
  • rsyslog – elastycznie przetwarza strumień logów i przekierowuje go w różne miejsca (pliki, serwery zdalne, bazy), głównie w formacie tekstowym (syslog).

W prostych środowiskach wystarcza sam journald z dobrze ustawionym persistent logging i ewentualnym eksportem do zewnętrznych narzędzi przez journalctl. Przykład: pojedynczy serwer testowy lub mały serwer aplikacyjny, gdzie analiza logów jest realizowana lokalnie, a wymagania audytowe są umiarkowane.

W środowiskach produkcyjnych z reguły pojawia się potrzeba:

  • integracji z centralnym serwerem syslog lub SIEM,
  • standardowych, tekstowych plików logów kompatybilnych ze starszymi narzędziami,
  • zaawansowanego filtrowania i parsowania (np. wyciągania pól z logów aplikacyjnych),
  • rozbudowanego kolejkowania na wypadek problemów z siecią.

Tu wchodzi rola rsyslog jako modułowego demona, który odbiera logi z journald (moduł imjournal) lub bezpośrednio z /dev/log, a następnie zgodnie z konfiguracją przekazuje je dalej. Jeśli zespół nie jest w stanie odpowiedzieć, które logi przetwarza rsyslog, a które trafiają wyłącznie do journald, jest to czytelny punkt kontrolny: architektura logowania jest niejasna i podatna na błędy konfiguracyjne.

Punkt kontrolny: znana ścieżka logów dla każdej krytycznej aplikacji

Dla audytora jednym z pierwszych pytań jest: którędy dokładnie idą logi tej usługi od momentu wygenerowania do ostatecznego miejsca przechowywania? Brak jednoznacznej odpowiedzi to poważny sygnał ostrzegawczy.

Praktyczna checklista dla każdej krytycznej aplikacji:

  • Czy aplikacja loguje na stdout/stderr, do syslog(), czy własnych plików?
  • Czy jej jednostka systemd ma jawnie ustawione StandardOutput/StandardError?
  • Czy journald odbiera te logi (sprawdzalne przez journalctl -u nazwa-uslugi)?
  • Czy rsyslog (lub inny daemon) pobiera je z journald (imjournal) lub z /dev/log?
  • Do jakich konkretnie plików lub zdalnych systemów trafiają te logi i na jak długo?

Dobrym krokiem jest stworzenie krótkiej „karty logowania” dla każdej istotnej usługi: jedna strona z opisem źródeł logów, ścieżek przetwarzania, miejsc docelowych i czasów retencji. Taki dokument ogranicza wiedzę „w głowach adminów”, ułatwia audyt i przyspiesza reakcję podczas incydentu. Jeśli na etapie projektowania nowej aplikacji taka karta nie powstaje, to sygnał ostrzegawczy, że logowanie traktowane jest jako dodatek, a nie element bezpieczeństwa i utrzymania.

Drugi praktyczny element to okresowe ćwiczenia w odtwarzaniu historii zdarzeń. Wybierany jest konkretny incydent (np. nieudane logowanie SSH, błąd w aplikacji webowej, restart usługi bazodanowej) i zadaniem zespołu jest złożenie osi czasu wyłącznie na podstawie logów: journald, rsyslog, logów aplikacyjnych i ewentualnie zdalnego SIEM. Jeśli kompletowanie takiej historii zajmuje godziny albo wymaga „magii” pojedynczego administratora, architektura logowania jest zbyt skomplikowana lub słabo udokumentowana.

Trzeci obszar to spójność konfiguracji między środowiskami. Dobrą praktyką jest utrzymywanie wzorcowych konfiguracji journald i rsyslog (np. w Ansible, Puppet, Git) i egzekwowanie minimalnego zestawu wymagań: włączona persystencja journald, określony rozmiar buforów, jasne reguły rotacji plików oraz standardowe ścieżki logów aplikacyjnych. Rozjazd pomiędzy „dev”, „test” i „prod” często skutkuje sytuacją, w której błąd zauważony na produkcji jest niemożliwy do odtworzenia w kontrolowany sposób, bo logi w środowiskach różnią się zakresem i formatem.

Czwarty element to regularny przegląd poziomów logowania. Zbyt niski poziom (np. wszędzie INFO) powoduje przeoczenie istotnych zdarzeń, zbyt wysoki (wszędzie DEBUG) generuje zalew danych i zwiększa ryzyko, że w logach pojawią się dane wrażliwe. Minimum to okresowe sprawdzenie, czy kluczowe usługi używają sensownych poziomów (ERROR/WARN/INFO) i czy reguły w rsyslog/journald nie obcinają niechcący komunikatów potrzebnych do analizy incydentów.

Jeżeli architektura logów jest zrozumiała, ścieżka przepływu komunikatów dla każdej krytycznej usługi da się narysować w kilku krokach, a konfiguracje journald i rsyslog są świadomie utrzymywane, to system logowania przestaje być „tajemniczym czarnym pudełkiem”, a staje się narzędziem pracy. W takim środowisku diagnoza problemów, spełnienie wymogów audytowych i planowanie rozwoju stają się prostsze, bo każdy incydent zostawia ślad, który da się szybko odnaleźć i rzetelnie przeanalizować.

systemd-journald – konfiguracja, persystencja i retencja

Konfiguracja journald jest rozproszona między plik domyślny i nadpisujące go pliki lokalne. Kluczem jest zrozumienie, gdzie faktycznie obowiązujące parametry są ustawione, a nie dopisywanie kolejnych opcji bez ładu.

Pliki konfiguracyjne i kolejność ich ładowania

Główny plik dostarczany przez dystrybucję to /etc/systemd/journald.conf lub /usr/lib/systemd/journald.conf (zależnie od dystrybucji). Zasada jest podobna jak w innych komponentach systemd: domyślna konfiguracja może być nadpisana przez pliki w /etc/systemd/ oraz katalogi journald.conf.d/.

Praktyczny porządek ładowania:

  1. Plik domyślny (np. /usr/lib/systemd/journald.conf).
  2. Plik lokalny /etc/systemd/journald.conf – nadpisuje ustawienia domyślne.
  3. Pliki w katalogu /etc/systemd/journald.conf.d/*.conf – pozwalają na podział konfiguracji na mniejsze, tematyczne fragmenty.

Punkt kontrolny: przed zmianą konfiguracji trzeba sprawdzić, czy w systemie istnieją pliki w journald.conf.d. Brak tej kontroli skutkuje często „niewyjaśnionym” zachowaniem journald, bo faktyczne parametry pochodzą z pliku, o którym nikt nie pamięta.

Jeżeli w systemie nie ma spójnej polityki, który plik ma być źródłem „prawdy” (główny journald.conf czy pliki w journald.conf.d/), to każdy kolejny administrator może wprowadzać zmiany w innym miejscu i de facto nikt nie ma pełnego obrazu aktywnych ustawień.

Persistent, volatile i auto – gdzie lądują logi

Podstawowy parametr, który decyduje o tym, czy logi przeżyją restart, to Storage= w sekcji [Journal]:

  • Storage=auto – domyślny tryb w wielu dystrybucjach; journald używa /var/log/journal, jeśli katalog istnieje, w przeciwnym razie korzysta wyłącznie z pamięci (/run/log/journal).
  • Storage=persistent – wymusza zapis na dysk w /var/log/journal; jeśli katalog nie istnieje, journald próbuje go utworzyć.
  • Storage=volatile – logi wyłącznie w pamięci, znikają po restarcie.
  • Storage=none – journald nie zapisuje logów ani w pamięci, ani na dysk; praktycznie wyłącza dziennik.

Minimalna czynność konfiguracyjna to świadome ustawienie Storage=persistent oraz upewnienie się, że katalog /var/log/journal istnieje i ma poprawne uprawnienia. Automatyczne poleganie na auto bez weryfikacji katalogu prowadzi do częstego scenariusza: po reinstalacji lub „porządku” w /var/log logi nagle przestają być trwałe.

Sygnałem ostrzegawczym jest sytuacja, gdy na serwerze produkcyjnym po restarcie zespół nie ma dostępu do logów sprzed przeładowania, a nikt nie potrafi powiedzieć, czy journald był ustawiony na persistent, czy przypadkiem działał w trybie volatile.

Limity rozmiaru i czasu przechowywania

Retencja w journald jest kontrolowana przede wszystkim przez limity wielkości dziennika. Kluczowe parametry w journald.conf to:

  • SystemMaxUse= – maksymalna łączna przestrzeń na logi systemowe (/var/log/journal),
  • SystemKeepFree= – ilość miejsca na dysku, którą journald pozostawi wolną; nadpisuje aktywność rotacji, gdy zbliżamy się do progu zapełnienia dysku,
  • SystemMaxFileSize= – maksymalny rozmiar pojedynczego pliku dziennika,
  • RuntimeMaxUse=, RuntimeMaxFileSize= – odpowiedniki dla dziennika w pamięci (/run/log/journal).

Retencja czasowa (np. „trzy miesiące”) nie jest definiowana wprost parametrem typu „KeepDays”, ale wyliczana pośrednio przez kombinację ilości danych i limitu miejsca. Jeśli dziennik zużywa niewiele przestrzeni, logi mogą sięgać wielu miesięcy wstecz; jeśli serwer generuje duże wolumeny logów, okres ten automatycznie się skraca.

Punkt kontrolny: dla środowisk o ścisłych wymaganiach audytowych naturalnym minimum jest oszacowanie dziennego wolumenu logów (przynajmniej przybliżone) i ustawienie SystemMaxUse oraz SystemKeepFree tak, aby realny czas retencji pokrywał się z polityką bezpieczeństwa. Brak takiego szacunku oznacza, że nikt nie wie, ile faktycznie dni historii przechowuje journald.

Jeżeli podczas incydentu bezpieczeństwa okazuje się, że journald przechowuje dane z ostatnich dwóch dni, a wymagania mówią o 30 dniach, to nie jest „pech” – to bezpośredni brak planowania retencji.

Uprawnienia, ACL i ochrona danych wrażliwych

Logi zawierają często dane wrażliwe: adresy IP, identyfikatory użytkowników, czasem fragmenty żądań HTTP czy treści błędów aplikacyjnych. journald domyślnie ustawia uprawnienia do katalogu /var/log/journal na takie, które ograniczają odczyt do roota i członków grupy systemd-journal.

Praktyczny model dostępu:

  • root – pełny dostęp do logów przez journalctl,
  • użytkownik w grupie systemd-journal – odczyt logów systemowych,
  • zwykły użytkownik – domyślnie odczyt ograniczony do logów własnych procesów.

Rozszerzając uprawnienia, część administratorów dodaje szerokie ACL lub zmienia prawa katalogu na zbyt liberalne. To wygodne w krótkim terminie, ale z perspektywy audytu jest to wyraźny sygnał ostrzegawczy: dostęp do pełnej historii logów przez konta techniczne bez kontroli i rejestru.

Punkt kontrolny to inwentaryzacja, kto realnie ma dostęp do pełnego dziennika: lista członków grupy systemd-journal, obecność specyficznych ACL oraz istnienie kont „serwisowych”, które technicznie mogą odczytywać wszystko. Jeśli liczba takich kont jest nieznana lub nikt nie wie, dlaczego konkretne konto ma dostęp do dziennika, kontrola dostępu do logów jest iluzoryczna.

journalctl w praktyce – podstawowe scenariusze i pułapki

Praca z journald bez biegłego użycia journalctl jest jak zarządzanie bazą danych bez znajomości SQL. Narzędzie umożliwia zarówno prosty podgląd, jak i złożone filtrowanie w czasie, po jednostkach, procesach i metadanych.

Filtrowanie po jednostkach, priorytetach i czasie

Najczęstszy scenariusz to analiza konkretnej usługi. Podstawowa forma to:

journalctl -u nazwa-uslugi.service

Dodanie parametru -xe rozszerza widok o bardziej szczegółowe komunikaty i kontekst błędów:

journalctl -u nazwa-uslugi.service -xe

Filtrowanie czasowe opiera się na opcjach --since i --until, które przyjmują wygodne formaty:

journalctl --since "2026-07-01 10:00" --until "2026-07-01 12:00"
journalctl --since "1 hour ago"
journalctl --since yesterday -u sshd.service

Priorytet określa się parametrem -p, np.:

journalctl -p err..alert
journalctl -p warning -u nginx.service --since today

Punkt kontrolny: zespół utrzymaniowy powinien mieć zdefiniowany minimalny zestaw „komend pierwszej reakcji” dla najważniejszych usług. Jeżeli przy każdym incydencie ktoś musi „szukać w Google” jak przefiltrować logi po czasie i priorytecie, oznacza to brak podstawowych procedur operacyjnych.

Jeśli w codziennej praktyce używa się wyłącznie journalctl -u usluga bez zawężenia czasu i priorytetu, to diagnoza awarii często przeplata się z losowymi, nieistotnymi wpisami – a czas reakcji wydłuża się niepotrzebnie.

Metadane journald jako narzędzie audytowe

journald przechowuje bogaty zestaw pól metadanych: _PID, _UID, _GID, _SYSTEMD_UNIT, _BOOT_ID, _CMDLINE i wiele innych. Można po nich filtrować lub wyświetlać je w surowej postaci:

journalctl _PID=1234
journalctl _SYSTEMD_UNIT=sshd.service _UID=0
journalctl -o verbose -u sshd.service --since "2026-07-01"

Przykładowo, podczas analizy nieautoryzowanego uruchomienia procesu można zawęzić logi do konkretnego _CMDLINE lub _UID. To funkcjonalność, której nie daje klasyczny, płaski plik tekstowy bez dodatkowego parsowania.

Punkt kontrolny: podczas audytu przydatne jest zadanie prostego zadania zespołowi – np. „pokaż wszystkie wpisy journald pochodzące z sshd uruchomionego w tym bootowaniu, ale tylko z UID 0”. Jeśli odpowiedź sprowadza się do ręcznego przeszukiwania plików tekstowych w /var/log, integracja z journald jest używana w minimalnym zakresie.

Jeżeli zespół traktuje journald wyłącznie jako „źródło” dla rsyslog i nigdy nie korzysta z filtrowania po metadanych, to część potencjału narzędzia pozostaje niewykorzystana, a analiza incydentów jest niepotrzebnie utrudniona.

Tryby wyjścia i eksport: od podglądu po archiwizację

journalctl potrafi generować logi w różnych formatach. W codziennym użyciu przydaje się:

  • -o short (domyślny) – skondensowany widok tekstowy,
  • -o short-iso – daty w formacie ISO z informacją o strefie czasowej (ważne przy korelowaniu z innymi systemami),
  • -o json, -o json-pretty – logi w JSON, wygodne dla zewnętrznych narzędzi,
  • -o verbose – pełne listy pól metadanych.
journalctl -u nginx.service --since today -o short-iso
journalctl -u app.service --since "2026-07-01" -o json-pretty > app-logs.json

Dla potrzeb archiwizacji i przenoszenia logów między systemami journald oferuje własny format binarny:

journalctl --since "2026-07-01" --until "2026-07-02" 
  -u app.service --output=export > app-logs.export

# zaimportowanie na innym systemie
journalctl --file=app-logs.export

To wygodny sposób na przekazanie pełnego kontekstu incydentu do analizy offline, bez konieczności kopiowania całego katalogu /var/log/journal.

Jeżeli jedynym stosowanym mechanizmem eksportu jest „kopiuj całe /var/log/journal tar-em”, można to traktować jako sygnał ostrzegawczy – brak znajomości natywnego formatu eksportu utrudnia selektywną archiwizację i transmisję danych do zewnętrznych zespołów (np. zespołu dochodzeniowego).

Analiza „na żywo” i korelacja z innymi źródłami

Do obserwacji bieżących zdarzeń używa się journalctl -f, które jest odpowiednikiem tail -f dla journald:

journalctl -u app.service -f
journalctl -f -p warning

W praktyce często zachodzi potrzeba korelacji logów z kilku usług. Dobrym wzorcem jest krótkoterminowe zapisywanie ich do osobnych plików i praca na nich równolegle:

journalctl -u app.service --since "2026-07-01 10:00" -o short-iso > app.log
journalctl -u postgres.service --since "2026-07-01 10:00" -o short-iso > db.log

Takie podejście pozwala użyć tradycyjnych narzędzi (grep, awk, diff) do korelacji czasowej, przy jednoczesnym zachowaniu zalet journald przy wyszukiwaniu i selekcji danych.

Punkt kontrolny: jeżeli w organizacji nie ma ustalonej metody korelowania zdarzeń pomiędzy usługami (wspólny format daty, strefa czasowa, procedura zapisu do plików), analiza bardziej złożonych incydentów zamienia się w improwizację. Minimum to standard -o short-iso przy eksporcie i jednolita strefa czasowa w logach na wszystkich serwerach objętych incydentem.

Ekran terminala MS-DOS na klawiaturze laptopa w ciemnym otoczeniu
Źródło: Pexels | Autor: Rafael Minguet Delgado

Rsyslog – rola, moduły wejściowe i typowe konfiguracje

rsyslog funkcjonuje zwykle jako warstwa pośrednia między journald a docelowymi miejscami przechowywania logów. Jego siłą jest modularność i rozbudowane możliwości filtrowania, ale ta sama cecha bywa źródłem złożoności i błędów konfiguracyjnych.

Podstawowe źródła wejściowe: imuxsock, imjournal, imtcp

Rsyslog odbiera logi poprzez tzw. moduły wejściowe. Z punktu widzenia integracji z journald trzy moduły pojawiają się najczęściej:

  • imuxsock – tradycyjny moduł nasłuchujący na gnieździe /dev/log. Używany głównie tam, gdzie aplikacje logują poprzez klasyczne wywołania syslog, a journald nie jest głównym kolektorem. W środowiskach z systemd często powinien być wyłączony lub ograniczony, aby uniknąć duplikacji komunikatów (aplikacja → journald → rsyslog oraz aplikacja → rsyslog bezpośrednio).
  • imjournal – moduł czytający bezpośrednio z journald, wykorzystujący jego API. To standardowy sposób integracji rsyslog z systemd; umożliwia przenoszenie dalej logów już znormalizowanych przez journald, z zachowaniem kontekstu bootowania i podstawowych metadanych.
  • imtcp (i analogicznie imudp) – moduły odbierające logi po sieci w klasycznym formacie syslog (TCP/UDP). W praktyce są używane do przyjmowania logów z innych serwerów lub urządzeń sieciowych, które nie znają journald.

Punkt kontrolny: w konfiguracji rsyslog na hostach z systemd należy jasno określić, czy głównym źródłem jest imjournal, a imuxsock pełni jedynie funkcję awaryjną, czy odwrotnie. Jeżeli w katalogach z logami widać oczywiste duplikaty tych samych komunikatów różniących się jedynie prefiksem lub timestampem, jest to sygnał ostrzegawczy wskazujący na podwójny odbiór logów.

Typowy przepływ: z journald do plików i dalej do SIEM

Praktyczna konfiguracja rsyslog w środowisku serwerowym zwykle składa się z kilku etapów. journald zbiera logi ze wszystkich jednostek systemd, następnie imjournal przekazuje je do rsyslog. Tam następuje filtracja po poziomie, źródle lub facility, a na końcu zapis do plików w /var/log oraz, opcjonalnie, wysyłka do centralnego systemu logowania lub SIEM.

Przykładowy, uproszczony schemat: logi systemowe i aplikacyjne trafiają do plików rotowanych przez logrotate, logi bezpieczeństwa (ssh, sudo, firewall) są kopiowane lub przekazywane strumieniowo do zewnętrznego odbiorcy po TCP z TLS, a komunikaty informacyjne pozostają lokalnie. Taki układ pozwala ograniczyć wolumen danych przekazywanych do SIEM, jednocześnie nie gubiąc lokalnego kontekstu w journald.

Punkt kontrolny: jeśli wszystkie logi (łącznie z bardzo szczegółowymi komunikatami debug) są bezrefleksyjnie przesyłane do zewnętrznego systemu, a lokalne pliki są nieczytelne lub niekompletne, oznacza to brak przemyślanej polityki kategoryzacji i retencji. Minimum to wyraźny podział: co musi wyjść z serwera w trybie „prawie na żywo”, a co może zostać wyłącznie lokalnie w journald i na dysku.

Filtry, szablony i formatowanie – miejsce na błędy

Jedną z głównych zalet rsyslog jest możliwość budowania złożonych warunków filtrowania oraz definiowania szablonów formatujących wpisy logów. Używa się tego m.in. do rozdzielania logów aplikacji do osobnych plików, dopisywania identyfikatorów hosta lub środowiska (dev/test/prod) czy generowania formatu wymaganego przez zewnętrzny SIEM.

Typowy błąd konfiguracyjny to nadmiernie skomplikowane reguły, których nikt nie potrafi już wytłumaczyć. Jeśli filtracja jest oparta na kilku nakładających się warunkach (facility, poziom, dopasowanie tekstowe do wiadomości) i brak jej dokumentacji, ryzyko nieświadomego wycinania istotnych zdarzeń jest bardzo wysokie. Z drugiej strony brak jakichkolwiek filtrów powoduje, że system centralny jest zalewany nadmiarem informacji, przez co krytyczne alerty giną w szumie.

Punkt kontrolny: przegląd konfiguracji rsyslog powinien obejmować listę zdefiniowanych szablonów i reguł filtrowania wraz z ich krótkim uzasadnieniem. Jeżeli zespół nie jest w stanie odpowiedzieć, dlaczego określona klasa logów trafia do konkretnego pliku lub zewnętrznego odbiorcy, konfiguracja jest przypadkowa, a zgodność z wymaganiami audytowymi – wątpliwa.

Dodatkowym polem minowym są szablony generujące niestandardowe formaty, szczególnie wtedy, gdy różnią się między środowiskami. Minimalny zestaw pytań kontrolnych to: czy wszystkie logi wysyłane do jednego odbiorcy mają ten sam format, czy timestamp jest jednoznaczny i parsowalny, czy separatory pól nie kolidują z potencjalną treścią komunikatów. Jeżeli ten sam strumień logów jest raz zapisywany lokalnie w jednym formacie, a raz wysyłany do SIEM w innym, integracja analityczna po drugiej stronie staje się krucha i podatna na błędy przy każdej drobnej zmianie konfiguracji.

Konfigurując filtry i szablony, dobrym podejściem jest zasada „najpierw prosto, potem precyzyjnie”: najpierw wdrożenie prostego podziału (np. system, aplikacje, bezpieczeństwo), dopiero później stopniowe uszczegóławianie reguł na podstawie realnych potrzeb analitycznych i audytowych. Każda nowa reguła powinna mieć krótki opis celu, datę wprowadzenia oraz informację, kto ją zatwierdził. Brak takiej „metryczki” przy złożonych konfiguracjach jest sygnałem ostrzegawczym – po kilku miesiącach nikt nie będzie pamiętał, czy daną linię można bezpiecznie usunąć, czy jest krytyczna dla zgodności z polityką bezpieczeństwa.

W praktyce dobrze działa podejście, w którym najpierw włącza się logowanie „nadmiarowe” do osobnego pliku testowego, analizuje faktyczny rozkład typów zdarzeń, a dopiero potem przenosi zaakceptowane reguły do głównej konfiguracji produkcyjnej. Pozwala to uniknąć sytuacji, w której po wprowadzeniu nowego filtra nagle „znika” istotna kategoria zdarzeń (np. nietypowe błędy bazy danych), co ujawnia się dopiero przy pierwszym incydencie. Jeżeli zmiany w regułach rsyslog nie są poprzedzone choćby kilkudniowym okresem obserwacji w trybie „shadow logging”, jest to punkt kontrolny do odnotowania w audycie.

Cały łańcuch logowania – od aplikacji, przez journald i rsyslog, aż po centralny system – działa skutecznie tylko wtedy, gdy jest zaprojektowany jako spójny proces, a nie zbiór przypadkowych ustawień. Jeśli logi są kompletne, łatwe do korelacji w czasie i dostępne zarówno lokalnie, jak i z perspektywy audytora czy analityka bezpieczeństwa, system spełnia swoją funkcję. Jeżeli natomiast analiza incydentu zaczyna się od ręcznego szukania, „gdzie w ogóle są logi z tego serwera”, to czytelny sygnał ostrzegawczy, że architektura logowania wymaga uporządkowania.

Centralne logowanie z rsyslog: projektowanie relacji „log source → log collector”

Budowa centralnego systemu logowania na bazie rsyslog wymaga kilku świadomych decyzji architektonicznych. Niewłaściwie dobrany model (wszystko wszędzie, bez filtrów i standaryzacji) szybko zamienia się w magazyn nieprzeszukiwalnych danych, który ani nie wspiera reagowania na incydenty, ani nie spełnia wymogów audytowych.

Tryby pracy: agent na hoście vs koncentrator logów

Rsyslog może funkcjonować zarówno jako lokalny agent zbierający logi z journald i wysyłający je dalej, jak i jako centralny koncentrator przyjmujący logi z wielu hostów. W większych środowiskach te role zwykle się rozdziela: na każdym serwerze działa lekka konfiguracja agenta, a osobne, dobrze zabezpieczone hosty pełnią rolę hubów logów.

Podstawowe warianty:

  • Agent-only – rsyslog na serwerze pełni głównie funkcję „forwardera”: czyta z imjournal, wykonuje minimalną filtrację i wysyła logi po TCP/TLS do centralnego kolektora. Lokalne pliki są ograniczone (np. tylko krytyczne błędy).
  • Hybrid – rsyslog zarówno zapisuje logi lokalnie (pełne lub częściowe), jak i wysyła wybrane kategorie do centralnego systemu. To najczęstszy i najbezpieczniejszy scenariusz w środowiskach produkcyjnych.
  • Collector-only – rsyslog na hostach działa w trybie minimalnym lub wcale, a logi trafiają bezpośrednio do centralnego systemu z pominięciem lokalnego zapisu. Ten wariant jest rzadko uzasadniony poza specyficznymi środowiskami z bardzo restrykcyjną polityką danych na endpointach.

Punkt kontrolny: jeżeli nie istnieje udokumentowana decyzja, czy host jest w danej roli „agentem”, „kolektorem” czy „hybrydą”, konfiguracje będą się różnić przypadkowo. Jeżeli na części serwerów logi są trzymane wyłącznie lokalnie, a na innych wyłącznie centralnie, przy pierwszym incydencie powstanie nieciągła oś czasu, a analiza okaże się częściowo losowa.

Transport TCP/TLS, kolejkowanie i niezawodność

Dane logowe są często traktowane jako „drugorzędne”, co skutkuje wysyłką po UDP bez zabezpieczeń i bez jakiejkolwiek kontroli dostarczenia. Z perspektywy audytora to typowa słabość: nie ma pewności, czy log dotarł do centralnego systemu ani kto mógł go po drodze podsłuchać lub zmodyfikować.

Rsyslog wspiera bezpieczny transport TCP/TLS oraz rozbudowane mechanizmy kolejkowania. Minimalny zestaw praktyk przy projektowaniu transportu do kolektora:

  • Wymuszenie połączeń TCP z TLS (moduł omfwd z parametrami StreamDriver="gtls", StreamDriverMode="1", weryfikacja certyfikatu kolektora).
  • Użycie asynchronicznych kolejek dyskowych lub hybrydowych (pamięć + dysk) po stronie agenta, aby chwilowa niedostępność kolektora nie skutkowała utratą logów.
  • Jawne określenie polityki w razie przepełnienia kolejki: czy host ma wtedy odrzucać nowe logi, czy porzucać najstarsze – brak decyzji oznacza nieprzewidywalne zachowanie przy awarii kolektora.

Prosty przykład konfiguracji wysyłki z lokalnego rsyslog do kolektora po TCP/TLS:

module(load="omfwd")
module(load="gtls")

# parametry TLS (ścieżki przykładowe)
global(
  DefaultNetstreamDriver="gtls"
  DefaultNetstreamDriverCAFile="/etc/rsyslog.d/ca.pem"
  DefaultNetstreamDriverCertFile="/etc/rsyslog.d/client.pem"
  DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/client.key"
)

# kolejka trwała dla wyjścia sieciowego
$WorkDirectory /var/spool/rsyslog
$ActionQueueType LinkedList
$ActionQueueFileName fwdqueue
$ActionQueueMaxDiskSpace 1g
$ActionResumeRetryCount -1
$ActionQueueSaveOnShutdown on

# wysyłka wszystkich logów do kolektora
*.* action(
  type="omfwd"
  target="log-collector01.example.com"
  port="6514"
  protocol="tcp"
  StreamDriverMode="1"
  StreamDriverAuthMode="x509/name"
  StreamDriverPermittedPeers="log-collector01.example.com"
)

Punkt kontrolny: jeśli po stronie kolektora nie ma śladu spodziewanych logów, a na hostach nie istnieje żaden monitoring stanu kolejek rsyslog, brak dowodu dostarczenia będzie istotnym problemem w audycie. Jeżeli transport odbywa się po UDP bez TLS, to jest to wręcz podręcznikowy sygnał ostrzegawczy dla danych o znaczeniu dowodowym.

Standaryzacja formatów dla centralnego odbiorcy

System SIEM lub inny centralny kolektor logów ma określone oczekiwania co do formatu. W praktyce ryzyko błędów wynika z sytuacji, w której te same dane są dostarczane w kilku różnych wariantach, zależnie od serwera, wersji rsyslog czy lokalnej „twórczości” administratora.

Bezpieczny model zakłada zdefiniowanie jednego szablonu wyjściowego dla danej klasy odbiorców i stosowanie go konsekwentnie na wszystkich hostach. Przykładowo – prosty format „key=value” z jednoznacznym timestampem:

template(name="siemTemplate" type="string"
  string="ts=%timereported:::date-rfc3339% host=%hostname% app=%programname% 
pid=%procid% msg=%msg%n")

*.* action(
  type="omfwd"
  target="siem.example.com"
  port="6514"
  protocol="tcp"
  template="siemTemplate"
)

Kluczowe pytania przy ocenie szablonów:

  • Czy timestamp jest jednoznaczny (data, czas, strefa/offset, brak skrótów zależnych od locale)?
  • Czy pola są rozdzielone w sposób, który nie koliduje z treścią komunikatu (np. uniknięcie surowych przecinków lub średników jako jedynego separatora)?
  • Czy nazwy pól są spójne między hostami (np. zawsze app=, a nie raz program=, innym razem service=)?

Punkt kontrolny: jeśli integrator SIEM musiał stworzyć osobne parsery dla każdego typu serwera lub środowiska, winna jest zwykle brakująca standaryzacja szablonów w rsyslog. Jeżeli różnice w formacie nie są w żaden sposób opisane, każdy większy upgrade rsyslog lub zmiana konfiguracji grozi „po cichu” zepsutą korelacją zdarzeń.

Separacja strumieni: co centralnie, co lokalnie

Nie wszystkie logi muszą lądować w centralnym systemie. Zbieranie wszystkiego „jak leci” jest kuszące na początku, ale szybko prowadzi do kosztów (licencyjnych, wydajnościowych) oraz trudności analitycznych. Rolą rsyslog jest w tym miejscu rozsądny podział na kilka głównych kategorii.

Przykładowy, przejrzysty podział:

  • Bezpieczeństwo (ssh, sudo, firewall, audyt systemowy) – wysyłane w trybie near real-time do SIEM, często z kopią lokalną o dłuższej retencji.
  • Krytyczne logi aplikacyjne – również kierowane centralnie, przynajmniej na środowiskach produkcyjnych.
  • Logi informacyjne i debug – przechowywane lokalnie (journald + rotowane pliki), z możliwością eksportu na żądanie.

Konfiguracja może wyglądać np. tak:

# logi bezpieczeństwa – lokalnie + SIEM
if (
  $programname == "sshd"
  or $programname == "sudo"
  or $syslogfacility-text == "authpriv"
  or $syslogfacility-text == "kern"
) then {
  action(type="omfile" file="/var/log/security.log")
  action(type="omfwd" target="siem.example.com" port="6514" protocol="tcp"
         template="siemTemplate")
  stop
}

# reszta – lokalnie, bez wysyłki
*.* action(type="omfile" file="/var/log/messages")

Punkt kontrolny: jeśli polityka „co wysyłamy centralnie” nie jest opisana, a jedyne kryterium brzmi „wszystko, co się da”, to w dłuższej perspektywie prowadzi to do technicznej i kosztowej spirali. Odwrotna skrajność – wysyłanie niemal niczego – oznacza z kolei, że centralne narzędzia bezpieczeństwa działają w zasadzie „w ciemno” i nie są w stanie potwierdzić pełności obrazu zdarzeń.

Przejrzysta struktura logów na dysku: katalogi, rotacja, retencja

Nawet przy obecności journald i centralnego kolektora, lokalne pliki logów pozostają podstawowym źródłem informacji w wielu scenariuszach – od szybkiego debugowania po analizę incydentu, gdy dostęp do sieci jest ograniczony. Chaotyczny układ plików w /var/log to klasyczny problem: wszystko formalnie „jest”, ale znalezienie czegokolwiek trwa zbyt długo.

Układ katalogów: minimum czytelności

Domyślne rozmieszczenie logów różni się w zależności od dystrybucji, ale ogólna zasada powinna być wspólna: logiczny podział według funkcji, a nie według tego, „jak pakiet je zainstalował”. W praktyce oznacza to przynajmniej:

  • wydzielenie katalogu na logi aplikacji biznesowych (np. /var/log/apps/),
  • spójne nazewnictwo plików (np. appname.log, a nie mieszanka rozszerzeń i formatów),
  • oddzielenie logów systemowych, sieciowych i bezpieczeństwa w sposób zgodny z polityką organizacji.

Przykładowy, przejrzysty układ:

/var/log/
  messages
  secure
  cron
  audit/
    audit.log
  apps/
    web-frontend/
      web-frontend.log
      access.log
      error.log
    payments/
      payments.log
  rsyslog/
    rsyslogd.log

Punkt kontrolny: jeżeli zespół nie potrafi odpowiedzieć, w którym pliku znajdują się logi kluczowej aplikacji, lub nazewnictwo plików różni się między serwerami tej samej roli, to sygnał ostrzegawczy. Jeżeli dodatkowo logi aplikacji trafiają „gdzieś do /tmp” według uznania dewelopera, audyt ciągłości i kompletności jest de facto niewykonalny.

Logrotate i rotacja logów tworzonych przez rsyslog

Rsyslog z reguły polega na zewnętrznym mechanizmie rotacji plików, takim jak logrotate. Brak spójnej konfiguracji rotacji prowadzi do dwóch typowych problemów: albo logi rosną bez końca, ryzykując zapełnienie dysku, albo są nadmiernie kasowane, przez co okres retencji jest znacznie krótszy niż deklarowany w politykach.

W pliku konfiguracyjnym /etc/logrotate.d/<nazwa> należy jasno określić:

  • częstotliwość rotacji (daily, weekly),
  • liczbę przechowywanych kopii (rotate N),
  • kompresję (compress),
  • reakcję rsyslog na zmianę pliku (postrotate z systemctl kill -s HUP rsyslog lub systemctl reload).

Przykład dla pliku /var/log/apps/web-frontend/web-frontend.log:

/var/log/apps/web-frontend/web-frontend.log {
    daily
    rotate 14
    compress
    missingok
    notifempty
    create 0640 webapp adm
    postrotate
        /bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
    endscript
}

Punkt kontrolny: jeśli rotacja jest ustawiona „na oko” (inne parametry na każdym serwerze tej samej klasy) lub brak jej w ogóle, to sprzeczność z deklarowaną polityką retencji. Jeżeli przy rotacji rsyslog nie otrzymuje sygnału HUP, logi mogą zacząć trafiać do nieistniejących plików lub zatrzymać się do czasu restartu usługi – sygnał ostrzegawczy w środowiskach, gdzie ciągłość logowania ma znaczenie dowodowe.

Retencja, pojemność i dowody z logów

Polityka retencji logów powinna wynikać z wymagań prawnych i bezpieczeństwa, a nie przypadkowej konfiguracji logrotate. Sytuacja, w której aplikacja krytyczna ma lokalne logi tylko z ostatnich kilku dni, jest częsta i zwykle odkrywana dopiero przy analizie incydentu.

Przy projektowaniu retencji warto przejść przez kilka kroków:

  • określić minimalny okres przechowywania dla logów bezpieczeństwa, aplikacyjnych i systemowych (np. 6/12/24 miesiące),
  • zdecydować, jaka część tego okresu jest realizowana lokalnie, a jaka w centralnym repozytorium lub archiwum offline,
  • policzyć realny rozmiar dzienny logów na typowym serwerze i zweryfikować, czy założone parametry rotate i size faktycznie to zapewniają.

Punkt kontrolny: jeśli deklarowany w polityce okres retencji nie ma odzwierciedlenia w konfiguracji logrotate i ustawieniach SIEM, jest to wyłącznie zapis na papierze. Jeżeli brak regularnego monitoringu zajętości /var/log i brak procedury reagowania na zbliżanie się do 100% wykorzystania dysku, prędzej czy później dojdzie do sytuacji, w której system przestanie logować w najgorszym możliwym momencie.

Uzgadnianie journald i rsyslog: unikanie duplikacji i luk

systemd-journald i rsyslog mogą ze sobą współpracować bardzo dobrze, ale tylko wtedy, gdy ich role są świadomie zdefiniowane. W praktyce często występują dwa skrajne zjawiska: podwójne logowanie tych samych komunikatów oraz niezamierzona luka, w której część zdarzeń nie trafia ani do journald, ani do plików rsyslog.

Jasny podział ról: kto jest źródłem prawdy

Podstawowe pytanie brzmi: który komponent traktujemy jako „źródło prawdy” dla logów lokalnych. Typowy, dojrzały model zakłada, że journald zbiera wszystko (w tym logi z gniazd systemd i standardowych strumieni procesów), a rsyslog pełni głównie rolę „mostu” do plików tekstowych oraz systemów zewnętrznych. W takim układzie nie ma potrzeby, aby aplikacje logowały równolegle do journald i bezpośrednio do plików – to prosta droga do niespójności, szczególnie przy analizie incydentu, gdy godziny lub identyfikatory zdarzeń zaczynają się rozmijać.

Minimalny zestaw ustaleń dla zespołu infrastruktury:

  • czy każda aplikacja ma używać standardowego wyjścia / stderr (przez systemd) czy dedykowanego sysloga,
  • czy przyjmujemy zasadę, że wszystkie zdarzenia z aplikacji muszą być widoczne w journalctl,
  • jakie klasy logów rsyslog ma zawsze zapisywać do plików (np. /var/log/messages, /var/log/secure), a jakie wyłącznie forwardować dalej.

Punkt kontrolny: jeżeli różni administratorzy odpowiadają inaczej na pytanie „gdzie jest pełny zapis zdarzeń z ostatnich 24 godzin na tym serwerze?”, to sygnał ostrzegawczy. Jeżeli dodatkowo część aplikacji omija systemd i syslog, zapisując logi we własnych katalogach bez kopii w journald, spójna rekonstrukcja incydentu staje się w praktyce nierealna.

Konfiguracja forwardowania z journald do rsyslog

Aby uniknąć luk, trzeba wprost zdefiniować, jak journald przekazuje komunikaty do rsyslog. W systemach, gdzie rsyslog ma przetwarzać logi z journald, kluczowe są dwa elementy: włączenie socketu systemd-journald-dev-log lub imjournal w rsyslog oraz wyłączenie niepotrzebnych, historycznych wejść (np. imuxsock nasłuchującego na /dev/log, jeśli journald już tam przekazuje dane).

Przykładowa, uporządkowana konfiguracja wejścia w /etc/rsyslog.d/10-input.conf:

# wejście z journald – jedno, spójne źródło
module(load="imjournal" StateFile="imjournal.state" RatelimitInterval="0")

# opcjonalnie, wyłączenie klasycznego gniazda /dev/log,
# jeżeli wszystko i tak przechodzi przez journald
#module(load="imuxsock" SysSock.Use="off")

Punkt kontrolny: jeśli jednocześnie aktywne są moduły imjournal i imuxsock bez jasnej koncepcji, to wysokie ryzyko podwójnego logowania tych samych komunikatów. Jeżeli rsyslog nie ma żadnego wejścia z journald, a aplikacje nie wysyłają logów po syslogu, część zdarzeń może istnieć tylko w pamięci journald przez krótki czas, po czym zostanie bezpowrotnie utracona.

Ograniczanie duplikacji: filtry, facility i tagi

Duplikacja logów zwykle wynika z braku filtrów lub niejednoznacznego użycia facility i tagów. Prosty przykład: logi sshd trafiają do journald, stamtąd do rsyslog, a jednocześnie sshd jest skonfigurowany do bezpośredniego wysyłania do sysloga – efekt to dwa identyczne wpisy w SIEM i podwójny wolumen licencjonowany. Rozwiązaniem jest konsekwentne korzystanie z jednego kanału i doprecyzowanie filtrów po stronie rsyslog.

Przed wdrożeniem filtrów warto przeprowadzić krótki „inwentarz”:

  • sprawdzić, które demony i aplikacje mają własne ustawienia sysloga (np. w /etc/rsyslog.conf, /etc/syslog-ng.conf, plikach konfiguracyjnych usług),
  • ustalić, czy którykolwiek z nich wysyła logi zarówno do journald, jak i bezpośrednio do rsyslog/remote syslog,
  • dla kluczowych aplikacji określić docelowy facility i tag, a w rsyslog dopasować reguły tak, aby każda wiadomość była przetwarzana tylko raz.

Przy porządkowaniu filtrów dobrze sprawdza się metoda „od ogółu do szczegółu”: najpierw reguły odfiltrowujące oczywiste duplikaty (np. identyczne facility i tag z dwóch źródeł), potem dopiero precyzyjne dopasowania dla wybranych aplikacji. W rsyslog można to zrealizować, stosując warunki na polach strukturalnych oraz wyraźnie oznaczając komunikaty pochodzące z journald. Przykładowo, jeśli dana aplikacja ma logować wyłącznie przez systemd, reguły obsługujące jej dawny kanał syslogowy powinny zostać usunięte lub przynajmniej przeniesione do sekcji nieaktywnej z jasnym komentarzem „deprecated”.

Dobrym nawykiem jest wprowadzenie prostego nazewnictwa tagów i facility: aplikacje biznesowe z przypisanym facility (np. local0local3), komponenty infrastruktury z innym zakresem, a logi techniczne (debug, trace) trzymane osobno od zdarzeń istotnych dowodowo. Im mniej wyjątków od tej zasady, tym łatwiej później wykryć nieoczekiwane zachowanie – duży przyrost logów w local0 nagle kierowany do /var/log/messages zamiast do dedykowanego pliku to prosty sygnał, że ktoś ominął ustalone reguły. Jeżeli w regułach rsyslog zaczynają pojawiać się dziesiątki niemal identycznych warunków, a jedyna różnica to tag lub facility, architektura logowania wymaga przeglądu, a nie kolejnego wyjątku.

Przy audycie konfiguracji rsyslog dobrze sprawdza się krótka lista pytań kontrolnych: czy dla każdej kluczowej aplikacji istnieje dokładnie jedno źródło logów (journald lub syslog), czy reguły przetwarzające daną klasę zdarzeń pojawiają się tylko raz, czy w SIEM nie ma widocznych par komunikatów o tym samym czasie i treści, ale innym źródle. Jeżeli analiza krótkiego wycinka logów z jednej godziny ujawnia liczne duplikaty z różnych ścieżek (np. „journald->rsyslog” oraz „aplikacja->remote syslog”), koszt licencyjny i szum analityczny są tylko kwestią czasu.

Dojrzała konfiguracja logowania w Linuksie to nie zbiór domyślnych plików, lecz świadomie zaprojektowany układ ról: journald jako spójny bufor i punkt zbierania, rsyslog jako kontrolowany przetwórca i dystrybutor, a nad nimi jasne zasady retencji i odpowiedzialności. Jeśli na podstawowe pytania – gdzie jest pełny zapis zdarzeń, jak długo jest przechowywany i którędy przepływa – można odpowiedzieć jednym, spójnym diagramem, ryzyko sporów dowodowych i „znikających logów” istotnie maleje.

Najczęściej zadawane pytania (FAQ)

Po co są logi w Linuksie i kto faktycznie z nich korzysta?

Logi w Linuksie są podstawowym źródłem informacji o tym, co dzieje się w systemie: od błędów aplikacji, przez awarie usług, po działania użytkowników i administratorów. Administrator wykorzystuje je do diagnozy i debugowania incydentów, a audytor – do oceny zgodności z wymaganiami bezpieczeństwa i rekonstrukcji zdarzeń.

Kluczowi „odbiorcy” logów to: zespół utrzymania (diagnostyka), zespół bezpieczeństwa (forensic i detekcja incydentów), audyt wewnętrzny/zewnętrzny (zgodność z politykami, normami). Sygnałem ostrzegawczym jest sytuacja, w której żadna z tych grup nie umie jasno powiedzieć, gdzie znajdują się kompletne logi dla danej usługi.

Czym różni się journald od rsyslog i czy potrzebuję obu?

systemd-journald zbiera logi z kernela, usług systemd i aplikacji logujących na stdout/stderr. Przechowuje je w formie binarnej, z bogatym zestawem pól strukturalnych (czas, PID, jednostka systemd, użytkownik), co ułatwia filtrowanie i korelację zdarzeń. Z poziomu audytu to „źródło prawdy” o tym, co widzi systemd.

rsyslog (lub syslog-ng) to klasyczny daemon syslog, który odbiera logi przez interfejs syslog(), zapisuje je w plikach tekstowych i często wysyła dalej na zewnętrzne serwery logów lub SIEM. W wielu środowiskach journald i rsyslog współpracują: journald odbiera wszystko lokalnie, a rsyslog odpowiada za trwały zapis w /var/log i wysyłkę zdalną. Jeśli jeden z tych elementów jest wyłączony lub źle spięty, pojawia się punkt kontrolny do natychmiastowego sprawdzenia.

Gdzie w Linuksie szukać logów systemowych i aplikacyjnych?

Standardowe miejsce logów systemowych to /var/log oraz dziennik journald odczytywany poleceniem journalctl. Komunikaty kernela i usług systemd znajdziesz zwykle w journalu, a klasyczne logi syslog – w plikach typu /var/log/messages, /var/log/syslog, /var/log/auth.log (w zależności od dystrybucji).

Aplikacje często mają własne katalogi logów, np. /var/log/<nazwa_aplikacji> lub /opt/app/logs. Część loguje wyłącznie na stdout/stderr, licząc na przechwycenie przez systemd. Sygnałem ostrzegawczym jest sytuacja, gdy dla krytycznej aplikacji nie ma jasnej, udokumentowanej odpowiedzi: „tu są wszystkie jej logi, o takiej retencji”.

Jak sprawdzić, czy mój system logowania spełnia minimum w środowisku produkcyjnym?

Podstawowe punkty kontrolne to: czy journald działa w trybie persistent (logi przetrwają restart), czy jest jasno określone, jakie logi trafiają do /var/log i jak są rotowane (logrotate), oraz czy istnieje mechanizm wysyłki kluczowych logów na zewnętrzny serwer lub SIEM. Bez tego system jest podatny na utratę historii zdarzeń i „wyciemnione” okresy.

Praktyczny test: wybierz losową, istotną usługę (np. sshd, nginx, system billingowy) i spróbuj odtworzyć jej historię z ostatnich dni: start/stop, błędy, loginy użytkowników. Jeśli nie jesteś w stanie tego zrobić szybko i kompletnie, system logowania nie spełnia minimum i wymaga korekty konfiguracji oraz dokumentacji.

Jakie są skutki braku spójnej polityki logowania w Linuksie?

Najczęstsze skutki to: brak możliwości rzetelnej analizy incydentu (dziury czasowe w logach, brak kluczowych komunikatów), dublowanie danych (te same logi w journalu i wielu plikach), problemy z przestrzenią dyskową oraz brak odpowiedzialności za konfigurację logowania. W praktyce kończy się to zgadywaniem przy awariach i słabą audytowalnością systemu.

Typowy scenariusz ostrzegawczy: usługa pada, w journalctl i /var/log brak istotnych wpisów, logi okazują się w niestandardowym katalogu aplikacji, a część historii zniknęła po restarcie, bo journald działał w trybie volatile. Jeśli taki przypadek jest realny w twoim środowisku, polityka logowania wymaga natychmiastowego uporządkowania.

Jakie cechy powinien mieć dobrze zaprojektowany system logów w Linuksie?

Dobrze zaprojektowany system logowania musi zapewniać: kompletność (wszystkie istotne źródła logują do przewidywalnego strumienia), spójność i strukturę (jednolity format, jasne pola: timestamp, poziom, jednostka, PID, użytkownik), odporność na awarie (limity, kolejki, sensowne domyślne zachowanie przy pełnym dysku) oraz kontrolowaną retencję (rotacja, przechowywanie lokalne i zdalne).

Jeśli brakuje choć jednego z tych elementów, pojawia się luka: analiza jest kosztowna, logi znikają albo zapychają dyski, a audytor nie może jednoznacznie odpowiedzieć, „co się naprawdę wydarzyło”. Z perspektywy jakości to sygnał ostrzegawczy, że system logowania nie pełni roli narzędzia dowodowego, a jedynie „kosza” na komunikaty.

Jak ograniczyć ryzyko utraty logów i problemów przy dużej ilości komunikatów?

Kluczowe jest skonfigurowanie mechanizmów ochronnych: tryb persistent w journald z limitami wykorzystania dysku, limitowanie tempa logowania (rate limiting) przy pętlach błędów, kolejki dyskowe w rsyslog oraz sensownie ustawiony logrotate dla plików w /var/log. Dzięki temu gwałtowny wzrost liczby logów nie zablokuje systemu ani nie „wypycha” najważniejszych wpisów.

Dodatkowy punkt kontrolny to wysyłanie krytycznych logów (bezpieczeństwo, transakcje, dostęp administracyjny) na zewnętrzny serwer. Jeśli lokalny host zostanie utracony lub zniszczony, zewnętrzna kopia logów nadal umożliwia analizę i audyt. Brak takiego mechanizmu w środowisku krytycznym to poważny sygnał ostrzegawczy dla każdego audytora bezpieczeństwa.

Opracowano na podstawie

  • The Linux Programming Interface. No Starch Press (2010) – Mechanizmy jądra, syslog, zarządzanie logami w Linuksie
  • systemd System and Service Manager – man pages (systemd-journald, journalctl). freedesktop.org – Dokumentacja journald, pola strukturalne, trwałość i filtracja logów
  • rsyslog Documentation. Adiscon GmbH – Architektura rsyslog, kolejki, formatowanie, wysyłka zdalna logów
  • syslog-ng Premium Edition Administrator Guide. One Identity – Koncepcje syslog, źródła logów, filtry, cele zapisu i bezpieczeństwo
  • ISO/IEC 27001 Information security management systems – Requirements. International Organization for Standardization (2013) – Wymagania dot. logowania, audytu i retencji w systemach IT