Podstawy Bezpieczeństwa Serwera: zanim otworzysz drzwi, sprawdź zamek

Od chwili, gdy stał się 'moim serwerem’, wszystko jest moją odpowiedzialnością

Ostatnio przebiłem się przez ścianę linuksowego CLI i uprawnień (Permission). chmod, chown, a nawet to, czego nigdy nie wolno robić — chmod 777. Kontrolę dostępu do pojedynczego pliku miałem już jako tako opanowaną.

Ale wtedy byłem w wielkim błędzie. Myślałem, że wystarczy dobrze zarządzać 'uprawnieniami plików’, a serwer będzie bezpieczny.

„Bezpieczeństwo serwera? To chyba robota dla zespołu security?”

W dużej firmie — być może. Ale ja jestem jednoosobowym deweloperem. Administrator serwera, specjalista od bezpieczeństwa, inżynier sieciowy — wszystkim byłem 'ja’. Cała odpowiedzialność za bezpieczeństwo spoczywała na moich barkach.

A uświadomił mi to log logowań do serwera, który znalazłem pewnego poniedziałkowego poranka.

Uprawnienia plików (chmod) to tylko zamek w szufladzie wewnątrz pokoju. Drzwi wejściowe do całego budynku trzeba zabezpieczać osobno.

Kryzys: ktoś pukał do drzwi mojego serwera

W poniedziałek rano, jak zwykle z przyzwyczajenia zalogowałem się na serwer po SSH i sprawdzając logi, zauważyłem coś dziwnego.

# Sprawdzenie ostatnich nieudanych prób logowania SSH
$ grep "Failed password" /var/log/auth.log | tail -20

Gdy zobaczyłem log na ekranie, dostałem gęsiej skórki.

Feb 10 03:14:22 sshd: Failed password for root from 185.220.xx.xx
Feb 10 03:14:25 sshd: Failed password for root from 185.220.xx.xx
Feb 10 03:14:27 sshd: Failed password for admin from 185.220.xx.xx
Feb 10 03:14:30 sshd: Failed password for ubuntu from 185.220.xx.xx
...

Setki prób logowania od 3 nad ranem. IP zagraniczne. Nazwy kont przełączały się między root, admin, ubuntu. To ktoś puszczał 'zautomatyzowany program (bota)’ i atakował hasła metodą brute force.

„Ej, ale jeszcze mnie nie zhakowali, prawda…?”

Na szczęście nie udało im się włamać. Ale czy można stać przed włamywaczem, który próbuje na drzwiach jeden klucz po drugim, i powiedzieć „nie wszedł, więc jest w porządku”? Od razu zabrałem się za przegląd stanu bezpieczeństwa serwera.

Serwer z publicznym IP przez całą dobę jest atakowany automatycznie z całego świata. Mój serwer nie jest wyjątkiem.

Etap 1: zamknąć drzwi wejściowe — hardening SSH

Drzwi wejściowe do serwera to SSH (Secure Shell). Dokładnie te, których sam używam do łączenia się. Problem w tym, że haker chce wejść tymi samymi drzwiami. Od tego trzeba zacząć — wzmocnić te drzwi.

Zmiana portu SSH (domyślnie 22 → inny numer)

Domyślny port SSH to 22. Automatyczne skanery hakerów najpierw pukają właśnie na 22. Samo zmienienie numeru portu odfiltrowuje ponad 90% ataków brute force.

# Otwarcie pliku konfiguracyjnego SSH
$ sudo vi /etc/ssh/sshd_config

# Zmiana numeru portu (domyślnie 22 → np.: 2222)
Port 2222

# Restart usługi SSH
$ sudo systemctl restart sshd

Analogicznie: złodziej zwykle celuje w główne drzwi na parterze (22). Jeśli przeniesiesz wejście na drzwi na dach trzeciego piętra (2222), większość złodziei w ogóle nie znajdzie, gdzie są drzwi.

Blokada bezpośredniego logowania konta root

Z logów widać, że pierwszym kontem atakowanym przez hakerów jest 'root’. root to najwyższe konto administratora w Linuksie — jeśli je złamią, przejmują cały serwer.

# W pliku konfiguracyjnym SSH blokujemy bezpośrednie logowanie jako root
$ sudo vi /etc/ssh/sshd_config

PermitRootLogin no

