Zbieranie logów i ich analiza pod kątem bezpieczeństwa to absolutny fundament każdego systemu SIEM. Wazuh najczęściej gromadzi te dane za pomocą integracji API lub protokołu rsyslog. W tym artykule skupimy się na tym drugim rozwiązaniu – rsyslog to bowiem najpopularniejszy standard w świecie Linuxa, a Wazuh wspiera go natywnie.
Wazuh posiada wbudowane dekodery, które potrafią „rozebrać” logi na części pierwsze i wyciągnąć z nich kluczowe informacje. To właśnie te dane służą później do segmentacji zdarzeń, uruchamiania reguł i wyzwalania alarmów.
Niestety, mimo ogromnej popularności protokołu syslog (oraz jego nowoczesnej implementacji rsyslog), ma on jedną istotną wadę: natywnie wiadomości są przesyłane w sieci czystym tekstem (plain text). Oznacza to, że każdy, kto przechwyci ruch między źródłem a naszym systemem SIEM, może bez trudu odczytać ich treść. Jak temu zaradzić i zapewnić poufność przesyłanych informacji?
Zastosowanie biznesowe
Wiele osób wychodzi z założenia, że skoro logi krążą jedynie wewnątrz sieci LAN, to przesyłanie ich tekstem jawnym nie stanowi problemu. Przecież nasza sieć jest zabezpieczona, a dostęp do niej ma wyłącznie autoryzowany personel, prawda? Nic bardziej mylnego.
Projektując bezpieczną infrastrukturę IT, powinniśmy kierować się jednym z fundamentów architektury Zero Trust, czyli zasadą Assume Breach. Polega ona na założeniu, że atakujący już znajduje się wewnątrz naszej sieci (lub prędzej czy później do niej przeniknie). W związku z tym, planując segmenty LAN, musimy dążyć do maksymalnej izolacji i szyfrowania każdego możliwego strumienia danych. Takie podejście drastycznie utrudnia napastnikowi tzw. lateral movement — czyli swobodne poruszanie się po infrastrukturze, „myszkowanie” w poszukiwaniu danych i dalszą eskalację uprawnień.
Warto również rozważyć przypadek biznesowy, w którym system Wazuh musi pobrać logi z maszyn znajdujących się w sieci zewnętrznej, przesyłając dane przez internet publiczny. Pełna widoczność systemów IT i ciągłe monitorowanie bezpieczeństwa to fundamenty nowoczesnej organizacji – nie możemy pozwolić sobie na tzw. ślepe plamy (blind spots), które tylko czekają na wykorzystanie przez atakującego.
W takiej sytuacji optymalnym rozwiązaniem byłoby zestawienie tunelu VPN typu Site-to-Site (S2S) lub Point-to-Site (P2S), aby dane podróżowały w pełni zaszyfrowanym kanałem. Wiemy jednak, że w rzeczywistości nie zawsze jest to możliwe ze względów technicznych lub budżetowych. Czasami jedyną dostępną opcją pozostaje przesyłanie logów bezpośrednio przez publiczny internet. W takim scenariuszu szyfrowanie przestaje być jedynie opcją typu „nice to have” – staje się bezwzględnym wymogiem bezpieczeństwa, bez którego wdrożenie takiego rozwiązania w środowisku produkcyjnym byłoby skrajnie nieodpowiedzialne.
Jak to osiągnąć?
Aby osiągnąć pełne szyfrowanie przesyłanych logów, będziemy potrzebować następujących komponentów:
- Serwer Wazuh – wymaga modyfikacji konfiguracji usługi
wazuh-manager, aby poprawnie odbierać przetworzone dane. - Nginx jako Reverse Proxy – serwer Nginx weźmie na siebie obsługę warstwy SSL (szyfrowanie ruchu za pomocą certyfikatów) oraz weryfikację list ACL (kontrola dostępu dla autoryzowanych adresów IP).
- Usługa rsyslog – posłuży do zbierania i przekazywania logów ze zdalnych hostów do managera.
Na potrzeby tego artykułu całość została uruchomiona na jednym serwerze. Warto jednak pamiętać, że w profesjonalnym wdrożeniu produkcyjnym serwer Nginx najlepiej umieścić w odizolowanej strefie DMZ. Dostęp do niego ze świata zewnętrznego realizujemy wtedy poprzez precyzyjny port forwarding na urządzeniu brzegowym, co stanowi dodatkową warstwę separacji naszej sieci wewnętrznej.
Opis wdrożenia
Konfiguracja Nginx Reverse Proxy
Proces rozpoczynamy od instalacji serwera Nginx. W moim przypadku korzystam z systemu Debian 13 Bookworm, więc użyję menedżera pakietów apt:
sudo apt update
sudo apt install nginx
Następnie edytujemy główny plik konfiguracyjny /etc/nginx/nginx.conf. Musimy zdefiniować sekcję stream, która pozwoli Nginxowi operować na poziomie protokołu TCP (warstwa 4), a nie tylko HTTP. Konfigurujemy odpowiedni upstream oraz backend:
stream {
upstream wazuh_syslog {
# Adres IP i port naszego lokalnego serwera rsyslog
server 127.0.0.1:514;
}
server {
# Port, na którym Nginx będzie nasłuchiwał szyfrowanego ruchu rsyslog
listen 6514 ssl;
proxy_pass wazuh_syslog;
# ACL: Zezwalamy tylko na ruch z konkretnego, zaufanego adresu IP
allow 8.8.8.8;
# Odrzucamy wszystkie pozostałe połączenia
deny all;
# Ścieżki do certyfikatów SSL (np. wygenerowanych przez Let's Encrypt)
ssl_certificate /etc/wazuh-dashboard/certs/public.pem;
ssl_certificate_key /etc/wazuh-dashboard/certs/private.pem;
# Optymalizacja wydajności proxy
proxy_buffer_size 64k;
proxy_connect_timeout 30s;
proxy_timeout 1m;
}
}
Po zapisaniu zmian musimy zweryfikować, czy w konfiguracji nie wkradł się żaden błąd składniowy:
sudo nginx -t
Jeśli wszystko skonfigurowaliśmy poprawnie, otrzymamy komunikat:
nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful
Na koniec restartujemy usługę, aby wczytać nową konfigurację, i upewniamy się, że Nginx uruchomi się automatycznie po każdym restarcie systemu:
sudo systemctl restart nginx
sudo systemctl enable nginx
Debugowanie i logi
Na etapie wdrażania i testowania warto skonfigurować osobny plik logów dla sekcji stream. Pozwoli to na bieżąco monitorować statusy połączeń (np. 200 OK lub błędy typu 500) oraz weryfikować, czy pakiety faktycznie docierają do serwera.
W tym celu dodaj poniższe linie wewnątrz bloku stream {}:
log_format basic '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
access_log /var/log/nginx/stream.log basic;
Dedykowany plik stream.log wraz ze standardowym error.log będą Twoimi najważniejszymi narzędziami w przypadku konieczności przeprowadzenia troubleshootingu.
Konfiguracja usługi rsyslog
Gdy nasza „brama” (Nginx) jest już gotowa do odbierania zaszyfrowanych połączeń, musimy skonfigurować samą usługę rsyslog. To ona zajmie się fizycznym odebraniem logów od Nginxa i zapisaniem ich do pliku, który później zanalizuje Wazuh.
Jeśli usługa nie jest jeszcze zainstalowana w Twoim systemie, wykonaj poniższe komendy:
sudo apt update
sudo apt install rsyslog
Następnie przechodzimy do katalogu /etc/rsyslog.d/, gdzie utworzymy dedykowany plik konfiguracyjny dla naszego odbiornika. W moim przykładzie będzie to fortigate.conf, ponieważ to właśnie z tym urządzeniem testowałem integrację w laboratorium.
W pliku umieszczamy następującą konfigurację:
# Ładujemy moduł odpowiedzialny za komunikację TCP
module(load="imtcp")
# Definicja portu, na którym ma nasłuchiwać usługa (nasz backend dla Nginxa)
input(type="imtcp" port="514")
# Definiujemy szablon zapisu logów.
# Ważne, aby struktura logu była czytelna dla dekoderów Wazuha.
template(name="FortigateFile" type="string" string="date=%$now% %msg%\n")
# Proces zapisu logów do konkretnego pliku na dysku
action(type="omfile"
file="/var/log/fortigate/syslog.log"
template="FortigateFile")
Restartujemy usługę rsyslog, aby wczytać nową konfigurację, i upewniamy się, że będzie ona uruchamiana automatycznie przy starcie serwera:
sudo systemctl restart rsyslog
sudo systemctl enable rsyslog
Aby zweryfikować, czy wszystko działa zgodnie z planem, sprawdzamy aktywne gniazda sieciowe i porty, na których nasłuchuje nasz system:
ss -tulpn
Jeśli konfiguracja jest poprawna, na liście powinniśmy zobaczyć usługę rsyslogd nasłuchującą na porcie 514/TCP:
tcp LISTEN 0 25 0.0.0.0:514 0.0.0.0:* users:((„rsyslogd”,pid=600,fd=7))
Dlaczego TCP zamiast UDP?
Bardziej doświadczeni administratorzy mogli zauważyć, że wymuszamy tutaj protokół TCP, mimo że standardowo syslog kojarzony jest z bezpołączeniowym UDP.
Wybór ten jest podyktowany mechanizmem działania szyfrowania. Nawiązanie bezpiecznego połączenia TLS wymaga przeprowadzenia pełnego procesu 3-way handshake. Protokół UDP, działający na zasadzie „wyślij i zapomnij”, nie posiada mechanizmów kontroli sesji, co uniemożliwiłoby poprawne zestawienie szyfrowanej komunikacji. Dlatego w architekturze opartej na TLS, TCP jest niezbędnym fundamentem.
Protokół TCP jest też niezbędny ze względu na samego Nginxa. Standardowe konfiguracje reverse proxy (szczególnie w kontekście streamingu ruchu) najlepiej radzą sobie właśnie z protokołami połączeniowymi. Wykorzystanie TCP gwarantuje, że Nginx będzie w stanie prawidłowo obsłużyć sesję i przekazać strumień danych do backendu bez strat, które mogłyby wystąpić przy próbie tunelowania bezpołączeniowego UDP.
Dlaczego zapisujemy logi do plików zamiast użyć sekcji <remote>?
Osoby lepiej zaznajomione z Wazuhem mogą zadać sobie pytanie: po co angażować osobną usługę rsyslog i zapisywać dane do plików, skoro Wazuh posiada natywną obsługę protokołu syslog poprzez sekcję <remote> w konfiguracji?
Odpowiedź brzmi: przejrzystość i higiena pracy z danymi. Stosując rsyslog jako pośrednika, zyskujemy znacznie większą kontrolę nad przepływem informacji. Możemy tworzyć osobne strumienie na różnych portach dla konkretnych grup urządzeń, a następnie kierować je do dedykowanych plików. Dzięki temu dokładnie wiemy, co i skąd trafia do naszego systemu.
W przypadku korzystania z natywnej funkcji <remote> w Wazuh-Managerze, wszystkie logi trafiają do jednego „worka”. Aby zweryfikować, czy dane w ogóle docierają, musielibyśmy włączyć opcję <logall>, co przy dużej liczbie integracji generuje ogromny szum informacyjny. W takim gąszczu zdarzeń bardzo trudno jest wyłowić konkretne logi i przeprowadzić sprawny troubleshooting.
Podejście z wykorzystaniem rsysloga jest po prostu „czystsze” – pozwala na lepszą separację danych i jest znacznie łatwiejsze w zarządzaniu w dłuższej perspektywie, szczególnie w rozbudowanych środowiskach.
Archiwizacja logów
Aby nasz plik logów /var/log/fortigate/syslog.log nie rozrósł się do niekontrolowanych rozmiarów, musimy skonfigurować mechanizm jego rotacji. W tym celu tworzymy nowy plik konfiguracyjny (np. /etc/logrotate.d/fortigate) o następującej treści:
/var/log/fortigate/syslog.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root root
postrotate
systemctl kill -s HUP rsyslog.service
endscript
}
Kluczowe parametry:
- daily: Rotacja odbywa się codziennie.
- rotate 7: Przechowujemy logi z ostatnich 7 dni (w Twoim przykładzie było
0, co usuwałoby logi natychmiast po rotacji – warto zachować choć kilka dni na wypadek awarii). - compress: Stare logi są kompresowane (oszczędność miejsca).
- create 0640 root root: Nowy plik tworzony jest z odpowiednimi uprawnieniami, aby usługa miała do niego dostęp, ale osoby postronne nie mogły go czytać.
- postrotate: Bardzo ważna sekcja – po zrotowaniu pliku wysyłamy sygnał SIGHUP do rsysloga, aby „puścił” stary plik i zaczął pisać do nowego.
Konfiguracja po stronie klienta
Ostatnim ogniwem łańcucha jest odpowiednie przygotowanie hosta, który ma wysyłać logi do naszego systemu. Sposób konfiguracji usługi rsyslog będzie zależał od tego, czy pracujemy na fizycznym urządzeniu, maszynie wirtualnej, kontenerze czy aplikacji typu SaaS. Niezależnie od platformy, kluczowe zmienne, które musimy ustawić, to:
- Serwer rsyslog: Wskazujemy publiczny adres IP naszego Nginx Reverse Proxy.
- Port: 6514/TCP (zgodnie z tym, co ustawiliśmy w Nginx).
Niezwykle ważne jest również aktywowanie szyfrowania SSL/TLS. Warto pamiętać, że nie każdy klient natywnie obsługuje tę funkcję. Jeśli korzystasz z certyfikatów wystawionych przez własne, niezaufane publicznie CA (Certificate Authority), konieczne będzie dodanie certyfikatu Root CA na hoście klienckim. W przeciwnym razie większość systemów (jeśli poprawnie weryfikują zaufanie) odrzuci połączenie i nie nawiąże bezpiecznej komunikacji z Twoim reverse proxy.
Konfiguracja systemu Wazuh
Gdy logi regularnie odkładają się już w plikach, możemy przejść do samej konfiguracji Wazuha. Jeśli Twój Nginx i rsyslog znajdują się na osobnym serwerze, musisz zainstalować tam Wazuh-agenta i na nim skonfigurować monitoring pliku. W przypadku, gdy wszystkie usługi działają na tym samym hoście co manager, modyfikacji dokonujemy bezpośrednio w konfiguracji Wazuh-managera.
W obu przypadkach edytujemy plik /var/ossec/etc/ossec.conf. Dodajemy do niego poniższą sekcję, która poinstruuje system, skąd ma pobierać dane do analizy:
<localfile>
<log_format>syslog</log_format>
<location>/var/log/fortigate/syslog.log</location>
</localfile>
Po zapisaniu zmian restartujemy usługę, aby zastosować nową konfigurację:
sudo systemctl restart wazuh-manager
Jeśli w systemie masz aktywne odpowiednie reguły (oraz dekodery, jeżeli format Twoich logów odbiega od standardu), w panelu Wazuh powinny zacząć pojawiać się pierwsze alerty.
W moim laboratorium wykorzystałem natywne reguły Wazuh dla urządzeń Fortigate. Efekty były widoczne niemal natychmiast – system zaczął rejestrować liczne próby nieautoryzowanych logowań. Urządzenie testowe zostało celowo wystawione na świat jako honeypot, co szybko przyciągnęło boty skanujące sieć i pozwoliło zweryfikować poprawność działania całego łańcucha przesyłu logów.

