Pierwszy artykuł o domowym laboratorium komputerowym spotkał się z dużym zainteresowaniem, więc kontynuujemy temat – dzisiaj pochylimy się nad podstawowymi kwestiami bezpieczeństwa takiego rozwiązania.
Wiecie już, czym jest homelab i dlaczego warto go zbudować. Czas zatem poznać kilka propozycji oraz podejść do łatwego podniesienia bezpieczeństwa systemów opartych na Linuksie. Kilka z przedstawionych zagadnień będzie miało znaczenie w kolejnych odcinkach, gdzie skupimy się na konfiguracji poszczególnych narzędzi, takich jak np. Wazuh.
Artykuły w tej serii mają w założeniu mieć charakter praktyczny. Stąd też celowo pomijamy aspekty instalacji i bazowej konfiguracji systemu oraz usług (informacji na ten temat w sieci nie brakuje), a skupiamy się wyłącznie na najważniejszych zagadnieniach związanych z danym tematem.
W tym artykule znajdziecie subiektywną listę rozwiązań, które możecie wykorzystać do zabezpieczenia systemów linuksowych. Narzędzia te nie są jedynymi dostępnymi do wykorzystania, ale są uniwersalne i łatwe w zastosowaniu przy budowie homelabu. W artykule omówimy:
- Dobór dystrybucji pod docelowe zastosowania w homelabie.
- Firewall – na przykładzie UFW pokazujemy, jak łatwo wdrożyć politykę firewalla na Linuksie.
- Bezpieczeństwo SSH – wskazujemy, jaki kierunek warto obrać przy wykorzystaniu tego podstawowego protokołu komunikacyjnego.
- Fail2Ban – pokazujemy, jak łatwo można zredukować listę prób ataków na usługę SSH.
- Lynis – wskazujemy, jak przeprowadzić audyt stanu bezpieczeństwa systemu oraz usług na nim działających w oparciu o rekomendacje standardu CIS.
- Auditd – wdrażamy mechanizm logowania zdarzeń systemowych.
- LKRG – wspominamy o module jądra Linuxa, które warto rozważyć jako prewencyjną ochronę jądra przed exploitami.
- Ansible – krótka zapowiedź automatyzacji z Ansible, która nawet w małym środowisku homelabowym znacznie upraszcza proces administracji serwerami.
Jaką wybrać dystrybucję i gdzie uruchamiać?
Możemy wybrać dowolną dystrybucję Linuksa. Warto poznać kilka z nich, aby zobaczyć różne podejścia do użytkowania, zarządzania czy utrzymywania. Wiele osób zaczyna od dystrybucji takich jak Ubuntu, Debian czy Fedora, a bardziej ambitni od Rocky Linuxa (następcy CentOS), Archa, a nawet Gentoo. Wszystko zależy od tego, jakie macie plany, a także ile czasu chcecie poświęcić na zagadnienia, które planujecie realizować z wykorzystaniem danej dystrybucji.
Na pewno warto zwrócić uwagę na długość wsparcia dla danej dystrybucji, dlatego w przypadku np. Ubuntu polecamy wydania LTS (ang. Long Time Support). Mają one zapewniony dłuższy czas wsparcia w kontekście aktualizacji systemowych i poprawek bezpieczeństwa. Drugim istotnym aspektem jest także popularność samej dystrybucji – im większa, tym łatwiej będzie znaleźć rozwiązania naszych problemów.
W tej serii artykułów będziemy uruchamiać hosty oparte na dystrybucji Ubuntu Server 22.04 LTS.
Gdzie uruchamiać wspomniane dystrybucje? Wszystko zależy od tego, czym dysponujecie w swoim homelabie. Może to być stary komputer stacjonarny, dedykowana stacja robocza lub serwer, a może po prostu Raspberry Pi. Możecie postawić samodzielny, czysty system lub skorzystać z gotowych rozwiązań wirtualizacyjnych jak Proxmox czy ESXi. Oczywiście pamiętajcie też o możliwości konteneryzacji z wykorzystaniem np. Dockera.
W domu mam dedykowany serwer pod wirtualizację, na którym postawiłem Proxmoxa i tam hostuję większość usług uruchomionych w sieci. Na innym z serwerów zainstalowałem Ubuntu Server 22.04 LTS, który obsługuje skonteneryzowane usługi. Taki model pozwala mi na różne warianty testów i korzystania z wybranych usług.
Systemowy firewall – iptables, UFW
Firewall możemy skonfigurować na dwa sposoby. Możemy pójść ścieżką klasyczną w postaci iptables lub cel zrealizować znacznie łatwiejszym narzędziem do zarządzania regułami, czyli UFW. Poniżej pokażemy bardzo prosty przykład polityki do wdrożenia na przykładzie UFW.
Dobrą zasadą (jeśli tylko to możliwe) jest ograniczenie zewnętrznego dostępu do usług na serwerze tylko do określonej listy źródeł. Podobnie możemy zrobić także lokalnie w komunikacji wychodzącej z naszego systemu. Upraszczamy w ten sposób aspekt pilnowania nadmiarowo dostępnych usług sieciowych, które są uruchamiane na zarządzanym przez nas serwerze.
UFW jest domyślnie dostępny w dystrybucji Ubuntu, dlatego w pierwszej kolejności dodamy reguły, które stworzą bazową politykę. Następnie uruchomimy UFW i wyświetlimy dodane reguły. Zacznijmy od blokady ruchu przychodzącego z wyjątkiem usługi SSH.
sudo ufw default deny incoming
sudo ufw allow OpenSSH
Następnie zablokujmy ruch wychodzący z wyjątkami dla protokołu HTTP, HTTPS, DNS oraz SSH.
sudo ufw default deny outgoing
sudo ufw allow out http
sudo ufw allow out https
sudo ufw allow out 53
sudo ufw allow out OpenSSH
Ostatnim krokiem jest uruchomienie UFW i podejrzenie dodanych reguł w trybie numeracji.
sudo ufw enable
sudo ufw status numbered
W ten sposób wdrożyliśmy naszą podstawową politykę firewalla dla komunikacji zarówno IPv4, jak i IPv6. Jak widać, można ją edytować w prosty i klarowny sposób. Prawda, że łatwe?
Podstawowe zabezpieczenia protokołu SSH
Rekomendujemy skorzystanie z wytycznych CIS. Znajdziecie tam szereg podstawowych i rekomendowanych zabezpieczeń do wdrożenia. W przypadku SSH zwrócimy uwagę na najbardziej istotne zagadnienia:
- Rekomendujemy przejście na formę uwierzytelniania przez klucze SSH (zamiast wyłącznie hasła) przy zdalnym połączeniu do powłoki systemowej. To znacznie wpływa na bezpieczeństwo waszego serwera.
- SSH jest także świetnym rozwiązaniem do przekierowywania portów czy zdalnego montowania katalogów pomiędzy hostami. Nie wszyscy zdają sobie sprawę z wielu dodatkowych możliwości wykorzystania SSH w praktyce.
- SSH może też śmiało zastąpić usługi takie jak VPN, SMB/NFS.
Kolejną naszą rekomendacją jest zainstalowanie Fail2Ban, który będzie wykrywał próby nieautoryzowanego dostępu do serwera SSH. Będzie on blokował tych bardziej aktywnych atakujących na podstawie zdefiniowanej przez nas polityki.
Instalacja i konfiguracja sprowadza się do kilku komend. Najpierw skorzystamy z menadżera apt, a następnie tworzymy własny “jail.local”, który jest plikiem konfiguracyjnym dla naszych polityk. Możemy go stworzyć na podstawie kopii domyślnie dostępnej konfiguracji.
sudo apt update
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Przedstawione poniżej parametry są bazowe dla uruchomienia usługi. Kolejno wymienione regulują czas blokady, określają maksymalną liczbę prób nieudanego logowania, a także okres, w którym weryfikowana jest liczba takich prób.
bantime = 10m
maxretry = 5
findtime = 10m
W dalszej części konfiguracji musimy dodać jeszcze parametry dla wybranego przez nas protokołu. Poniższa konfiguracja będzie miała zastosowanie dla protokołu SSH.
[sshd]
enabled = true
mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
Po zapisaniu zmian wystarczy z pomocą polecenia systemctl zrestartować usługę, a także ustawić ją jako domyślnie uruchamianą przy starcie systemu.
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
W efekcie, gdy ktoś spróbuje zalogować się do naszego serwera w sposób nieautoryzowany, po liczbie ustalonych przez nas błędnych logowań zostanie zablokowany.
Lynis – sprawdzamy poziom zabezpieczenia systemu
Do weryfikacji stanu zabezpieczeń wykorzystamy program Lynis, który przeprowadza lokalny skan systemu operacyjnego. Otrzymamy raport podsumowujący aktywne zabezpieczenia lub ich brak, bazujący na wytycznych standardu CIS.
Standard CIS, a dokładniej Center of Internet Security, robi mnóstwo dobrej roboty dla budowania świadomości bezpieczeństwa, na przykład udostępniając za darmo dedykowane rekomendacje hardeningu systemów i usług sieciowych.
Uruchomienie Lynisa sprowadza się do kilku komend. Pobieramy najnowszą paczkę Lynisa, rozpakowujemy ją, zmieniamy uprawnienia dla katalogu Lynisa pochodzącego z paczki, a następnie przechodząc do niego uruchamiamy funkcję audytu całego systemu.
wget https://downloads.cisofy.com/lynis/lynis-3.0.9.tar.gz
tar xvf lynis-3.0.9.tar.gz
sudo chown -R 0:0 lynis
cd lynis/
sudo ./lynis audit system
W rezultacie możemy spodziewać się całkiem sporej listy zagadnień ocenionych przez Lynisa. Na czystym i nieskonfigurowanym docelowo systemie należy oczekiwać szeregu “niezgodności” dla przeanalizowanych ustawień. Poniższy raport prezentuje listę sprawdzonych parametrów kernela z wytypowaniem odchyleń dla rekomendowanych wartości (podanych w nawiasie po nazwie). Są one zgodne ze wspomnianymi rekomendacjami zabezpieczeń od CIS, a także dokładnie wytłumaczone w samym dokumencie. Aby go pobrać, musicie wypełnić formularz. Pamiętajcie, że są one przeznaczone do niekomercyjnego zastosowania.
Całość raportu wieńczy podsumowanie, które w punktacji 0-100 prezentuje stan bezpieczeństwa audytowanego systemu. Na tej podstawie jesteśmy w stanie przeanalizować braki w konfiguracji systemu oraz usług na nim działających. Wyznacza to praktyczny kierunek sukcesywnej poprawy zabezpieczeń, a także daje możliwość ich weryfikacji ad-hoc.
Logowanie zdarzeń w systemie
Dzienniki zdarzeń to jeden z kluczowych mechanizmów bezpieczeństwa, pomagających zarówno monitorować anomalie, jak i analizować ewentualne incydenty. My skorzystamy z Auditd, popularnego rozwiązania na systemach opartych na Linuksie. Pozwala na kolekcjonowanie zdarzeń, które mają miejsce w przestrzeni użytkownika systemowego, a także w samym jądrze systemu.
Instalacja i wdrożenie reguł do monitorowania jest prosta i wymaga użycia kilku komend. Reguły możemy dodać i budować w oparciu o wytyczne wspomnianego już benchmarku CIS lub skorzystać z gotowych list, dostępnych np. tutaj.
sudo apt update
sudo apt install auditd
Reguły zapisywane są w pliku /etc/audit/rules.d/audit.rules
. Za pomocą polecenia auditctl -l
możemy je wyświetlić. W domyślnej instalacji nie uświadczymy jednak żadnej reguły.
Dla pokazania, jak działa Auditd, dodajmy dwie proste reguły do pliku audit.rules. Będą one rejestrować zdarzenie uruchomienia przez użytkownika komendy nc. Warto ją monitorować z uwagi na częste wykorzystanie przez atakujących do otwierania portów dla zdalnego dostępu.
sudo auditctl -w /usr/bin/nc -k netcat_use
Zdarzenie wywołamy poprzez uruchomienie komendy nc w powłoce użytkownika lokalnego. Znajdziemy je potem w logach z wykorzystaniem komendy ausearch.
nc -vz adwersarz.pl 80
sudo ausearch -k netcat_use
Wpis w logu dostarcza dużo detali technicznych do dalszej analizy. Na przykład Wazuh, opierając się na takich danych, jest w stanie np. informować o anomaliach w systemie.
Linux Kernel Runtime Guard
Jest to moduł kernela, który odpowiada za reagowanie na wykryte anomalie związane z próbami wykorzystywania podatności w systemie operacyjnym. Zapewnia weryfikację w trybie rzeczywistym integralności i konfiguracji jądra systemowego, a także monitorowanie kluczowych struktur danych i funkcji jądra. W praktyce LKRG może znacznie utrudnić wykorzystanie Metasploita przez atakującego czy zablokować próbę ucieczki z przejętego kontenera do systemu hostującego.
Instalacja LKRG może wymagać większej uwagi i doświadczenia, ale nie jest żadnym wyzwaniem zarezerwowanym dla ekspertów. Poświęcimy jej w przyszłości osobny artykuł, tymczasem zachęcamy was do spróbowania samodzielnej instalacji i przetestowania.
Pamiętajcie o automatyzacji
Ansible to bardzo popularne narzędzie automatyzujące pracę z wieloma hostami. Usprawnia realizację nudnych, rutynowych zadań związanych z administracją systemami. W naszym homelabie możemy spodziewać się konieczności np. regularnych aktualizacji systemów. Wraz z rozwojem homelabu liczba rutynowych zadań, które nadają się do automatyzacji będzie tylko rosnąć 🙂
Na razie zostawiamy was z ogólnym wprowadzeniem do Ansible’a, a w jednym z odcinków tej serii przyjrzymy się, jak łatwo adaptować playbooki Ansible’a do działania.
Nawyk bezpieczeństwa “by default”
Wdrożenie zabezpieczeń wcale nie musi być nie lada wyzwaniem. Warto wyrobić w sobie nawyk myślenia o bezpieczeństwie już od początku budowania nowych systemów i sieci.
W artykule opisaliśmy tylko subiektywnie wybrane rozwiązania. Naszym celem jest budowa świadomości i zachęcanie do wdrażania i utrzymywania bezpiecznych systemów, dlatego pominęliśmy bardziej techniczne i wymagające zagadnienia. Podobnie z doborem narzędzi – chcemy zwrócić uwagę na łatwość ich wykorzystywania w praktyce. Jeśli jesteście chętni, aby któremuś z omawianych tematów przyjrzeć się bardziej – śmiało dajcie o tym znać w komentarzach!