Linux

Linux Hardening Audyt bezpieczeństwa serwera Linux — jak sprawdzić, czy hardening naprawdę działa

Linux Hardening: Audyt bezpieczeństwa serwera Linux — jak sprawdzić, czy hardening naprawdę działa

Można mieć firewall, AppArmor, automatyczne aktualizacje, SSH na kluczach, Docker uruchomiony rootless i kilka stron konfiguracji opisujących „bezpieczny serwer”.

A potem wystarczy jedno polecenie:

sudo ss -tulpn

i okazuje się, że na publicznym adresie nasłuchuje usługa, o której administrator dawno zapomniał.

To właśnie dlatego hardening nie kończy się w momencie konfiguracji. Konfiguracja jest tylko hipotezą. Audyt ma sprawdzić, czy ta hipoteza jest prawdziwa.

Na Netbe istnieje już praktyczny materiał poświęcony audytowi Linuxa z użyciem Lynis. (Netbe) Ten artykuł traktuję jako kolejny poziom: nie „jak uruchomić skaner”, ale jak myśleć jak audytor i jak ręcznie zweryfikować najważniejsze wyniki.

Zaczynamy od pytania: co właściwie chronimy?

Nie istnieje coś takiego jak „bezpieczny Linux” w oderwaniu od zastosowania.

Serwer WWW, serwer bazodanowy, host Dockera, router, stacja robocza i maszyna administracyjna mają zupełnie inne powierzchnie ataku.

Dlatego pierwszy etap audytu nie powinien wyglądać tak:

Uruchom Lynis
       ↓
Napraw wszystko na czerwono
       ↓
Gotowe

Znacznie lepiej:

Rola serwera
     ↓
Powierzchnia ataku
     ↓
Mechanizmy ochronne
     ↓
Stan rzeczywisty
     ↓
Luki konfiguracyjne
     ↓
Priorytety napraw

To ważne, ponieważ narzędzie audytowe może wskazać wiele rzeczy, które są formalnie warte poprawy, ale nie wszystkie mają takie samo znaczenie dla konkretnego systemu.

Audyt zaczyna się od powierzchni ataku

Pierwsze polecenie, które uruchamiam, jest banalne:

sudo ss -tulpn

Nie interesuje mnie jeszcze, czy wynik wygląda „dobrze”.

Interesuje mnie, czy rozumiem każdy wpis.

Jeżeli widzę:

0.0.0.0:22
0.0.0.0:80
0.0.0.0:443
127.0.0.1:5432

mam już kilka istotnych informacji.

SSH, HTTP i HTTPS są dostępne przez wszystkie interfejsy.

PostgreSQL tylko lokalnie.

To zupełnie inna sytuacja niż:

0.0.0.0:5432

Wtedy baza danych przestaje być wyłącznie usługą wewnętrzną.

Pierwsze pytanie audytora brzmi więc nie „czy port jest otwarty?”, ale „czy ten port powinien być otwarty właśnie tutaj?”.

Drugi etap: co uruchamia się razem z systemem?

Kolejny krok:

systemctl list-unit-files --state=enabled

oraz:

systemctl --type=service --state=running

To dwa różne spojrzenia.

Pierwsze pokazuje usługi skonfigurowane do automatycznego uruchamiania.

Drugie pokazuje to, co faktycznie działa.

Różnica między nimi jest istotna.

Możesz mieć usługę włączoną, ale obecnie zatrzymaną.

Możesz również mieć usługę uruchomioną ręcznie, mimo że nie jest permanentnie włączona.

Audyt powinien wykrywać oba przypadki.

Najczęstszy problem: serwer robi więcej, niż powinien

Wyobraź sobie VPS przeznaczony wyłącznie do hostowania strony.

Powinien prawdopodobnie potrzebować:

SSH
HTTPS
HTTP

A audyt pokazuje:

SSH
HTTP
HTTPS
SMTP
PostgreSQL
Redis
Avahi
CUPS
RPC

Nie oznacza to automatycznie, że system jest podatny.

Oznacza jednak, że administrator powinien umieć wyjaśnić obecność każdej usługi.

Jeżeli nie potrafi, właśnie znaleźliśmy problem administracyjny.

Minimalizacja powierzchni ataku nie polega na magicznym ustawieniu jednego parametru.

Polega na tym, że system wykonuje tylko te zadania, których rzeczywiście potrzebuje.

