Wstęp
Projekt ten powstał z potrzeby przejścia od czystej teorii do inżynierskiej praktyki w zakresie cyberbezpieczeństwa, administracji sieciami oraz systemami enterprise. Budowa domowego laboratorium (Cyber Range) zintegrowanego z systemem monitorowania zdarzeń klasy SIEM na papierze wydaje się prosta. W praktyce okazała się brutalnym testem mojej odporności na frustrację i braki w wiedzy infrastrukturalnej.
Nie jestem seniorem infrastruktury ani architektem enterprise – większość rzeczy robiłem po raz pierwszy, eksperymentując i szukając rozwiązań w dokumentacjach, na forach i metodą prób i błędów.
Głównym ograniczeniem na starcie był brak zaplecza sprzętowego klasy enterprise. Do dyspozycji miałem domowy router MikroTik, host wirtualizacji z systemem Windows oraz minikomputer Raspberry Pi 5. Ograniczeniem była również moja wybiórcza wiedza na temat zaawansowanych mechanizmów systemu RouterOS, niuansów wirtualizacji w Hyper-V oraz specyfiki środowisk Windows. Projekt nie był realizowany według gotowego szablonu — był to proces iteracyjny, pełen błędnych założeń, awarii sieci, rollbacków konfiguracji i rozwiązywania problemów rzadko opisywanych w popularnych poradnikach.
Poniżej znajduje się mój techniczny dziennik budowy. Bez upiększania, z pełną listą ślepych zaułków i momentów, w których jedynym wyjściem było przywrócenie backupu.
Architektura Labu (Koncepcja)
Projekt zakładał podział na trzy główne segmenty logiczne i sieciowe:
- Segment Monitorowania (SOC): Oparty na minikomputerze Raspberry Pi 5 z dyskiem NVMe, na którym zainstalowano serwer centralny Wazuh (Manager, Indexer, Dashboard). Komponent ten odpowiada za zbieranie i korelację logów.
- Segment Tożsamości i Klientów (Active Directory Range): Środowisko zwirtualizowane na hoście Hyper-V (laptop). Składa się z kontrolera domeny Windows Server 2025 oraz stacji roboczej Windows 11 Enterprise.
- Segment Sieciowy (Core): Router MikroTik. Odpowiada za realizację izolacji warstwy drugiej (VLAN), routing międzyinstancyjny, DHCP oraz firewall.
Chronologiczny Przebieg Projektu i Debugowanie
Faza 1: OS, migracja na NVMe i walka z bootloaderem RPi 5
Wiedziałem, że instalacja bazy danych (OpenSearch) na karcie SD zajechałaby ją w kilka tygodni przez ciągły zapis (IOPS). Musiałem przenieść system na dysk NVMe.
Najpierw próbowałem zainstalować Ubuntu Server 24.04 używając prekonfiguracji cloud-init. Naiwnie ustawiłem nazwę użytkownika na operator. Szybko dowiedziałem się, że w debianowych systemach ten UID (37/11) jest zarezerwowany. System wstał, ale skrypty startowe zgłupiały – nie utworzono katalogu domowego, odcinając mi całkowicie dostęp po kluczach SSH. Zamiast z tym walczyć, postawiłem system od nowa i użyłem niezastrzeżonego konta.
Następnie sklonowałem system z karty SD na dysk NVMe za pomocą narzędzia rpi-clone:
git clone https://github.com/geerlingguy/rpi-clone.git
cd rpi-clone
sudo cp rpi-clone rpi-clone-setup /usr/local/sbin
sudo rpi-clone nvme0n1
Proces zakończył się pomyślnie, jednak po restarcie malinka odmówiła uruchomienia systemu z nowego dysku i szukała karty SD.
Diagnoza: Analiza konfiguracji bootloadera wykazała obecność problemu typu race condition. Domyślny parametr BOOT_ORDER=0xf461 w pamięci EEPROM powodował pętlę i zmuszał sprzęt do szukania partycji rozruchowej na niewłaściwych nośnikach, a sama szyna PCIe była ograniczana w celu oszczędzania energii.
Wymagana była ręczna edycja:
sudo rpi-eeprom-config --edit
Nadpisałem parametry wymuszając pełną prędkość i priorytet magistrali PCIe (0xf1):
BOOT_UART=1
BOOT_ORDER=0xf1
PCIE_PROBE=1
NET_INSTALL_AT_POWER_ON=1
Po restarcie komenda lsblk prawidłowo zameldowała dysk nvme0n1 jako partycję główną. Dodatkowo wyciąłem całkowicie układ radiowy komendą sudo rfkill block wifi, żeby uniknąć asymetrycznego routingu w przyszłości.
Faza 2: Ślepa uliczka w Dockerze i kryptografia Filebeat
Chciałem ułatwić sobie wdrożenie SIEMa i postawić Wazuha w Dockerze, zakładając, że kontenery rozwiążą problem zależności. Pobrałem repozytorium i odpaliłem skrypt generujący certyfikaty. Od razu dostałem błąd: exec format error. Kontener producenta był skompilowany wyłącznie pod architekturę x86_64, a procesor RPi to aarch64.
Użyłem pakietu qemu-user-static do emulacji x86. Certyfikaty się wygenerowały, ale kiedy podniosłem cały stos, kontener wazuh.dashboard zaczął wpadać w pętlę restartów z kodem 139 (Segmentation Fault). Emulacja tak ciężkiego środowiska Node.js przerosła zasoby sprzętowe. Zrozumiałem, że Docker na ARM dla tego stacku to na ten moment ślepy zaułek. Zrobiłem docker system prune -a i przeszedłem na instalację bare-metal (natywną) z pakietów apt.
Kolejny problem pojawił się przy zabezpieczaniu certyfikatów Filebeat (kuriera logów). Wykonałem komendy:
sudo chmod 500 /etc/wazuh-indexer/certs
sudo chmod 400 /etc/wazuh-indexer/certs/*
Dostałem błąd braku dostępu do plików. Debugowanie zajęło mi chwilę, zanim zrozumiałem mechanikę powłoki w Linuksie. Nadanie katalogowi uprawnienia 500 (brak prawa odczytu/listowania) sprawia, że shell nie jest w stanie rozwinąć znaku gwiazdki * (wildcard) przed przekazaniem ścieżek do polecenia sudo. Musiałem ręcznie i precyzyjnie wskazać absolutne ścieżki do każdego pliku (admin-key.pem, indexer-key.pem itd.), aby kryptografia zadziałała.
Faza 3: Uwierzytelnianie Wazuha i schizofrenia bazy
Po udanej instalacji pakietów, Dashboard powitał mnie komunikatem o braku autoryzacji. W logach API leciały setki błędów 401 Unauthorized.
Próbowałem zresetować hasło dla konta admin narzędziem z poziomu CLI, ale użyłem w haśle znaku wykrzyknika !, który bash zinterpretował jako odwołanie do historii, co z kolei całkowicie uszkodziło plik z hashami.
Dowiedziałem się wtedy, że wewnętrzny mechanizm bezpieczeństwa OpenSearch nie przyjmuje haseł przekazanych w czystym tekście w plikach konfiguracyjnych. Wymagane było ręczne wygenerowanie bezpiecznego skrótu kompatybilnego z silnikiem bcrypt dla konta technicznego kibanaserver:
$2y$12[...]./[...]
Wdrożenie zahaszowanego hasła do konfiguracji internal_users.yml, siłowe załadowanie go skryptem securityadmin.sh i restart usług otworzyły mi w końcu dostęp do konsoli webowej.
Faza 4: Pierwsza próba segmentacji na MikroTiku i krytyczny Rollback
Założenie sieciowe wyglądało ambitnie: stworzyć trzy odrębne podsieci (SOC_VLAN, KALI_VLAN, AD_VLAN).
Na MikroTiku dodałem interfejsy VLAN, adresację 10.X.X.X/24, pule DHCP i przypisałem port Raspberry Pi (etherX) do VLAN XX. Chciałem, żeby moja domyślna sieć (VLAN XX) działała nietagowana na pozostałych portach, więc wpisałem:
/interface bridge vlan add bridge=bridge vlan-ids=XX tagged=bridge untagged=wifiX,wifiY,etherX,etherY
System zwrócił błąd: failure: interface cannot be in tagged and untagged at the same time.
To był pierwszy poważny błąd architektoniczny. Próba ręcznego sterowania domyślnym VLANem na bridge’u bez głębszego zrozumienia mechanizmu filtrowania doprowadziła do całkowitego zablokowania tablicy przełączeń i firewalla. Mój Mac zarządczy stracił dostęp do wszystkiego, a reguła domyślna drop all not coming from LAN zablokowała nowy ruch, ponieważ nie dodałem nowych VLANów do odpowiedniej listy interfejsów.
Zamiast brnąć w ślepą uliczkę (co skończyłoby się fizycznym resetem routera igłą), wykonałem pełny rollback logując się przez WinBox po adresie MAC:
/system backup load name=PRZED_VLANAMI
Zrozumiałem, że muszę uprościć architekturę. Zamiast trzech VLANów, postawiłem na jeden izolowany segment laboratoryjny: VLAN XX (192.168.XX.XX/24).
Faza 5: Przebudowa sieci i pułapka Wi-Fi Trunking w Hyper-V
Nowy plan zakładał, że host wirtualizacji połączy się po domowym Wi-Fi, a ruch z maszyn wirtualnych będzie tagowany ramkami 802.1Q (Trunk) wewnątrz Hyper-V i wysyłany do MikroTika.
Nic nie zadziałało. Wirtualki nie dostawały adresów DHCP, a host fizyczny nie mógł wynegocjować połączenia wewnątrz labu.
Root cause: Fizyczne i programowe ograniczenie warstwy bezprzewodowej. Standardowe karty Wi-Fi w laptopach konsumenckich (oraz ich sterowniki w Windows) aktywnie usuwają (stripują) tagi VLAN z ramek przesyłanych drogą radiową. Ruch opuszczający wirtualny switch był po prostu niszczony.
Obejście (Workaround): Zamiast pchać Trunk przez Wi-Fi, odwróciłem logikę. Podziału dokonuje sam MikroTik. Stworzyłem dedykowany wirtualny punkt dostępowy (Virtual AP), stylizowany na sieć domową, aby wtopić się w tło bloku mieszkalnego:
/interface wifi add name=wifi_xxx master-interface=wifiXX security=xxx_lab configuration.ssid="[...]"
Interfejs ten został dodany do mostka jako Access Port z wymuszonym PVID XX:
/interface bridge port add bridge=bridge interface=xxx_lab pvid=xx
/interface bridge port set [find interface=etherX] pvid=xx
Na hoście Hyper-V przełącznik zewnętrzny przestał tagować cokolwiek. Laptop spinał się z wirtualnym SSID, a router sam zrzucał i nakładał tag VLAN XX. Sieć ruszyła natychmiast.
Faza 6: Błąd 3099 (Zombie w Wazuh)
Gdy sieć się ustabilizowała w VLAN XX, adres IP Malinki się zmienił. Wszedłem na Dashboard, a tam powitał mnie krytyczny alert: Some Wazuh daemons are not ready yet (wazuh-remoted->failed).
Skrypt systemowy wazuh-control status twierdził, że usługi działają. W rzeczywistości demon remoted (odpowiedzialny za nasłuch agentów na portach 1514/1515) zawiesił się, ponieważ gniazda sieciowe zgubiły bindowanie podczas gwałtownej zmiany topologii interfejsu (odnowienie DHCP).
Wystarczył brutalny restart całego silnika z poziomu SSH:
sudo systemctl restart wazuh-manager
Demon wyczyścił stare procesy (PID), podniósł się poprawnie i zsynchronizował z API.
Faza 7: Wdrożenie Active Directory i konflikt NetBIOS
Na maszynie wirtualnej uruchomiłem Windows Server 2025. Host nazywał się „Pentagon”. Próba instalacji domeny w PowerShellu (Install-ADDSForest -DomainName "pentagon.lab") została natychmiast przerwana błędem: A NetBIOS domain name must be specified.
Rozwiązanie: Fundamentalny konflikt nazewnictwa. Instalator AD domyślnie próbował wygenerować nazwę NetBIOS domeny jako „PENTAGON”, co stanowiło konflikt z nazwą samego hosta. Windows na to nie pozwala.
Zmieniłem nazwę serwera na DC01 (Rename-Computer -NewName "DC01") i po restarcie proces przeszedł pomyślnie.
Faza 8: Złe Wi-Fi, Domenowy DNS i anomalie PowerShell w Windows 11
Kolejny krok: podłączenie klienckiej stacji Windows 11. Pierwszy test łączności – ping do pentagon.lab – nie odpowiadał. Zacząłem węszyć w ustawieniach karty sieciowej i DNS w poszukiwaniu błędów routingu, po czym… zorientowałem się, że Windows w tle samoczynnie połączył się z moją główną, domową siecią Wi-Fi, całkowicie poza moim nowym wirtualnym AP dla labu. Zwykły, prozaiczny błąd (klasyczne przeoczenie inżyniera), który kosztował mnie dobre kilkanaście minut szukania dziury w całym. Po ręcznym przełączeniu na właściwe SSID (VLAN XX) i upewnieniu się, że DNS wskazuje na kontroler (192.168.XX.XX), nazwa zaczęła odpowiadać.
Gdy sieć w końcu grała, podjąłem próbę podłączenia stacji z konsoli:
Add-Computer -DomainName "pentagon.lab" -Restart
Ku mojemu zaskoczeniu, mimo podania poprawnych poświadczeń Enterprise Admina, konsola wyrzuciła czerwony błąd: Access is denied. Skrypt uparcie odmawiał współpracy.
Obejście problemu: Użyłem graficznego interfejsu systemu Windows. Po wywołaniu monitu o hasło w oknie GUI, te same poświadczenia zostały zaakceptowane bez błędu, a maszyna dołączyła do domeny.
Faza 9: Abstrakcja Sesji w Hyper-V
Utworzyłem w AD użytkownika testowego jdoe. Przy próbie zalogowania na jego konto poprzez konsolę maszyn wirtualnych Hyper-V, system odrzucił połączenie z błędem o braku uprawnień do usług pulpitu zdalnego.
Diagnoza: Konsola Hyper-V uruchamia się domyślnie w „Trybie sesji rozszerzonej” (Enhanced Session). Pod spodem nie jest to czysty podgląd wideo, ale tunelowana sesja RDP. Zwykli użytkownicy domeny nie mają praw do logowania zdalnego.
Rozwiązałem to, logując się na lokalnego administratora i dodając jdoe do lokalnej grupy Remote Desktop Users poprzez przystawkę lusrmgr.msc.
Faza 10: Agenty SIEM i błędy HTTP 403
Na sam koniec chciałem pobrać agentów Wazuh na maszyny z Windows za pomocą PowerShell. Wywołałem komendę Invoke-WebRequest, ale z rozpędu wklepałem złą wersję w adresie URL:
Invoke-WebRequest -Uri "https://packages.wazuh.com/4.x/windows/wazuh-agent-4.15.0-1.msi" -OutFile "$env:tmp\wazuh-agent.msi"
msiexec.exe /i "$env:tmp\wazuh-agent.msi" /q WAZUH_MANAGER="192.168.XX.XX"
Dostałem błąd (403) Forbidden. Przez chwilę zacząłem już dorabiać do tego teorię o zaawansowanych regułach anty-botowych na serwerach CDN Wazuha, które niby blokują domyślny nagłówek User-Agent w PowerShellu.
Prawda okazała się znacznie bardziej banalna – po prostu walnąłem literówkę w adresie (wersja 4.15 zamiast 4.11), a serwer odrzucił zapytanie o nieistniejący plik.
Po poprawieniu linku na właściwy, to samo polecenie Invoke-WebRequest przeszło gładko i instalator pobrał się bez żadnego kombinowania. Na koniec trzeba było tylko uruchomić nowo zainstalowaną usługę, wpisując komendę wskazaną przez kreator Wazuha
NET START WazuhSvc
Największe Wyzwania i Lessons Learned
- Wi-Fi i VLANy to toksyczny związek: Największym błędem koncepcyjnym była próba puszczenia „otagowanego” ruchu sieciowego (VLAN XX) przez zwykłą kartę Wi-Fi w laptopie prosto do maszyn wirtualnych w Hyper-V. Straciłem na to mnóstwo czasu, szukając błędów w wirtualnym switchu, podczas gdy problem był prosty: zwykłe karty Wi-Fi w Windowsie po prostu te tagi ucinają. Zamiast walczyć z systemem, przeniosłem ten problem na router – stworzyłem na MikroTiku osobne, wirtualne Wi-Fi (Virtual AP) dedykowane tylko dla labu i to uratowało projekt.
- PowerShell nie zawsze ma rację (GUI ratuje życie): Zawsze zakładałem, że konsola potrafi więcej niż interfejs graficzny. Tymczasem przy próbie dodania komputera do domeny PowerShell twardo rzucał błędem
Access is denied, a stare, poczciwe okienko Windows (Właściwości systemu) przyjęło te same hasła bez zająknięcia. Z kolei problem z logowaniem użytkownika w Hyper-V uświadomił mi prozaiczną rzecz: „Enhanced Session” (Tryb sesji rozszerzonej) to pod maską po prostu pulpit zdalny (RDP), do którego zwykły użytkownik domeny nie ma domyślnie dostępu. - Restrykcyjność nazw w AD: Błąd NetBIOS przy promowaniu kontrolera domeny był klasykiem. Dokumentacja Microsoftu zawsze podaje ujednolicone przykłady w stylu
DC01, przez co rzadko trafia się na błąd wynikający z tego, że fizyczna nazwa komputera („Pentagon”) i nazwa domeny („pentagon.lab”) wchodzą ze sobą w konflikt. - Znaczenie Rollback Planu: W sieciach nie ma pojęcia „jakoś to naprawię”, gdy przez jedną złą regułę odetniesz sobie routing na głównym routerze. Posiadanie przygotowanego, binarnego backupu
.backupna MikroTiku przed zabawą z filtrowaniem VLANów na bridge’u było moją jedyną deską ratunku przed całkowitym paraliżem sieci w domu. - Najprostsze błędy bolą najbardziej: Zanim zaczniesz szukać skomplikowanych błędów w routingu, DNS-ach czy blokadach na firewallu, upewnij się, że… jesteś podłączony do właściwej sieci. Sytuacja, w której Windows sam przepiął mnie na domowe Wi-Fi (przez co nie mogłem spingować domeny labowej), przypomniała mi, że przy debugowaniu zawsze trzeba zaczynać od absolutnych podstaw. Podobnie było z błędem 403 przy pobieraniu instalatora Wazuha – zamiast spisku serwerów, powodem była zwykła literówka w adresie URL.
Finalna Architektura i Przepływ Ruchu
Obecne środowisko działa stabilnie i izoluje złośliwy (lub testowy) ruch od sieci domowej.
[INTERNET]
|
[Router MikroTik (VLAN Filtering: Enabled)]
|
|-- [Nietagowany LAN / Zarządzanie] -> IP: 192.168.XX.0/24
| |-- Stacja inżynierska (Headless SSH/Web do SOC)
|
|-- [VLAN XX - Lab] ----> IP: 192.168.YY.0/24
|-- Port fizyczny (Access) ----> Raspberry Pi 5 (NVMe, WazuhSIEM)
|-- Virtual AP (Access) ----> Sieć bezprzewodowa "[...]"
|
+-- Host wirtualizacji (IP: .XXX)
|-- Hyper-V External Virtual Switch
|-- Windows Server 2025 "DC01" (IP: static)
|-- Windows 11 Klient (IP: static)
Maszyny z segmentu Windows komunikują się z serwerem Wazuha bezpośrednio w warstwie drugiej przełącznika w MikroTiku. Mój laptop zarządczy swobodnie routuje się do VLAN XX dzięki regułom firewall (Forwarding L3).
Roadmapa v3.0
Fundament pod testowanie ataków został wylany. Zamiast przekombinowywać z infrastrukturą, w kolejnych etapach skupię się na tym, co daje najwięcej frajdy – czyli walce Offense vs Defense:
Wdrożenie Sysmona: Instalacja System Monitora na końcówkach z Windows i wgranie dobrych polityk audytu, by SIEM w końcu widział dokładnie tworzenie procesów, wywołania z wiersza poleceń czy podejrzane modyfikacje rejestru.
Fizyczny Attack Box (Kali Linux): Zamiast stawiać kolejne maszyny wirtualne, do testów ofensywnych wykorzystam mojego osobnego laptopa z Kali Linuxem. Wystarczy, że podepnę się do sieci labowej (VLAN XX) i zacznę emulować zagrożenia (skanowanie sieci, ataki na Active Directory).
Strojenie detekcji (Blue Team): Kiedy fizyczny Kali zacznie generować szum w sieci, moim zadaniem będzie weryfikacja, co dokładnie łapią domyślne reguły Wazuha, a następnie pisanie własnych, niestandardowych reguł detekcji pod konkretne ataki.
Projekt kosztował wiele nerwów, ale debugging sieciowy, komendy konfiguracyjne i wiedza operacyjna, jaką z niego wyniosłem, są bezcenne. Praktyka wciąż weryfikuje teorię w najmniej oczekiwanych momentach.