Dealownia
Menu
sprawdzono – jak sprawdzamy oferty

Zabezpieczenie VPS: SSH, ufw, fail2ban – lista kontrolna

Zabezpieczenie VPS na Ubuntu 24.04: logowanie kluczem SSH, zapora ufw, fail2ban, automatyczne aktualizacje, Docker a zapora i comiesięczny przegląd.

Bezpieczeństwo i kopiezaktualizowano 6 min czytania

Redakcja serwisu Dealownia · ceny i fakty ze stron dostawców, jak sprawdzamy

Po przejściu tej listy Twój VPS przyjmuje logowanie tylko kluczem, ma zamknięte wszystkie porty poza SSH i WWW, banuje adresy zgadujące hasła, sam instaluje poprawki bezpieczeństwa, a Ty raz w miesiącu w kwadrans sprawdzasz, czy wszystko nadal tak wygląda. Nic z tego nie kosztuje – wszystkie narzędzia są w repozytorium Ubuntu.

Czego potrzebujesz

  • VPS z Ubuntu 24.04 LTS (wskazówki dla Debiana 12 i 13 są tam, gdzie coś działa inaczej). Wielkość serwera nie ma tu znaczenia: wszystko działa na najmniejszym planie z 1 vCPU, 1 GB RAM i 10 GB dysku.
  • Użytkownika z sudo i działający klucz SSH. Jeśli jeszcze go nie masz, zacznij od poradnika od zera.
  • Dostęp do konsoli w panelu dostawcy – to Twoje wyjście awaryjne, gdy zablokujesz sobie SSH.

Krok 1. SSH: tylko klucze, bez roota

Zawsze trzymaj otwartą jedną sesję SSH, a zmiany testuj w drugim oknie. Ustawienia dopisz w osobnym pliku:

bash
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowUsers deploy
MaxAuthTries 3
EOF
sudo sshd -t && sudo systemctl restart ssh
sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|allowusers|maxauthtries)'
  • Nazwa 00- ma znaczenie: sshd bierze pierwszą znalezioną wartość, a obrazy chmurowe często mają 50-cloud-init.conf z PasswordAuthentication yes.
  • AllowUsers wpuszcza tylko wymienione konta (wpisz tu nazwę swojego użytkownika) – nawet jeśli ktoś doda klucz innemu użytkownikowi, nie zaloguje się.
  • sshd -t sprawdza składnię; z błędem w pliku restart mógłby zostawić Cię bez SSH.

Zmiana portu SSH zmniejsza szum w logach, ale nie jest zabezpieczeniem. Jeśli ją robisz na Ubuntu 24.04, pamiętaj, że SSH startuje przez gniazdo systemd (ssh.socket): po zmianie Port wykonaj sudo systemctl daemon-reload && sudo systemctl restart ssh.socket i najpierw otwórz nowy port w ufw.

Krok 2. Zapora ufw

bash
sudo apt -y install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status verbose

limit zamiast allow przy SSH: według dokumentacji ufw odrzuca połączenia z adresu, który próbuje nawiązać 6 lub więcej połączeń w ciągu 30 sekund. Regułę SSH dodajesz przed enable, bo inaczej zapora odetnie bieżącą sesję. Do usuwania reguł służy sudo ufw status numbered i sudo ufw delete NUMER.

Krok 3. Docker a zapora

Ten punkt łatwo przeoczyć: według dokumentacji Dockera porty kontenerów opublikowane przez -p lub ports: omijają reguły ufw. Kontener z "5432:5432" wystawia bazę na cały internet, choć ufw status tego nie pokazuje. Zasada: publikuj porty tylko na pętli zwrotnej i wystawiaj usługi przez nginx z HTTPS.

yaml
    ports:
      - "127.0.0.1:3000:3000"

Sprawdzenie, co naprawdę nasłuchuje na publicznych adresach:

bash
sudo ss -tulpn | grep -v '127\.0\.0\.\|\[::1\]'

Na liście powinny zostać tylko SSH (22) i nginx (80, 443). Filtr ukrywa adresy z całej sieci 127.0.0.x, w tym 127.0.0.53 i 127.0.0.54 (lokalny resolver DNS na Ubuntu). Może zostać jeszcze wpis UDP klienta DHCP (port 68), a zależnie od obrazu także klienta synchronizacji czasu – to programy, przez które serwer sam pobiera adres i czas, a nie usługi do zamknięcia. Bazy danych w Dockerze nie potrzebują publikowania portu wcale – kontenery z jednego pliku compose widzą się po nazwach usług.

Krok 4. fail2ban

bash
sudo apt -y install fail2ban
sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true