Firewall: „mam UFW” nie jest wynikiem audytu

Kolejny klasyczny błąd.

Administrator mówi:

Mam UFW, więc firewall jest skonfigurowany.

Sprawdzamy:

sudo ufw status verbose

I widzimy:

Status: active

Koniec?

Nie.

To dopiero informacja, że mechanizm działa.

Teraz trzeba sprawdzić politykę.

Czy ruch przychodzący jest domyślnie blokowany?

Czy SSH jest dostępne z całego Internetu?

Czy przypadkiem nie ma reguły:

ALLOW Anywhere

która została dodana pół roku temu podczas diagnostyki?

W istniejącym przewodniku hardeningu Netbe również przyjęta jest zasada ograniczania ruchu przychodzącego do rzeczywiście potrzebnych usług. (Netbe)

Następny test: aktualizacje

To miejsce często daje fałszywe poczucie bezpieczeństwa.

Administrator wykonuje:

sudo apt update
sudo apt upgrade

i uznaje temat za zamknięty.

Ale bezpieczeństwo aktualizacji to również proces.

Na Ubuntu mechanizm unattended-upgrades może automatycznie instalować aktualizacje bezpieczeństwa, a jego działanie jest logowane.

Sprawdzam więc nie tylko, czy pakiety są aktualne, ale również:

systemctl status unattended-upgrades

oraz:

ls -lah /var/log/unattended-upgrades/

Można również wykonać test bez instalowania zmian:

sudo unattended-upgrade --dry-run

To ważna różnica.

„Mam automatyczne aktualizacje” jest założeniem. „Widzę historię ich działania i potrafię potwierdzić konfigurację” jest dowodem.

AppArmor: aktywny nie znaczy skuteczny

Na Ubuntu AppArmor jest instalowany i ładowany domyślnie. Stan można sprawdzić przez:

sudo aa-status

Ale tutaj również nie kończy się audyt.

Interesuje mnie:

  • ile profili jest załadowanych,
  • które działają w enforce,
  • które działają w complain,
  • czy krytyczne usługi są rzeczywiście objęte profilami.

To ogromna różnica.

Profil w enforce faktycznie egzekwuje politykę.

Profil w complain przede wszystkim raportuje naruszenia, ale ich nie blokuje. Ubuntu dokumentuje oba tryby wprost.

Jeżeli ktoś mówi:

„Mam AppArmor.”

pytam:

„Które procesy są ograniczone i w jakim trybie?”

Dopiero wtedy zaczyna się prawdziwy audyt.

Logi AppArmor mówią więcej niż sam status

Jeżeli aplikacja próbowała wykonać operację zablokowaną przez profil, informacja może pojawić się w logach systemowych lub audit logach.

Możemy więc szukać zdarzeń:

sudo journalctl -k | grep -i apparmor

albo:

sudo grep -i apparmor /var/log/audit/audit.log

Nie należy jednak traktować każdego DENIED jako dowodu ataku.

Może to być prawidłowo zablokowana operacja aplikacji.

Może to być źle skonfigurowany profil.

Może to być nietypowa konfiguracja usługi.

Audyt wymaga interpretacji kontekstu.

Następny problem: użytkownicy

Teraz schodzimy niżej.

cut -d: -f1 /etc/passwd

Samo wyświetlenie użytkowników niczego jeszcze nie daje.

Pytanie brzmi:

kto naprawdę potrzebuje dostępu do systemu?

Następnie sprawdzam konta posiadające powłokę:

grep -E '/bin/(bash|sh|zsh)$' /etc/passwd

oraz grupę administratorów:

getent group sudo

Na serwerze produkcyjnym nie chcę pięciu przypadkowych kont posiadających możliwość uzyskania roota.

Chcę wiedzieć:

Konto
  ↓
Dlaczego istnieje?
  ↓
Jak się loguje?
  ↓
Do czego ma dostęp?
  ↓
Czy nadal jest potrzebne?

To prosty model, ale niezwykle skuteczny.

Root nie powinien być odpowiedzią na każdy problem

Jedno z najbardziej charakterystycznych zachowań podczas administracji Linuksem:

sudo -i

a potem wszystko zaczyna działać.

To świetne narzędzie diagnostyczne.

Fatalna strategia bezpieczeństwa.

Jeżeli aplikacja potrzebuje uprawnień roota, pytam dlaczego.

