Red Hat 6.x / CentOS 6.x
Filtrowanie logów systemowych i przekierowywanie ich części do różnych plików jest bardzo rozbudowanym tematem. Kompleksowe jego poznanie wymaga pewnie wielu godzin spędzonych z dokumentacją, ale taka znajomość dla zwykłego administratora nie jest sprawą najwyższej wagi. Zaprezentuję tu jak można zrealizować najczęstsze (czyt: takie, które kiedykolwiek miałem okazję realizować) przypadki rozdzielania logów w zależności od ich ważności czy pochodzenia.Całość konfiguracji przeprowadzamy oczywiście w pliku /etc/rsyslog.conf
Filtrowanie logów podsystemów
Filtrowanie logów pochodzących z jakiegoś podsystemu lub o zadanym priorytecie jest chyba najprostsze do realizacji, między innymi dlatego, że gotowy szablon tego rozwiązania mamy już umieszczony w /etc/rsyslog.conf.Definicje filtrów opierają się o tzw. selektory i mają format FACILITY.PRIORITY.
FACILITY określa podsystem, który produkuje dany wpis, i może przyjmować wartości (słowne lub numeryczne): kern (0), user (1), mail (2), daemon (3), auth (4), syslog (5), lpr (6), news (7), uucp (8), cron (9), authpriv (10), ftp (11) oraz local0 do local7 (16-23).
PRIORITY jak sama nazwa wskazuje to priorytet wiadomości, o możliwych wartościach: debug (7), info (6), notice (5), warning (4), err (3), crit (2), alert (1), oraz emerg (0).
Dla obu pozycji możliwe jest użycie znaku *, który wskazuje na wszyskie facilities lub priorities.
Dla przykładu, weźmy dwa wpisy z pliku odpowiedzialne za filtrowanie.
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
Pierwszy wpis zgodnie z komentarzem umieszcza wszystkie logi facility mail w dedykowanym pliku, drugi robi to samo z logami pochodzącymi z cron-a.
Oba wpisy różnią się w swojej składni minusem przed ścieżką pliku docelowego. Umieszczenie minusa przed nazwą pliku spowoduje, że log taki będzie zapisywany synchronicznie.
Możliwe jest również definiowanie wielu pozycji w jednej linii. Jeśli potrzebujemy zdefiniować kilka priorytetów dla jednego facility, wartości oddzielamy od siebie przecinkiem, np:
mail.info,debug /var/log/mail.info
Definiowanie przekierowania kilku facilities do jednego pliku, użyjemy średnika, np:
mail.crit;kern.crit /var/log/critical
Dodatkowo istnieje możliwość użycia operatora wykluczenia w postaci wykrzyknika. Taki wpis przekeiruje wszystkie logi facility, oprócz debug oraz notice:
daemon.!debug,!notice /var/log/deamons
Filtrowanie logów zależnie od ich właściwości
Drugim typem filtrowania jakiego możemy użyć jest filtr oparty o właściwości wpisów. Ma on odmienną konstrukcję od prezentowanego wcześniej, a jego schemat wygląda następująco:
:wlasciwosc, operator-porownania, "wartosc"
Właściwości jak i operatory są odgórnie zdefiniowane, a pełna ich lista jest dostępna w pliku /usr/share/doc/rsyslog-5.8.10/property_replacer.html.
Najczęściej używanymi właściwościami są:
* msg czyli typ wiadomości
* fromhost - pochodzące z konkretnego hosta (przy logowaniu z serwerem centralnym)
* fromhost-ip - pochodzące z konkretnego IP
* programname - generowane przez konkretny program
Operatorami porównania mogą być:
* isequal
* contains
* startswith
* regex
Nazwy samych operatorów opisują doskonale realizowane przez nie porónania, więc nie ma sensu tego tłumaczyć.Opcjonalnie możemy przed operatorem użyć znaku negacji !.
Wartością w regule może być dowolny ciąg znaków, którego będziemy wyszukiwać w danym wpisie.
Dla przykładu utworzymy filtr oddzielający logi konkretnego programu.
Do utworzenia takiego filtra należy zidentyfikować pod jaką nazwą dany program występuje w procesie logowania. Możemy posłużyć się wpisami w /var/log/messages, gdzie każdy z programów przedstawia się nazwą w piątej kolumnie (po miesiącu, dniu, godzinie i hostname'ie), np:
Sep 23 05:01:53 rsyslog-c1 sshd[3591]: Accepted password for root from 192.168.1.6 port 61960 ssh2
Sep 23 06:29:23 rsyslog-c1 su: pam_unix(su-l:session): session opened for user test by root(uid=0)
Sep 23 06:29:23 rsyslog-c1 su: pam_unix(su-l:session): session opened for user test by root(uid=0)
Oczywiście w konfiguracji filtra pomijamy pid procesu zawarty w nawiasie.
Przyjmijmy, że chcemy w osobnym pliku umieszczać logowania poprzez ssh, oraz w jeszcze innym wszelkie zmiany użytkownika w trakcie sesji, czyli reagować na su. Konfiguracja jest oczywista:
:programname, isequal, "sshd" /var/log/sshd
:programname, isequal, "su" /var/log/su
:programname, isequal, "su" /var/log/su
Kolejnym przykładem może być filtrowanie wszystkich logów, zawierających jakiś błąd. Filtr taki będzie mieć postać:
:msg, contains, "error" /var/log/errorlog
Odfiltruje wszystkie wiadomości zawierające słowo kluczowe error i umieści w odrębnym pliku.
Taka składnia może być przydatna w przypadku serwera centralnego rsyslog. Umożliwia ona rozdzielenie logów pochodzących z różnych hostów na osobne pliki, np odnosząc się do naszej przykładowej realizacji centralnego rsysloga:
:fromhost, isequal, "rsyslog-c1.my.domain" /var/log/rsyslog-c1/messages
Regułka przekieruje wszytkie wpisy z hosta rsyslog-c1.my.domain do pliku /var/log/rsyslog-c1/messages
Filtry warunkowe
Filtrów warunkowych możemy użyć do łączenia kilku filtrów właściwościowych opisanych wcześniej, oraz umieszczania ich w pętlach if-else. Ja nie potrzebuję na codzień bardzo zaawansowanych filtrów, dlatego najczęściej używam ich do przekierowywania logów przesyłanych do serwera centralnego.Z pomocą prostego warunku możemy umieszczać różne logi z hosta zdalnego w różnych plikach., np:
if $programname == 'sshd' and $fromhost == 'rsyslog-c1.my.domain' then /var/log/rsyslog-c1/sshd
:fromhost, isequal, "rsyslog-c1.my.domain" /var/log/rsyslog-c1/messages
:fromhost, isequal, "rsyslog-c1.my.domain" /var/log/rsyslog-c1/messages
Oddzielimy w ten sposób logi generowane przez sshd na maszynie rsyslog-c1 do oddzielnego pliku, podczas gdy wszystkie logi z tego hosta trafiają do pliku messages w tym samym katalogu.
Pomijanie zapisanych pozycji
Testując powyższą przykładową konfigurację na serwerze można zauważyć, że wpisy dotyczące sshd pojawiają się w pliku /var/log/rsyslog-c1/sshd, ale niepotrzebnie dublują się również w pliku /var/log/rsyslog-c1/messages. Jest na to prosta rada - po zapisaniu części logów do pliku należy poinformować rsyslog, że nie chcemy ich już więcej używać:
if $programname == 'sshd' and $fromhost == 'rsyslog-c1.my.domain' then /var/log/rsyslog-c1/sshd
if $programname == 'sshd' and $fromhost == 'rsyslog-c1.my.domain' then ~
:fromhost, isequal, "rsyslog-c1.my.domain" /var/log/rsyslog-c1/messages
if $programname == 'sshd' and $fromhost == 'rsyslog-c1.my.domain' then ~
:fromhost, isequal, "rsyslog-c1.my.domain" /var/log/rsyslog-c1/messages
Znak tyldy w ścieżce zapisu logu spowoduje usunięcie pozycji z pamięci rsyslog.
Dynamiczne generowanie nazw plików
Podczas używania serwera centralnego dość szybko znudzi się nam ręczne określanie nazw plików i tworzenie reguł dla każdego hosta zdalnego z osobna. Pomocna okazuje się tutaj możliwość dynamicznej definicji nazw plików.Proces polega na określeniu szablonu nazwy w oparciu o zmienne elementy logów. Elementami mogą być (lista zawiera te najczęściej wykorzystywane, a pełną można znaleźć "googlając" hasło RSYSLOG_DebugFormat):
* %FROMHOST% - czyli przesłane z hosta
* %FROMHOST-IP% - przełane z IP
* %HOSTNAME% - hostname zawarty w logu
* %syslogtag% - tag wiadomości
* %programname% - nazwa programu generującego log
* %PROCID% - id procesu
* %MSGID% - id wiadomości (wg standardu IETF)
* %TIMESTAMP% - znacznik czasu z wiadomości
* %msg% - treść wiadomości
Sama definicja szablonu nazwy takiego pliku wygląda następująco:
$template NazwaSzablonu,"/sciezka/z/wykorzystaniem/tagow/np/%HOSTNAME%"
Użycie tak zdefiniowanego szablonu sprowadza się do użycia jego nazwy poprzedzonej znakiem ? zamiast nazwy konkretnego pliku, np:
*.* ?NazwaSzablonu
Tyle teorii, teraz jakiś działający przykład do przetestowania. Scenariusz jest następujący: kilka serwerów klienckich przesyła swoje logi do serwera centralnego. Serwer centralny zapisuje logi z poszczególnych hostów w osobnych katalogach o nazwach zgodnych z hostname klienta. Z logów odławiać będziemy zdarzenia z programu sshd, które będą trafiać do osobnego pliku w katalogu hosta.
Realizacja zadania sprowadzi się do kilku linijek, i obsłuży obecne i przyszłe hosty zdalnie logujące:
$template HostMessages,"/var/log/%hostname%/messages"
$template HostSshd,"/var/log/%hostname%/sshd"
:programname, isequal, "sshd" ?HostSshd
:programname, isequal, "sshd" ~
*.* ?HostMessages
$template HostSshd,"/var/log/%hostname%/sshd"
:programname, isequal, "sshd" ?HostSshd
:programname, isequal, "sshd" ~
*.* ?HostMessages
Pierwsze dwie linijki definiują nam dynamiczne nazwy plików (a w zasadzie dynamiczne są katalogi, w których są pliki). Linijka trzecia przekierowuje logi z sshd do odpowiedniego pliku, podczas gdy czwarta "discarduje" je, aby nie trafiały już do pliku ogólnego. Ostatnia linijka kieruje pozostałe logi z hosta do pliku messages w katalogu zgodnym z nazwą hosta.
Voila, oto całość definicji, która równie dobrze sprawdza się dla 2 co i dla 200 hostów zdalnie logujących do serwera centralnego.
Jak pisałem na początku, temat filtrów rsyslog jest bardzo obszerny, a powyższy tekst ociera się o elementy, które okazały się przydatne w moim administratorskim bycie. Zainteresowanym osiągnięciem mistrzostwa w tej dziedzinie polecam dokumentację - zarówno systemową jak i projektu ze strony rsyslog.
Brak komentarzy:
Prześlij komentarz