Teraz zalogowanie się po SSH jako root jest niemożliwe. Logujesz się zwykłym kontem, a gdy trzeba, podnosisz uprawnienia przez sudo.

Uwierzytelnianie kluczem SSH zamiast hasła

Nawet jeśli hasło jest bardzo skomplikowane, automatyczny program próbujący dziesiątki tysięcy kombinacji kiedyś je złamie. Najpewniejszym rozwiązaniem jest wyłączenie logowania hasłem i zezwolenie na dostęp wyłącznie 'kluczem SSH (Key)’.

# Wygenerowanie pary kluczy SSH na własnym komputerze (lokalnie)
$ ssh-keygen -t rsa -b 4096

# Skopiowanie klucza publicznego na serwer
$ ssh-copy-id -p 2222 user@my-server-ip

# Wyłączenie logowania hasłem na serwerze
$ sudo vi /etc/ssh/sshd_config
PasswordAuthentication no

Uwierzytelnianie kluczem SSH to nie 'klucz’, tylko 'odczyt linii papilarnych’. Hasło (klucz) da się skopiować, ale klucz prywatny (odcisk palca) znajdujący się tylko na moim komputerze jest w praktyce nie do powielenia.


Etap 2: postawić ogrodzenie — Firewall

Skoro wzmocniliśmy drzwi (SSH), czas ogrodzić cały budynek i kontrolować, kto wchodzi. To właśnie 'Firewall’.

Na serwerze jest łącznie 65 535 portów (wejść). Bez firewalla to tak, jakby wszystkie te 60 tysięcy drzwi stało otworem. Trzeba otworzyć tylko te, których się potrzebuje, a resztę pozamykać.

Najprostszym narzędziem firewalla w Linuksie jest 'UFW (Uncomplicated Firewall)’.

# Aktywacja UFW
$ sudo ufw enable

# Domyślna polityka: blokuj cały ruch przychodzący, zezwalaj wychodzącemu
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing

# Otwarcie tylko potrzebnych portów
$ sudo ufw allow 2222/tcp   # SSH (zmieniony port)
$ sudo ufw allow 80/tcp     # HTTP
$ sudo ufw allow 443/tcp    # HTTPS

# Sprawdzenie aktualnego stanu firewalla
$ sudo ufw status
Port Przeznaczenie Otwarty?
2222 SSH (zmieniony port) ✅ Zezwolony
80 HTTP (web) ✅ Zezwolony
443 HTTPS (bezpieczny web) ✅ Zezwolony
22 SSH (domyślny, już nieużywany) ❌ Zablokowany
Pozostałe Wszystkie ❌ Zablokowane

Z 60 tysięcy drzwi zostały otwarte dokładnie 3, a resztę zamurowałem cegłą. Zniknęły same drzwi, w które mógłby pukać złodziej.

Zasada firewalla jest prosta: 'zamknij wszystko, otwórz tylko to, co potrzebne’.

Etap 3: szyfrowanie komunikacji — HTTPS

Jeśli serwer udostępnia usługę webową, trzeba chronić także komunikację między użytkownikiem a serwerem. To jest 'HTTPS’.

HTTP wysyła dane jak 'pocztówkę’. Każdy po drodze może zajrzeć w treść. HTTPS wysyła dane w 'zaklejonej kopercie’. Nawet jeśli ktoś je przechwyci, nie odczyta zawartości.

Co, jeśli login i hasło, które użytkownik wpisał w formularzu, lecą przez HTTP? Ktoś, kto korzysta z tego samego Wi-Fi w kawiarni, zobaczy całą treść jak na dłoni.

W praktyce najprostszym sposobem na wdrożenie HTTPS jest wystawienie darmowego certyfikatu SSL przez 'Let’s Encrypt’.

# Instalacja Certbota (narzędzia automatyzującego Let's Encrypt)
$ sudo apt install certbot python3-certbot-nginx

# Wystawienie certyfikatu i automatyczne wdrożenie w Nginx
$ sudo certbot --nginx -d mydomain.com

# Test automatycznego odnawiania (certyfikat trzeba odnawiać co 90 dni)
$ sudo certbot renew --dry-run

Kilka linijek poleceń i adres mojej usługi zmienia się z http:// na https://, a w pasku przeglądarki pojawia się ikonka kłódki. Dajemy użytkownikowi zaufanie: „ta strona jest bezpieczna”.