Jeżeli kontener potrzebuje --privileged, pytam dlaczego.

Jeżeli usługa systemd potrzebuje pełnego zestawu capabilities, pytam dlaczego.

W hardeningu najcenniejsze pytanie często brzmi:

„Czy naprawdę tego potrzebujesz?”

Co z SSH?

SSH zasługuje na osobny audyt.

Najpierw:

sudo sshd -T

To bardzo przydatne, ponieważ pokazuje efektywną konfigurację serwera SSH po uwzględnieniu konfiguracji.

Sprawdzam między innymi:

permitrootlogin
passwordauthentication
pubkeyauthentication
maxauthtries
x11forwarding
allowtcpforwarding

Nie wystarczy spojrzeć na /etc/ssh/sshd_config.

Liczy się konfiguracja, którą daemon faktycznie stosuje.

To jedna z podstawowych różnic pomiędzy czytaniem pliku a audytem działającego systemu.

A teraz ciekawy test: czy system pozwala na eskalację?

Sprawdzam:

sudo -l

dla odpowiednich użytkowników.

Szczególnie interesują mnie reguły NOPASSWD i szerokie uprawnienia do wykonywania programów jako root.

Przykład:

user ALL=(ALL) NOPASSWD: /usr/bin/some-program

nie musi być błędem.

Ale musi mieć uzasadnienie.

Najgorsza konfiguracja bezpieczeństwa to taka, której nikt już nie pamięta.

Kernel również podlega audytowi

Hardening nie kończy się na usługach.

Sprawdzam podstawowe parametry:

sysctl kernel.randomize_va_space
sysctl kernel.kptr_restrict
sysctl net.ipv4.conf.all.rp_filter

Nie należy jednak bezmyślnie kopiować całych list sysctl z Internetu.

Każdy parametr powinien mieć powód.

Zmiana ustawienia kernela może poprawić bezpieczeństwo, ale może również zmienić zachowanie aplikacji lub sieci.

Dobry hardening to kontrolowana zmiana, nie kolekcjonowanie magicznych wartości.

Co z Dockerem?

Jeżeli serwer uruchamia kontenery, audyt wykonuję również na tej warstwie.

Na początek:

docker info

Potem:

docker ps --no-trunc

i dla konkretnego kontenera:

docker inspect <container>

Interesuje mnie przede wszystkim:

privileged
capabilities
user
security_opt
read_only
mounts
network
ports

To właśnie tutaj często wychodzą problemy, których nie widać podczas klasycznego audytu hosta.

Netbe ma już osobny materiał pokazujący, dlaczego kontener nie powinien być traktowany jak pełna piaskownica. (Netbe)

 

Najciekawszy etap: porównanie założeń z rzeczywistością

Po kilku godzinach audytu zwykle mam dwie listy.

Pierwsza:

Jak system powinien działać

Druga:

Jak system faktycznie działa

I właśnie różnica pomiędzy nimi jest najcenniejszym wynikiem audytu.

Przykład:

ZAŁOŻENIE
SSH tylko przez klucze

RZECZYWISTOŚĆ
PasswordAuthentication yes

Albo:

ZAŁOŻENIE
PostgreSQL tylko lokalnie

RZECZYWISTOŚĆ
0.0.0.0:5432

Albo:

ZAŁOŻENIE
AppArmor chroni Nginx

RZECZYWISTOŚĆ
profil nie jest załadowany

Albo:

ZAŁOŻENIE
automatyczne aktualizacje działają

RZECZYWISTOŚĆ
ostatnia instalacja aktualizacji była dawno temu

To są realne problemy.

Nie dlatego, że narzędzie wyświetliło czerwony komunikat.

Dlatego, że rzeczywisty stan systemu różni się od modelu bezpieczeństwa administratora.

Lynis jest początkiem, nie sędzią

Lynis jest bardzo przydatny właśnie dlatego, że potrafi szybko przejrzeć dużą liczbę elementów systemu. Na Netbe znajduje się osobny przewodnik pokazujący jego instalację, audyt i interpretację raportu. (Netbe)

Największym błędem byłoby jednak potraktowanie wyniku w rodzaju:

Hardening Index: 78

jako oceny bezpieczeństwa serwera.

Serwer z wynikiem 90 może mieć jeden fatalny błąd.

Serwer z wynikiem 75 może być w konkretnej roli skonfigurowany rozsądniej.

