Konfiguracja journald - journald.conf
Wprowadzenie
Plik journald.conf
to główny plik konfiguracyjny dla systemowego dziennika journald. Określa on wszystkie aspekty działania dziennika systemowego - od sposobu przechowywania logów, przez ich rotację, aż po kompresję i limity rozmiaru.
Lokalizacja pliku konfiguracyjnego
Konfiguracja journald znajduje się w kilku możliwych lokalizacjach, które są sprawdzane w następującej kolejności:
/etc/systemd/journald.conf.d/*.conf
- fragmenty konfiguracji w katalogu/etc/systemd/journald.conf
- główny plik konfiguracyjny/usr/local/lib/systemd/journald.conf.d/*.conf
- lokalne fragmenty konfiguracji/usr/lib/systemd/journald.conf.d/*.conf
- systemowe fragmenty konfiguracji/etc/systemd/journald@NAMESPACE.conf
- konfiguracja dla konkretnej przestrzeni nazw/etc/systemd/journald@NAMESPACE.conf.d/*.conf
- fragmenty konfiguracji dla przestrzeni nazw/usr/local/lib/systemd/journald@NAMESPACE.conf.d/*.conf
- lokalne fragmenty dla przestrzeni nazw/usr/lib/systemd/journald@NAMESPACE.conf.d/*.conf
- systemowe fragmenty dla przestrzeni nazw
Tradycyjnie, zalecam tworzenie własnych plików konfiguracyjnych w katalogu /etc/systemd/journald.conf.d/
z rozszerzeniem .conf
, zamiast bezpośredniej modyfikacji głównego pliku konfiguracyjnego.
Format pliku konfiguracyjnego
Plik journald.conf
używa standardowego formatu plików konfiguracyjnych używanych przez systemd:
Wszystkie opcje konfiguracyjne znajdują się w sekcji [Journal]
.
Dostępne opcje konfiguracyjne
Poniżej przedstawiam wiekszość dostępnych opcji konfiguracyjnych w ostatniej wersji journald:
Opcje przechowywania danych
Storage=
Określa sposób przechowywania komunikatów dziennika:
volatile
- przechowywanie tylko w pamięci (w/run/log/journal/
)persistent
- przechowywanie na dysku (w/var/log/journal/
)auto
- przechowywanie na dysku, jeśli katalog/var/log/journal/
istnieje, w przeciwnym razie w pamięci (domyślne)none
- brak przechowywania, wszystkie komunikaty są odrzucane
Compress=
Określa, czy zapisywane dane mają być kompresowane w celu oszczędzania miejsca:
yes
- włącza kompresję (domyślne)no
- wyłącza kompresję
CompressionLevel=
Poziom kompresji w skali od 1 (najniższa, najszybsza) do 9 (najwyższa, najwolniejsza), lub od -1 (domyślna) do 0 (brak):
Seal=
Określa, czy pliki dziennika powinny być zabezpieczone kryptograficznie:
yes
- włącza zabezpieczenie (domyślne, jeśli dostępne są narzędzia kryptograficzne)no
- wyłącza zabezpieczenie
Jak to działa?
Gdy Seal=yes, systemd używa kryptografii klucza publicznego (FSS - Forward Secure Sealing), aby:
- podpisywać logi - każdy wpis w dzienniku jest uwierzytelniany
- zabezpieczać przed zmianami - jeśli ktoś zmodyfikuje plik logu, system wykryje manipulację
- zapewniać integralność czasową - logi są chronione przed cofaniem czasu (backdating)
SplitMode=
Określa, jak dzielić pliki dziennika:
uid
- tworzy oddzielne pliki dla każdego użytkownikalogin
- tworzy oddzielne pliki dla każdej sesji logowanianone
- przechowuje wszystkie logi w jednym pliku (domyślne)
Opcje ograniczające rozmiar dziennika
SystemMaxUse=, SystemKeepFree=
Określają maksymalną ilość miejsca na dysku dla dzienników systemowych (globalnych) oraz ilość wolnego miejsca, które powinno pozostać dostępne:
SystemMaxFileSize=
Maksymalny rozmiar pojedynczego pliku dziennika systemowego:
SystemMaxFiles=
Maksymalna liczba plików dziennika systemowego:
RuntimeMaxUse=, RuntimeKeepFree=
Określają maksymalną ilość miejsca w pamięci (/run
) dla dzienników oraz ilość wolnego miejsca, które powinno pozostać dostępne:
RuntimeMaxFileSize=
Maksymalny rozmiar pojedynczego pliku dziennika w pamięci:
RuntimeMaxFiles=
Maksymalna liczba plików dziennika w pamięci:
MaxFileSec=
Maksymalny czas, przez jaki komunikaty są przechowywane w pojedynczym pliku dziennika przed rozpoczęciem rotacji:
MaxRetentionSec=
Maksymalny czas przechowywania komunikatów dziennika (niezależnie od innych limitów):
Opcje kontroli dostępu i polityki przesyłania
ForwardToSyslog=, ForwardToKMsg=, ForwardToConsole=, ForwardToWall=
Opcje określające, czy dziennik powinien przekazywać komunikaty do innych systemów logowania:
ForwardToSyslog=yes # Przekazywanie do tradycyjnego syslog
ForwardToKMsg=no # Przekazywanie do bufora kmsg jądra
ForwardToConsole=no # Przekazywanie na konsolę
ForwardToWall=yes # Przekazywanie do wszystkich zalogowanych użytkowników (wall)
MaxLevelStore=, MaxLevelSyslog=, MaxLevelKMsg=, MaxLevelConsole=, MaxLevelWall=
Określają maksymalny poziom ważności komunikatów przechowywanych lub przekazywanych do poszczególnych systemów:
Dostępne poziomy (od najniższego do najwyższego): debug, info, notice, warning, err, crit, alert, emerg
Opcje formatowania i identyfikacji
TTYPath=
Ścieżka do terminala, na który mają być wysyłane komunikaty dziennika:
LineMax=
Maksymalna długość linii komunikatu dziennika:
ReadKMsg=
Określa, czy komunikaty z bufora kmsg jądra mają być odczytywane i przechowywane:
Audit=
Określa, czy system audytu jądra ma być używany:
Opcje sieciowe
SyncIntervalSec=
Określa częstotliwość synchronizacji dziennika na dysk:
RateLimitIntervalSec=, RateLimitBurst=
Opcje ograniczające liczbę komunikatów przyjmowanych w określonym czasie:
RateLimitIntervalSec=30s # Okres czasu
RateLimitBurst=10000 # Maksymalna liczba komunikatów w okresie
SystemCallArchitectures=
Lista dozwolonych architektur wywołań systemowych:
Jak to działa?
Parametr określający, które architektury wywołań systemowych są dozwolone dla danego procesu/kontenera.
native - oznacza, że proces może wykonywać tylko wywołania systemowe zgodne z architekturą systemu, na którym działa (np. x86_64, ARM64).
Każda operacja na poziomie jądra (np. otwarcie pliku, tworzenie procesu) wymaga wywołania systemowego.
Różne architektury procesorów (x86, ARM, RISC-V) mają różne numery i sposoby wywoływania syscalli.
Ograniczenie do native
Jeśli ustawisz SystemCallArchitectures=native, proces może używać tylko syscalli swojej architektury.
Próba wykonania syscalla z innej architektury (np. emulacja i386 na x86_64) zostanie zablokowana.
Przykładowo:
1. W systemd (np. dla usług/kontenerów)
[Service]
SystemCallArchitectures=native
RestrictAddressFamilies=AF_UNIX AF_INET
- blokuje wywołania systemowe spoza natywnej architektury
- powoduje uniemożliwienie exploitów wykorzystujących emulację
2. W Docker/Sandboxach
docker run --security-opt systemcalls=native ...
Kontener może wykonywać tylko syscalle zgodne z hostem (np. x86_64).
CapabilityBoundingSet=
Określa zestaw ograniczeń możliwości (capabilities) procesu journald:
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ
MemoryDenyWriteExecute=
Zapobiega wykonywaniu kodu z obszarów pamięci ze znacznikiem do zapisu:
SystemCallFilter=
Filtr wywołań systemowych, które są dozwolone lub zabronione:
RestrictRealtime=
Zapobiega uzyskiwaniu priorytetów czasu rzeczywistego przez proces:
Co to oznacza?
Uniemożliwia procesowi (np. usłudze systemowej) ustawianie priorytetu czasu rzeczywistego (real-time scheduling) dla swoich wątków/zadań.
W Linuxie procesy mogą używać polityk planowania:
SCHED_OTHER (domyślna, współdzielony czas CPU),
SCHED_FIFO/SCHED_RR (czas rzeczywisty – proces ma wyższy priorytet niż nawet procesy jądra).
Dlaczego to ważne?
Bezpieczeństwo:
Proces z priorytetem SCHED_FIFO może zablokować cały system, jeśli wejdzie w nieskończoną pętlę (bo ma wyższy priorytet).
Atakujący mogą wykorzystać to do DoS (Denial of Service).
Stabilność:
Zapobiega przypadkowemu nadaniu RT przez błąd w oprogramowaniu.
Konfig w unit file
[Service]
RestrictRealtime=yes
Efekt: Proces usługi nie może użyć sched_setscheduler() do ustawienia SCHED_FIFO/SCHED_RR.
Jak sprawdzić priorytety procesów?
ps -eo pid,comm,cls,pri | grep -E 'FF|RR' # wyświetli procesy RT
chrt -p <PID> # pokaże politykę planowania
RestrictNamespaces=
Ogranicza przestrzenie nazw, które mogą być tworzone:
Co to oznacza?
Blokuje procesowi możliwość tworzenia nowych przestrzeni nazw (namespaces), które są podstawą konteneryzacji (Docker, LXC, podman).
Dotyczy m.in. tych przestrzeni:
PID (izolacja procesów),
NET (izolacja sieci),
UTS (izolacja hostname),
USER (izolacja UID/GID),
itd.
Dlaczego to ważne?
Tworzenie namespaces może być metodą ucieczki z kontenera (container breakout) lub eskalacji uprawnień.
Np. atakujący może próbować stworzyć nową przestrzeń PID/USER aby ominąć ograniczenia.
Zapobiega nieautoryzowanej konteneryzacji:
Jeśli usługa nie potrzebuje tworzyć kontenerów, możesz zablokować tę możliwość.
Konfig unit'a
[Service]
RestrictNamespaces=yes
Efekt: Wywołania takie jak unshare(2) lub clone(2) z flagami namespaces (CLONE_NEWPID, CLONE_NEWNET itd.) zostaną zablokowane.
Opcje szczegółowe
Można też blokować tylko wybrane przestrzenie nazw:
RestrictNamespaces=pid net user # blokuje tylko te trzy
lub zezwalać na wszystkie:
RestrictNamespaces=no
Jak sprawdzić namespaces procesu?
ls -l /proc/<PID>/ns/ # lista przestrzeni nazw procesu
LockPersonality=
Zapobiega zmianie osobowości wykonywania:
SplitRoundRobin=
Włącza tryb rotacji dla podziału dzienników:
AutoFlush=
Określa, czy dane mają być automatycznie zapisywane na dysk w przypadku krytycznych błędów:
Weryfikacja konfiguracji
Po wprowadzeniu zmian w konfiguracji można je zastosować i zweryfikować:
Ponowne załadowanie konfiguracji
Sprawdzenie statusu usługi
Sprawdzenie bieżących ustawień
Dobre praktyki
- Świadome ustalanie limitów - dopasuj limity rozmiaru dzienników do charakterystyki systemu
- Używanie kompresji - włącz kompresję nawet kosztem niewielkiego obciążenia CPU
- Zabezpieczenia - włącz opcję
Seal=yes
na serwerach produkcyjnych - Przechowywanie - używaj
Storage=persistent
dla ważnych systemów - Limity przepustowości - konfiguruj
RateLimitIntervalSec
iRateLimitBurst
dla ochrony przed DoS - Rotacja - ustaw odpowiednie wartości
MaxRetentionSec
iMaxFileSec
do automatycznego zarządzania starymi dziennikami
Uwagi dla najnowszych wersji
W ostatnich wersjach journala (2024-2025) dodano szereg funkcji związanych z bezpieczeństwem, takich jak filtrowanie wywołań systemowych i ograniczenia możliwości. Te opcje pomagają zmniejszyć potencjalny wektor ataku.
[Journal]
MemoryDenyWriteExecute=yes
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG
SystemCallArchitectures=native
SystemCallFilter=~@mount @privileged @setuid
RestrictRealtime=yes
RestrictNamespaces=yes
LockPersonality=yes
Te ustawienia wzmacniają bezpieczeństwo procesu journald, ograniczając jego uprawnienia do niezbędnego minimum.
Podsumowanie
Konfiguracja journald oferuje wszechstronne możliwości dostosowania zachowania systemowego dziennika do różnych potrzeb - od małych systemów z ograniczonymi zasobami po duże serwery produkcyjne. Najnowsze wersje journald kładą szczególny nacisk na bezpieczeństwo i wydajność, dostarczając dodatkowych opcji konfiguracyjnych.
Właściwe skonfigurowanie journald pozwala na efektywne zarządzanie dziennikami systemowymi, jak i ich monitoringiem.