Ansible i CIS Benchmark – automatyzacja zabezpieczeń systemów Linux i Windows Server
Kwestia zastosowania odpowiedniej konfiguracji serwerów czy zwykłych stacji roboczych to bardzo szeroki temat. Ilość opisywanych porad, sugestii i pomysłów potrafi być przytłaczająca. W tym wszystkim trzeba też odróżnić naprawdę istotne rekomendacje od prezentowanych przez „ekspertów” od wiedzy teoretycznej porad, które w praktyce nie znajdą zastosowania, a wręcz mogą okazać się szkodliwe czy choćby utrudnić zabezpieczenie usług. Każdy system operacyjny posiada też własne konfiguracje, a poleganie na samych ogólnych poradach w krótkim czasie okaże się niewystarczające. Oczywiście podstawy, czyli konfiguracja kopii zapasowych, monitoring usług (narzędziami takimi jak Zabbix), praca z dyskami i partycjami, czy wreszcie skuteczne zarządzanie dostępem użytkowników, należy zrozumieć i umiejętnie stosować – poznanie wymienionych elementów rzecz jasna wymaga poświęcenia godzin, jak również nabycia doświadczenia. Jednak poleganie wyłącznie na tych podstawowych krokach to tylko niewielka część czynności, które powinniśmy wykonać niezależnie od tego, czy dana maszyna jest dostępna publicznie czy działa wyłącznie w sieci lokalnej.
Przeprowadzenie szerszej konfiguracji serwera nie jest zresztą powiązane jedynie z bezpieczeństwem. Świadczy też o kompetencjach i poziomie zaawansowania (profesjonalizmu) administratora. Dla przykładu jeżeli zadanie polega na wdrożeniu jakiejkolwiek aplikacji dostarczanej jako kontener Docker, to zainstalowanie Docker Engine i uruchomienie kontenera co prawda zrealizuje cel tego zadania, ale tylko w minimalnym stopniu – poza tym w czasach AI nie będzie to szczególnie osiągnięcie, a w całym procesie człowiek o takim poziomie wiedzy może zostać łatwo zastąpiony. Znacznie łatwiej też zarządzać w przyszłości sensownie skonfigurowaną maszyną, a nie „porzuconym” hostem, którego przeznaczenie nie jest już do końca zrozumiałe.
Warto też wspomnieć, iż naprawdę dobrze wykonany hardening wymaga czasu, bo ilość konfiguracji do zmodyfikowania jest spora bez znaczenia, czy zajmujemy się serwerem działającym na RHEL, czy komputerem biurkowym (choćby prywatnym laptopem) z zainstalowanym Windows 11.
Do tego wszystkiego pojawia się problem wybrania wartych wdrożenia zaleceń. Przykładowe wymuszenie odpowiedniej „jakości” hasła w każdym systemie będzie realizowane w inny sposób. Ogromna część zaleceń, z jakimi możemy się spotkać, jest też przeznaczona dla konkretnego systemu, a próba ich częściowego zastosowania w innym może okazać się niemożliwa.
Na szczęście nie musimy pamiętać o wszystkich zaleceniach czy utrzymywać prywatnych notatek z zakresu działań hardeningowych. Dostępne są opracowane przez realnych specjalistów ogólne zalecenia, takie jak CIS Benchmarks. Dotyczą różnych systemów operacyjnych, urządzeń sieciowych i też usług, np. serwera HTTP Apache, serwera bazy danych MySQL itd.
Z drugiej strony nie wszystkie porady można wdrożyć, bo część z nich co prawda zabezpieczy nasze usługi na najwyższym poziomie, ale jednocześnie uniemożliwi korzystanie z nich. Zdrowy rozsądek jest zdecydowanie przydatny.
Dodatkowo zwróćmy uwagę na liczbę porad. Poradnik CIS dla AlmaLinux 10 zawiera 1140 stron. Oczywiście zapoznanie się z całą treścią może być doskonałą formą nauki i poszerzenia wiedzy, natomiast w ciągu ośmiu godzin pracy może nie wystarczyć czasu w przeczytanie całości, a co dopiero na wyselekcjonowanie i wdrożenie zaleceń.
Ansible Lockdown
Tutaj rozwiązanie stanowi Ansible Lockdown. Jest to zbiór roli Ansible dla sporej części systemów operacyjnych, które umożliwią bardzo łatwe wdrożenie zaleceń CIS bądź też STIG (te jednak mogą nie nadawać się do zwykłych zastosowań, bo są opracowane na potrzeby Departamentu Obrony USA – więcej można przeczytać w tym miejscu).
Co więcej, możliwe zalecenia zostały pogrupowane wedle zastosowania (serwer/stacja robocza), ale też pod kątem poziomu zabezpieczeń. Co do zasady, dla standardowych środowisk optymalny będzie „level1” – bardziej wrażliwe konfiguracje są odseparowane, więc de facto nie można spodziewać się, iż wykonania playbooka Ansible w jakikolwiek sposób uszkodzi nasz system. Jednak jak zawsze należy przetestować wcześniej działanie i przygotować kopię zapasową czy snapshot maszyny wirtualnej, aby zapewnić sobie sprawną możliwość naprawy, jeżeli efekt końcowy nie będzie zadawalający. Najlepiej też wykonywać wszystkie playbooki na tzw. czystym systemie, czyli bez zainstalowanego naszego oprogramowania.
Nie da się ukryć, iż różnice między zwykłym komputerem służącym do pracy a serwerem udostępniającym różne usługi są spore. Dlatego też podzielimy tę serię na dwa tematy. Dziś oprócz wstępu teoretycznego zajmiemy się bardzo konkretną instrukcją przygotowania do pracy z Ansible i uruchomimy playbook dla systemu Red Hat Enterprise Linux oraz Windows Server 2025.
Ansible
Ansible określa się jako „radically simple IT automation platform” – w dużym skrócie jest to rozwiązanie stosowane do automatyzacji powtarzalnych działań na serwerach. jeżeli chcielibyśmy na przykład zainstalować wybrany program na dziewięciu serwerach, to zamiast manualnego łączenia się z każdym i wykonywania tego samego polecenia, możemy wskazać Ansible, które hosty są w naszym zainteresowaniu i „opisać”, co zamierzamy wykonać. Konfiguracje Ansible są plikami YAML.
Nasi czytelnicy niedawno mieli okazję poznać Ansible Vault. Obsługa samego Ansible jest nieco bardziej zaawansowana, natomiast pokażemy, jak łatwo zastosować to narzędzie do hardeningu systemów. Do adekwatnej pracy służy polecenie ansible-playbook, a same czynności realizowane są „zdalnie” – poprzez SSH dla serwerów Linux i WinRM w systemach Windows. Zaletą Ansible jest fakt, iż na docelowych hostach nie musi być zainstalowany jakikolwiek agent, który oczekiwałby na polecenia. Tutaj z jednego miejsca w dowolnym czasie uruchamia się playbook, a ten wykonuje nasze instrukcje.
Ansible wbrew opisowi w repozytorium nie jest trywialnym narzędziem.
Konfiguracja do pracy z Ansible
Najszybszym sposobem przygotowania środowiska do uruchamiania playbooków jest oczywiście wykorzystanie konteneryzacji. Istnieje gotowy obraz alpine/ansible zawierający wszystkie potrzebne komponenty. Dla pojedynczego zastosowania można uruchomić tymczasowy kontener poleceniem
Jeśli do połączenia SSH zamierzamy użyć naszego klucza prywatnego, to wystarczy skopiować lokalny katalog .ssh do kontenera bądź też zwyczajnie podmontować tę lokalizację parametrem -v (wydanym wraz z docker run).
ansible-playbook nie powinien być wykonywany dla localhost. Należy logicznie odseparować hosty, którymi zarządzamy, od tego, na którym wykonujemy playbooki. Pozwoli to zachować też przejrzystość naszej pracy. Opisana metoda uruchomienia nie jest zależna od systemu operacyjnego – również na tym polega konteneryzacja.
W kontenerze poleceniem
instalujemy wiadomy pakiet, którym sklonujemy potrzebne repozytoria. Ansible Lockdown składa się z 98 repozytoriów. Każde jest dla innego systemu (jego wersji) i odpowiednio dla zaleceń CIS i STIG. Zdecydowanie najczytelniej widać to w tabelach na stronie https://github.com/ansible-lockdown.
Najlepiej utworzyć dedykowany katalog (np. ~/cis) i dopiero do tego katalogu klonować odpowiednie repozytoria (do roles/).
Procedura w tym przypadku jest następująca (dla wszystkich systemów):
- Utworzenie pliku inventory.
- Utworzenie playbooka.
- Sklonowanie wybranego repozytorium do roles.
- Użycie ansible-galaxy do zainstalowania „kolekcji”.
- Weryfikacja poprawności działania połączenia SSH/WinRM (próba połączenia SSH + ansible ping/win_ping).
- Uruchomienie playbooka.
Po kolei zaczynamy od pliku inventory, który możemy nazwać hosty. Jego zawartość powinna być analogiczna do poniższej.
W pliku playbooka (np. cis.yml) określamy hosty, na których ma on zostać wykonany, i wskazujemy rolę (nazwę repozytorium, które sklonujemy). Zapis become: true oznacza konieczność działania na uprawnieniach administratora w systemach Linux.
- hosts: serwery become: true roles: - RHEL10-CISKlonujemy repozytorium:
Weryfikujemy możliwość dostępu do hostów. W pierwszej kolejności sugeruję sprawdzić działanie samego połączenia SSH (co doda fingerprint serwera do pliku known_hosts), a następnie wykonać polecenie analogiczne do poniższego.
Jeśli dysponujemy kluczem prywatnym SSH, można pominąć parametr -k (–ask-pass). Ostatecznie uruchamiamy playbook.
Opcja -K (–ask-become-pass) dotyczy użycia hasła do podniesienia uprawnień. jeżeli do tej akcji zbędne jest podanie hasła (NOPASSWD:ALL w /etc/sudoers), to oczywiście rezygnujemy z tego parametru (domyślnie jego wartość jest równoznaczna z hasłem użytym do połączenia SSH). –tags to określenie omówionego wcześniej poziomu i zastosowania zabezpieczeń. Oprócz tego przed przypadkowym uruchomieniem hardeningu zastosowano w tej konkretnej roli (nie wszystkie posiadają tę funkcjonalność) wymóg określenia nazwy profilu (nazwa zmiennej będzie analogiczna dla innych ról).
Bezpieczeństwo systemów z ustawieniami domyślnymi
Przygotowałem dwie maszyny z zainstalowanymi systemami RHEL 10 i Windows Server 2025 – bez jakichkolwiek modyfikacji. Oprócz tego osobny serwer Wazuh, do którego poprzez agenty dodałem oba hosty. Wyniki audytu bezpieczeństwa są raczej negatywne.
Raport zgodności z CIS Benchmark systemu RHEL 10
Raport zgodności z CIS Benchmark systemu Windows Server 2025
Hardening Red Hat Enterprise Linux
Zaczniemy od hardeningu pierwszego serwera. Sprawdzamy komunikację Ansible do docelowego hosta. W odpowiedzi powinno zostać zwrócone pong.
Weryfikacja połączenia Ansible
Teraz wykonujemy kopię zapasową bądź snapshot maszyny wirtualnej. jeżeli działanie playbooka zweryfikujemy na czystym systemie, to w przyszłości ten krok będzie można traktować jako opcjonalny.
I wreszcie uruchamiamy playbook podanym wyżej poleceniem. Przeprowadzenie wszystkich kroków hardeningu zajmuje nieco czasu – można porównać, ile godzin spędzilibyśmy w sytuacji braku tej automatyzacji.
Działanie playbooka na hoście z systemem RHEL
Playbook realizuje wybrany zestaw zaleceń z CIS Benchmark dla danego systemu. Bardzo duża ilość rekomendacji może być choćby nieznana, bo obejmuje aspekty, które w codziennej pracy ciężko spotkać. To jest właśnie sensowny hardening – minimalizacja wszelkich „wejść” do systemu.
Po udanym wykonaniu (każdego) playbooka pojawi się podsumowanie.
Pomyślne zakończenie wykonywania playbooka
Jak widać, wprowadzonych zostało 135 modyfikacji. To bardzo poprawne działanie. jeżeli dany element nie istnieje w naszym systemie bądź posiada już założone ustawienia, to nie wykonujemy jego rekonfiguracji, co i tak zakończyłoby się błędem. Zresztą można teraz ponowić playbook i przekonać się, iż liczba widoczna przy statusie changed będzie znacznie mniejsza.
Zredukowana liczba zmodyfikowanych elementów po ponownym wykonaniu playbooka
Tę cechę określa się jako idempotentność. Dzięki takiej konstrukcji roli Ansible można bez większego ryzyka uruchamiać playbooki kilkukrotnie – aczkolwiek akurat w przypadku Ansible Lockdown należy tę operację wykonać jeden raz (możliwie bezpośrednio po zakończeniu instalacji systemu), bo po wykryciu faktu zainstalowania niektórych kluczowych pakietów playbook podejmuje próbę ich usunięcia.
Zalecane jest ponowne uruchomienie serwera.
Można powiedzieć, iż wprowadzone przez playbook zmiany widoczne są na pierwszy rzut oka. W konsoli, zamiast standardowego „banera powitalnego” z nazwą i wersją systemu zobaczymy ostrzeżenie.
Zmieniony /etc/issue
Podobnie podczas nawiązywania połączenia SSH.
Ostrzeżenia podczas logowania SSH
Jest to efekt zapisania treści tego ostrzeżenia w plikach /etc/issue i /etc/issue.net oraz ustawienia opcji Banner w pliku /etc/ssh/sshd_config.
Również w wynikach audytu Wazuh widać pewną poprawę poziomu bezpieczeństwa naszego serwera. Ogromna część uwag co do jakości naszej konfiguracji to wynik użytego języka w systemie – dla przykładu sprawdzenie istnienia wybranej paczki w systemie wymaga wyjścia o treści „package X is not installed”, a jeżeli w systemie używamy języka polskiego, to zwrotka brzmi „pakiet X nie jest zainstalowany”.
Ponowny audyt zgodności z CIS Benchmark
Nie trzeba jednak zmieniać języka w całym systemie, bo Linux umożliwia zastosowanie „języka” na poziomie usługi. Edytujemy więc konfigurację jednostki wazuh-agent i w sekcji Service dopisujemy
Restartujemy agenta. Po chwili będzie można spodziewać się znacznie lepszych wyników audytu.
Zgodność z CIS Benchmark po zmianie języka wazuh-agent
Pozostałe weryfikacje ze statusem Failed dotyczą w dużej mierze kwestii związanych z osobnymi partycjami dla /tmp, /var, /var/tmp, /var/log, /var/log/audit i /home. Mimo wszystko dzięki roli Ansible Lockdown dla RHEL 10 udało nam się skutecznie rozwiązać wiele „problemów” bezpieczeństwa istniejących w systemie działającym z ustawieniami domyślnymi.
Ostatecznie po skonfigurowaniu odpowiednich partycji i ponownym uruchomieniu playbooka celem dodania adekwatnych parametrów do /etc/fstab, wyniki prezentowane w Wazuh stają się co najmniej obiecujące.
Wyniki audytu po dodaniu osobnych partycji
Z kolei uruchomienia playbooka z kolejnym tagiem level2-server nieznacznie poprawiło ogólny score. Pozostały już tylko naprawdę pojedyncze zalecenia.
Ostateczne wyniki audytu zgodności z CIS Benchmark
Oczywiście wyniki podane przez Wazuh należy traktować raczej jako orientacyjne – nikt nie twierdzi, iż uzyskanie score 100% jest celem samym w sobie. Wszystko należy dostosować do własnych wymagań, skali działania oraz charakterystyki środowiska. Nie istnieją gotowe scenariusze zabezpieczeń dostosowane dla wszystkich. Mimo wszystko modyfikacje wprowadzane przez role Ansible Lockdown stanowią dobry kompromis między bezpieczeństwem, a możliwością efektywnej pracy w systemie.
Hardening Windows Server
Konfiguracja dla Windows w pliku inventory powinna wyglądać w ten sposób:
Dodatkowo potrzebujemy zainstalować moduł Python o nazwie pywinrm. Dla obrazu alpine/ansible wystarczy wykonać:
Sama weryfikacja działania połączenia wykorzystuje win_ping – i tak zostaniemy poproszeni o podanie SSH password, ale rzecz jasna SSH nie jest używane.
W cis.yml (playbooku) należy usunąć bądź zakomentować linię become: true. Uruchamiamy:
Po pewnym czasie pojawi się następujący problem:
Błąd wykonania playbooka
Przyczyną jest blokada tokenu konta Administrator przy logowaniu zdalnym spowodowana ustawieniem FilterAdministratorToken w rejestrze na wartość 1 – to właśnie wykonuje poprzedni task Ensure User Account Control Admin Approval Mode for the Built-in Administrator account is set to Enabled.
- name: "2.3.17.1 | PATCH | Ensure User Account Control Admin Approval Mode for the Built-in Administrator account is set to Enabled" when: win25cis_rule_2_3_17_1 tags: - level1-domaincontroller - level1-memberserver - rule_2.3.17.1 - patch - uac - NIST800-171_3.1.1 - NIST800-53R5_AC-2_9 ansible.windows.win_regedit: path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System name: FilterAdministratorToken data: 1 type: dwordRozwiązanie jest trywialne, ponieważ wystarczy założyć osobne konto z uprawnieniami administratora dedykowane dla Ansible. Po zmianie nazwy użytkownika w pliku inventory pozostała część playbooka powinna wykonać się w pełni poprawnie. Po zakończeniu wykonujemy restart.
Playbook zabezpieczający Windows Server
W Wazuh jest widoczna znacząca różnica w stosunku do stanu bezpośrednio po instalacji.
Raport Wazuh z audytu po uruchomieniu playbooka
Wprowadzone zmiany można odnotować także bezpośrednio przy próbie lokalnego zalogowania do serwera.
Baner przy logowaniu do systemu Windows Server
Z ekranu logowania zniknęły również „podpowiedzi” nazw użytkowników. Należy podać nazwę konta i jego hasło.
Od razu też można będzie zauważyć różnicę podczas pracy na wbudowanym koncie Administrator – procesy nie będą już „automatycznie” startować na prawach administratora, a wymagane będzie zatwierdzenie UAC. Podobnie przy próbie wyłączenia/restartu systemu, gdzie również pojawi się odpowiedni monit.
Nie pozostaje nam nic innego, jak tylko uruchomić playbook z tagiem level2-domaincontroller. Wyniki audytu w Wazuh będą znakomite.
Ostateczne rezultaty zabezpieczenia Windows Server
Jeśli zainstalujemy Active Directory Domain Services i wykonamy promote naszej maszyny do kontrolera domeny, po czym raz jeszcze uruchomimy playbook, to nastąpi nieznaczna poprawa.
Audyt bezpieczeństwa po uruchomieniu AD DS
Podsumowanie
Dzięki prostej automatyzacji udało nam się w zasadzie bez jakichkolwiek trudności znacząco podnieść bezpieczeństwo naszych systemów serwerowych. Wykonanie tych wszystkich kroków bez użycia Ansible zajęłoby znacznie więcej czasu, a pamiętajmy, iż analogiczne zadania powinny być do wykonania nie tylko na jednej maszynie – stąd jakakolwiek automatyzacja jest uzasadniona. Ansible Lockdown uświadamia również, iż procesy hardeningu mogą zostać zintegrowane w standardowy workflow konfiguracji serwerów i nie trzeba tych tematów traktować oddzielnie. Oczywiście hardening należy przeprowadzać na możliwie „czystym” systemie albo przygotować „system wzorcowy”, a kolejne maszyny tworzyć z template. Wszystko też zależy, czy pracujemy z usługami cloud, posiadamy własną serwerownię, albo w ogóle obsługujemy wyłącznie komputery pracowników.
Zdecydowana większość modyfikacji wprowadzanych przez opracowane role jest częścią zaawansowanych zagadnień, których istnienia być może nie zakłada żaden administrator. Ansible Lockdown stanowi więc możliwość dostosowania zabezpieczeń bez konieczności poświęcenia dużej ilości czasu w zgłębienie niektórych aspektów pracy systemów. Z drugiej strony może być to okazja do zainteresowania się pewnymi obszarami w czasie wolnym.
W następnej części skoncentrujemy się na systemach desktopowych Windows 11 i Ubuntu 26.04. Sprawdzimy, czy wprowadzone zmiany będą mieć negatywny wpływ na wygodę pracy zwykłego użytkownika.
Jeśli interesuje Cię nie tylko wdrażanie zabezpieczeń dzięki Ansible i benchmarków CIS, ale także monitorowanie ich zgodności, sprawdź nasz artykuł o Wazuh jako darmowym rozwiązaniu SIEM i XDR.




.jpg)