Narzędzie pomaga znaleźć pytania.

Administrator musi znaleźć odpowiedzi.

Jak wygląda mój końcowy raport?

Nie zapisuję:

Lynis: 82

To niewiele mówi.

Zapisuję raczej:

1. PostgreSQL nie powinien być dostępny z Internetu
   Priorytet: wysoki

2. SSH dopuszcza uwierzytelnianie hasłem
   Priorytet: średni

3. Nginx działa z profilem AppArmor
   Status: OK

4. Automatyczne aktualizacje bezpieczeństwa działają
   Status: OK

5. Kontener aplikacji działa jako root
   Priorytet: średni

6. Na hoście działa nieużywana usługa
   Priorytet: niski

Taki raport można potem zweryfikować.

Można przypisać właściciela.

Można ustalić termin.

Można wykonać ponowny audyt.

I przede wszystkim można zobaczyć, czy sytuacja rzeczywiście się poprawiła.

Hardening bez audytu zaczyna być rytuałem

Najbardziej niebezpieczny moment przy zabezpieczaniu serwera następuje wtedy, gdy administrator zaczyna wykonywać te same polecenia automatycznie.

Instaluje firewall.

Konfiguruje SSH.

Włącza AppArmor.

Instaluje Fail2Ban.

Uruchamia Lynis.

I uznaje, że skończył.

Tymczasem bezpieczeństwo nie jest listą odhaczonych funkcji.

To relacja pomiędzy:

zagrożeniem
     ↓
powierzchnią ataku
     ↓
mechanizmem ochronnym
     ↓
rzeczywistą konfiguracją
     ↓
monitoringiem
     ↓
reakcją

Jeżeli jeden z tych elementów nie działa, cały model może mieć słaby punkt.

Dlatego po zakończeniu hardeningu warto zadać sobie jedno, bardzo niewygodne pytanie:

„Skąd wiem, że to naprawdę działa?”

Jeżeli odpowiedzią jest „bo tak skonfigurowałem”, audyt jeszcze się nie skończył.

Jeżeli odpowiedzią jest konkretny stan usługi, reguła firewalla, log, wynik polecenia, test połączenia i ponowna weryfikacja — dopiero wtedy zaczynamy mówić o bezpieczeństwie, które można zmierzyć.

Materiały uzupełniające na Netbe.pl

Warto połączyć ten artykuł z istniejącym przewodnikiem hardeningu Linuxa, który obejmuje m.in. firewall, SSH, AppArmor/SELinux, szyfrowanie, monitoring, Lynis i izolację kontenerów. (Netbe)

Dobrym uzupełnieniem jest również wcześniejszy materiał „Audyt bezpieczeństwa systemu Linux — kompleksowy przewodnik”, obejmujący Lynis, aktualizacje, użytkowników, usługi, logi, rootkity i monitoring integralności. (Netbe)

 

Polecane wpisy
Botnety w Atakach DDoS: Jak botnety są tworzone i wykorzystywane do masowych ataków DDoS
Botnety w Atakach DDoS: Jak botnety są tworzone i wykorzystywane do masowych ataków DDoS

🤖 Botnety w Atakach DDoS: Jak botnety są tworzone i wykorzystywane do masowych ataków DDoS 📌 Wprowadzenie W erze rosnącej Czytaj dalej

🔐 Bezpieczne przechowywanie kodów zapasowych 2FA – co zrobić, gdy stracisz dostęp do swojego urządzenia?
🔐 Bezpieczne przechowywanie kodów zapasowych 2FA – co zrobić, gdy stracisz dostęp do swojego urządzenia?

🔐 Bezpieczne przechowywanie kodów zapasowych 2FA – co zrobić, gdy stracisz dostęp do swojego urządzenia? W erze cyfrowego zagrożenia i Czytaj dalej

Marek "Netbe" Lampart Inżynier informatyki Marek Lampart to doświadczony inżynier informatyki z ponad 25-letnim stażem w zawodzie. Specjalizuje się w systemach Windows i Linux, bezpieczeństwie IT, cyberbezpieczeństwie, administracji serwerami oraz diagnostyce i optymalizacji systemów. Na netbe.pl publikuje praktyczne poradniki, analizy i instrukcje krok po kroku, pomagając administratorom, specjalistom IT oraz zaawansowanym użytkownikom rozwiązywać realne problemy techniczne.