Etap 4: automatyczny system obrony — Fail2Ban

Nawet po zmianie portu SSH i ustawieniu uwierzytelniania kluczem, na świecie są uparte boty. Zawsze znajdzie się taki, który odnajdzie zmieniony port i spróbuje się dobić.

W takich sytuacjach przydaje się 'Fail2Ban’. To narzędzie, które automatycznie blokuje IP po określonej liczbie nieudanych prób logowania.

# Instalacja Fail2Ban
$ sudo apt install fail2ban

# Konfiguracja ochrony SSH
$ sudo vi /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
maxretry = 5
bantime = 3600
findtime = 600
Ustawienie Znaczenie
maxretry = 5 Po 5 błędnych próbach
bantime = 3600 Blokuj ten IP przez 1 godzinę
findtime = 600 Reguła działa, gdy 5 porażek wystąpi w 10 minut
# Uruchomienie Fail2Ban
$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban

# Podejrzenie aktualnie zablokowanych IP
$ sudo fail2ban-client status sshd

Fail2Ban to 'kamera CCTV + automatyczny rygiel’ ustawione przed drzwiami. Jeśli podejrzany typ kilka razy poda złe hasło, wejście zostaje automatycznie zablokowane.

Bezpieczeństwo serwera to nie jedna warstwa, lecz układanie wielu warstw zabezpieczeń.

Praktyczna rada: checklista bezpieczeństwa

Całą naszą dotychczasową konfigurację zamieniam w checklistę. Za każdym razem, gdy stawiasz nowy serwer, przejście przez tę listę daje ci podstawową warstwę ochrony.

# Pozycja Polecenie/Konfiguracja
1 Zmiana portu SSH Port 2222 in sshd_config
2 Blokada logowania root PermitRootLogin no
3 Przejście na uwierzytelnianie kluczem SSH PasswordAuthentication no
4 Włączenie firewalla ufw enable, zezwól tylko na potrzebne porty
5 Wdrożenie HTTPS Let’s Encrypt + Certbot
6 Instalacja Fail2Ban Automatyczna blokada IP po nieudanych logowaniach
7 Regularne aktualizacje sudo apt update && sudo apt upgrade

Pozycja 7 jest zaskakująco ważna. Luki w zabezpieczeniach są odkrywane codziennie. Nawet najlepszy firewall nic nie da, jeśli sam system operacyjny albo oprogramowanie ma dziury. Regularna aktualizacja to najprostszy, a zarazem najskuteczniejszy środek bezpieczeństwa.


Na koniec: bezpieczeństwo nie jest czymś wyjątkowym — to nawyk

Na początku słowo „bezpieczeństwo” brzmiało dla mnie górnolotnie. Obrona przed hakerami, wykrywanie włamań, szyfrowanie… Myślałem, że to tematy rodem z filmów.

W praktyce okazało się, że wcale nie trzeba zaawansowanej technologii. Zmienić port SSH, włączyć firewall, ustawić uwierzytelnianie kluczem, zainstalować Fail2Ban. Wszystko załatwiało się kilkoma linijkami poleceń. Ważne było nie 'wiedzieć’, ale 'zrobić’.

Incydenty bezpieczeństwa nie biorą się z wyrafinowanych technik hakerskich, tylko z serwerów, na których nie wdrożono podstawowych zabezpieczeń.

Od tamtego dnia, zawsze gdy stawiam nowy serwer, zanim wgram jakikolwiek kod, najpierw obowiązkowo przechodzę przez tę checklistę bezpieczeństwa. Najpierw sprawdzić zamek, potem otworzyć drzwi — to najbardziej podstawowa postawa dbania o serwer.

Do tej pory budowaliśmy podstawową wydolność (CLI, uprawnienia, bezpieczeństwo) potrzebną do przetrwania w linuksowej dżungli. Ale pozostał jeszcze jeden fundamentalny problem. Środowisko mojego laptopa (Windows) i serwera Linux to dwa różne światy. Wersja Javy inna, biblioteki inne.

Istnieje technologia, która raz na zawsze kończy wymówkę „U mnie działa”. Następnym razem porozmawiamy o 'wirtualizacji i kontenerach’, które całkowicie niwelują różnice w środowisku.

Dodaj komentarz