[sshd]
enabled = true
EOF
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Nie edytuj jail.conf – plik ostrzega, że aktualizacja pakietu może go nadpisać; własne ustawienia trzymaj w jail.local albo w jail.d/. bantime.increment wydłuża ban dla adresów, które wracają. Przy logowaniu wyłącznie kluczem fail2ban nie jest pierwszą linią obrony, ale ucina szum i chroni usługi z hasłem, np. strony za auth_basic w nginx (jail nginx-http-auth).

Na Debianie 12 i 13 domyślnie nie ma pliku /var/log/auth.log (logi są tylko w journald), więc w sekcji [sshd] dopisz backend = systemd. Na Ubuntu 24.04 plik istnieje i ustawienie domyślne działa.

Krok 5. Automatyczne aktualizacje bezpieczeństwa

Na Ubuntu Server pakiet unattended-upgrades jest zainstalowany i według dokumentacji Ubuntu instaluje poprawki bezpieczeństwa od razu po instalacji systemu. Sprawdź, czy tak jest u Ciebie:

bash
cat /etc/apt/apt.conf.d/20auto-upgrades
sudo unattended-upgrade -v --dry-run

Oba klucze, APT::Periodic::Update-Package-Lists i APT::Periodic::Unattended-Upgrade, powinny mieć wartość "1" (codziennie). Jeśli pliku nie ma (np. na minimalnym obrazie albo Debianie):

bash
sudo apt -y install unattended-upgrades
sudo dpkg-reconfigure -f noninteractive unattended-upgrades

Część poprawek (jądro, biblioteka C) działa dopiero po restarcie. Możesz pozwolić na automatyczny restart nocą – w /etc/apt/apt.conf.d/50unattended-upgrades ustaw:

bash
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Domyślnie restart jest wyłączony. Jeśli go włączasz, upewnij się, że kontenery mają restart: unless-stopped, a monitor zewnętrzny powie Ci, gdyby serwer nie wstał. Logi aktualizacji są w /var/log/unattended-upgrades/.

Krok 6. Co sprawdzać co miesiąc

bash
sudo ufw status verbose
sudo ss -tulpn
sudo fail2ban-client status sshd
last -n 20
cat ~/.ssh/authorized_keys
getent group sudo docker
apt list --upgradable
ls /var/run/reboot-required 2>/dev/null && echo "Potrzebny restart"
df -h /
sudo certbot certificates
docker ps --format '{{.Names}}\t{{.Ports}}'

Na co patrzysz:

  • Porty: tylko 22, 80, 443 na publicznych adresach; w docker ps wszystkie porty z 127.0.0.1.
  • Logowania (last): tylko Twoje konto i znane adresy.
  • Klucze i grupy: żadnych obcych kluczy w authorized_keys, w grupach sudo i docker tylko Ty (grupa docker daje w praktyce uprawnienia roota).
  • Aktualizacje i restart: pusta lista pakietów albo tylko świeże; brak zaległego restartu.
  • Dysk: poniżej 80%. Pełny dysk zatrzymuje bazy i logi.
  • Certyfikaty: ważne dłużej niż 30 dni; jeśli mniej, odnowienie nie działa.
  • Kopia zapasowa: raz w miesiącu odtwórz ją na próbę. Kopia, której nigdy nie odtworzyłeś, jest niesprawdzona.

Większość tych punktów da się sprawdzać automatycznie – skrypt jest w poradniku o monitoringu; ręcznie przeglądaj klucze, użytkowników i porty.

Najczęstsze problemy

  • Odcięty SSH po włączeniu ufw. Reguła dla SSH nie została dodana albo SSH działa na innym porcie. Wejdź konsolą z panelu dostawcy i wykonaj sudo ufw allow OpenSSH (albo numer portu), potem sudo ufw reload.
  • Hasło nadal działa mimo PasswordAuthentication no. Inny plik w sshd_config.d jest czytany wcześniej. sudo sshd -T | grep passwordauthentication pokaże wartość, która naprawdę obowiązuje.
  • fail2ban-client status sshd zwraca błąd, a jail nie startuje. Brak pliku logu (Debian bez rsyslog) – dopisz backend = systemd. Błędy konfiguracji pokaże sudo fail2ban-client -t.
  • Zbanowałeś sam siebie. Z konsoli dostawcy: sudo fail2ban-client set sshd unbanip TWÓJ_ADRES. Stały adres domowy lub biurowy możesz dopisać do ignoreip w [DEFAULT].
  • Baza danych z Dockera widoczna z internetu. Port opublikowany bez 127.0.0.1. Popraw ports: i wykonaj docker compose up -d.

Co dalej

Zabezpieczony serwer jest gotowy na narzędzia: stack z analityką i monitoringiem albo osobno Uptime Kuma. Jeśli rozważasz darmowy VPS, przeczytaj najpierw o haczykach darmowych planów i zajrzyj na listę darmowych planów. Płatne plany porównasz w rankingu VPS.

Powiązane poradniki