Debian 13 (nazwa kodowa Trixie) to jedna z najstabilniejszych i najczęściej wybieranych dystrybucji Linuksa do zastosowań serwerowych – zarówno na VPS-ach, dedykowanych maszynach, jak i w środowiskach domowych (home lab, self-hosting). Ten poradnik krok po kroku pokazuje, jak przygotować świeżo zainstalowany Debian 13 do pracy jako bezpieczny serwer produkcyjny: od pierwszej konfiguracji systemu, przez twarde zabezpieczenie SSH, skonfigurowanie zapory sieciowej (firewall), instalację Dockera, aż po ochronę przed atakami brute-force za pomocą Fail2ban.
Artykuł jest napisany w formie praktycznej, gotowej do wklejenia w terminal – każda komenda jest wyjaśniona, a na końcu znajdziesz sekcję FAQ z odpowiedziami na najczęstsze pytania dotyczące bezpieczeństwa serwera Debian.
Spis treści
- Dla kogo jest ten poradnik
- Wymagania wstępne
- Krok 1: Pierwsze logowanie i aktualizacja systemu
- Krok 2: Tworzenie użytkownika z uprawnieniami sudo
- Krok 3: Konfiguracja i zabezpieczenie SSH
- Krok 4: Konfiguracja firewalla (nftables / UFW)
- Krok 5: Instalacja i konfiguracja Fail2ban
- Krok 6: Instalacja Dockera i Docker Compose
- Krok 7: Dodatkowe utwardzanie systemu (hardening)
- Krok 8: Monitoring, logi i automatyczne aktualizacje
- Checklista końcowa
- Najczęstsze błędy
- FAQ – najczęściej zadawane pytania
- Podsumowanie
1. Dla kogo jest ten poradnik
Ten przewodnik jest przeznaczony dla:
- osób stawiających swój pierwszy serwer VPS (Hetzner, OVH, DigitalOcean, home lab),
- administratorów migrujących z Ubuntu lub CentOS na Debiana,
- osób, które chcą uruchomić Dockera na czystym Debianie 13 w bezpiecznej konfiguracji,
- każdego, kto chce zrozumieć dlaczego dana komenda jest potrzebna, a nie tylko ją skopiować.
Zakładam, że masz dostęp do świeżo zainstalowanego Debiana 13 (np. u dostawcy VPS) oraz konto root lub użytkownika z uprawnieniami administratora.
2. Wymagania wstępne
- Świeża instalacja Debian 13 (Trixie) – minimalna instalacja bez środowiska graficznego.
- Dostęp do serwera przez konsolę (np. panel VPS) na wypadek, gdyby coś poszło nie tak z SSH.
- Publiczny adres IP serwera.
- Podstawowa znajomość terminala Linux.
- Lokalny komputer z klientem SSH (Linux/macOS: wbudowany
ssh; Windows: PowerShell, PuTTY lub WSL).
Ważna zasada bezpieczeństwa: każdą zmianę w konfiguracji SSH testuj w nowej sesji terminala, nie zamykając starej. Dzięki temu, jeśli coś zablokuje dostęp, wciąż masz otwartą sesję, by to naprawić.
3. Krok 1: Pierwsze logowanie i aktualizacja systemu
Po zalogowaniu się jako root (lub przez sudo), zacznij od pełnej aktualizacji systemu:
apt update && apt full-upgrade -y

Zainstaluj podstawowe narzędzia, które przydadzą się w dalszych krokach:
apt install -y sudo curl wget gnupg2 ca-certificates lsb-release \
apt-transport-https software-properties-common vim htop \
unattended-upgrades net-tools

Ustaw poprawną strefę czasową i nazwę hosta:
timedatectl set-timezone Europe/Warsaw
hostnamectl set-hostname moj-serwer
Zrestartuj system, aby upewnić się, że nowe jądro (jeśli było aktualizowane) zostało załadowane:
reboot

4. Krok 2: Tworzenie użytkownika z uprawnieniami sudo
Praca na koncie root przez SSH to jedna z najczęstszych przyczyn skutecznych ataków. Utwórz osobnego użytkownika:
adduser nazwa_użytkownika
usermod -aG sudo nazwa_użytkownika


Sprawdź, czy użytkownik ma dostęp do sudo:
su - nazwa_użytkownika
sudo whoami
Polecenie powinno zwrócić root. Jeśli tak, przejdź do konfiguracji SSH.

5. Krok 3: Konfiguracja i zabezpieczenie SSH
To najważniejszy element ochrony serwera – większość ataków na świeże VPS-y to automatyczne skanowanie portu 22 i próby logowania hasłem.
3.1 Generowanie kluczy SSH (na komputerze lokalnym)
Na swoim komputerze, nie na serwerze, wygeneruj parę kluczy:
ssh-keygen -t ed25519 -C "moj-serwer-2026"

Skopiuj klucz publiczny na serwer:
ssh-copy-id nazwa_użytkownika@adres_ip_serwera
Jeśli ssh-copy-id nie jest dostępny (np. Windows bez WSL), skopiuj ręcznie zawartość ~/.ssh/id_ed25519.pub do pliku ~/.ssh/authorized_keys na serwerze.

3.2 Twarda konfiguracja demona SSH
Edytuj plik konfiguracyjny:
sudo nano /etc/ssh/sshd_config
Wprowadź (lub zmień) następujące wartości:
Port 2222 (zmiana portu z 22 na 2222)
PermitRootLogin no (zabrania logowania użytkownika root)
PasswordAuthentication no (jeśli nie ustawiałeś hasła przy tworzeniu klucza)
PubkeyAuthentication yes (zezwalasz na logowanie utworzonym kluczem publicznym)
MaxAuthTries 3 (liczba dozwolonych prób logowania)
AllowUsers nazwa_użytkownika (zezwalasz użytkownikowi dostęp do logowania przez ssh)
Przykład, uzupełnij resztę wartości

Wyjaśnienie kluczowych opcji:
| Opcja | Znaczenie |
|---|---|
Port 2222 | Zmiana domyślnego portu ogranicza liczbę automatycznych skanów (nie jest to zabezpieczenie samo w sobie, ale redukuje szum w logach) |
PermitRootLogin no | Blokuje bezpośrednie logowanie jako root |
PasswordAuthentication no | Wymusza logowanie wyłącznie kluczem SSH |
MaxAuthTries 3 | Ogranicza liczbę prób uwierzytelnienia w jednej sesji |
AllowUsers | Biała lista użytkowników mogących się łączyć |
Zrestartuj SSH:
sudo systemctl restart ssh
Nie zamykaj bieżącej sesji! Otwórz nowy terminal i przetestuj połączenie na nowym porcie:
ssh -p 2222 deployuser@adres_ip_serwera
Dopiero po potwierdzeniu, że logowanie działa, zamknij starą sesję.
6. Krok 4: Konfiguracja firewalla (nftables / UFW)
Debian 13 domyślnie korzysta z nftables jako następcy iptables. Dla wygody większość administratorów używa nakładki UFW (Uncomplicated Firewall), która pod spodem generuje reguły nftables/iptables.
4.1 Instalacja UFW
sudo apt install -y ufw

4.2 Podstawowe reguły
Ustaw domyślną politykę – blokuj wszystko przychodzące, zezwalaj na wychodzące:
sudo ufw default deny incoming
sudo ufw default allow outgoing

Zezwól na nowy port SSH (koniecznie przed włączeniem firewalla!):
sudo ufw allow 2222/tcp comment 'SSH'

Zezwól na ruch WWW, jeśli serwer będzie hostował strony/aplikacje:
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

Włącz firewall:
sudo ufw enable

Sprawdź status i aktywne reguły:
sudo ufw status verbose

4.3 Rate limiting dla SSH
UFW pozwala ograniczyć liczbę połączeń z jednego IP w krótkim czasie – to dodatkowa warstwa ochrony przed brute-force, niezależna od Fail2ban:
sudo ufw limit 2222/tcp
Wskazówka: jeśli wolisz pracować bezpośrednio na
nftables(np. w środowiskach produkcyjnych z bardziej złożoną topologią sieci), Debian 13 udostępnia gotowy pakietnftablesz plikiem konfiguracyjnym/etc/nftables.conf. UFW jest jednak wystarczające dla większości pojedynczych serwerów i VPS-ów.
7. Krok 5: Instalacja i konfiguracja Fail2ban
Fail2ban skanuje logi systemowe (np. logi SSH) i automatycznie blokuje adresy IP, które wielokrotnie próbują się nieudanie zalogować.
5.1 Instalacja
sudo apt install -y fail2ban

5.2 Konfiguracja lokalna
Nigdy nie edytuj plików .conf bezpośrednio – twórz kopie .local, które nadpisują ustawienia domyślne i przetrwają aktualizacje pakietu:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
W sekcji [sshd] ustaw (pamiętaj o nowym porcie SSH z kroku 3):
[sshd]
enabled = true
port = 2222
filter = sshd
banaction = ufw
maxretry = 4
findtime = 10m
bantime = 1h
bantime.increment = true
Wyjaśnienie parametrów:
maxretry– liczba nieudanych prób przed banem,findtime– okno czasowe, w którym liczone są próby,bantime– czas trwania bana,bantime.increment– każdy kolejny ban dla tego samego IP jest dłuższy (progresywne kary).
5.3 Uruchomienie i weryfikacja
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Aby ręcznie odbanować adres IP (np. własny, jeśli pomylisz hasło):
sudo fail2ban-client set sshd unbanip 203.0.113.5
8. Krok 6: Instalacja Dockera i Docker Compose
Debian 13 nie zawiera Dockera w domyślnych repozytoriach w wersji zalecanej do produkcji – najlepiej zainstalować go z oficjalnego repozytorium Dockera.
6.1 Dodanie oficjalnego repozytorium
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
6.2 Instalacja Dockera i wtyczki Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
6.3 Uruchomienie usługi i test
sudo systemctl enable --now docker
sudo docker run hello-world
6.4 Praca z Dockerem bez sudo
Dodaj swojego użytkownika do grupy docker:
sudo usermod -aG docker nazwa_użytkownika
Wyloguj się i zaloguj ponownie (lub uruchom newgrp docker), aby zmiana zadziałała. Sprawdź:
docker ps

6.5 Docker a firewall – ważna pułapka bezpieczeństwa
Uwaga: Docker domyślnie manipuluje regułami iptables/nftables bezpośrednio, co może omijać reguły UFW i nieumyślnie wystawić kontenery na cały internet, mimo że UFW pokazuje port jako zablokowany. To jeden z najczęściej pomijanych problemów przy stawianiu serwerów Docker + UFW.
Rozwiązanie – zainstaluj i skonfiguruj ufw-docker:
sudo wget -O /usr/local/bin/ufw-docker \
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install
sudo systemctl restart ufw

Od teraz, aby wystawić port kontenera na świat, musisz jawnie zezwolić na to w UFW:
sudo ufw-docker allow nazwa_kontenera 443/tcp
Krok 7: Dodatkowe utwardzanie systemu (hardening)
7.1 Wyłączenie nieużywanych usług
systemctl list-unit-files --type=service --state=enabled
Wyłącz wszystko, czego faktycznie nie używasz.

7.2 Konfiguracja automatycznego wylogowania nieaktywnych sesji
Dodaj do /etc/profile:
echo "export TMOUT=900" | sudo tee -a /etc/profile
7.3 Ograniczenie dostępu do su
sudo dpkg-statoverride --update --add root sudo 4750 /bin/su

7.4 Włączenie modułu bezpieczeństwa jądra (AppArmor)
Debian 13 domyślnie zawiera AppArmor. Sprawdź jego status:
sudo aa-status

10 Krok 8: Monitoring, logi i automatyczne aktualizacje
8.1 Automatyczne aktualizacje bezpieczeństwa
sudo dpkg-reconfigure -plow unattended-upgrades

Upewnij się, że w /etc/apt/apt.conf.d/50unattended-upgrades odkomentowane są linie dotyczące repozytorium -security.
8.2 Podstawowy monitoring logów
sudo apt install -y logwatch
sudo logwatch --detail high --range today --service sshd


8.3 Przegląd aktywnych połączeń sieciowych
sudo ss -tulpn

11. Checklista końcowa
- [ ] System zaktualizowany (
apt full-upgrade) - [ ] Utworzony użytkownik nie-root z
sudo - [ ] Logowanie SSH tylko kluczem,
PermitRootLogin no - [ ] Zmieniony domyślny port SSH
- [ ] Firewall UFW aktywny, domyślna polityka
deny incoming - [ ] Fail2ban działa i monitoruje SSH
- [ ] Docker zainstalowany,
ufw-dockerskonfigurowany - [ ] Automatyczne aktualizacje bezpieczeństwa włączone
- [ ] Kopia zapasowa konfiguracji (
/etc/ssh,/etc/ufw,/etc/fail2ban) wykonana
12. Najczęstsze błędy
- Zablokowanie się poza serwerem – restart SSH bez otwartej zapasowej sesji lub bez wcześniejszego dodania reguły firewalla dla nowego portu.
- Docker omijający UFW – wystawienie kontenerów na świat mimo pozornie zamkniętego firewalla (patrz sekcja 6.5).
- Fail2ban skonfigurowany dla starego portu SSH po jego zmianie.
- Brak automatycznych aktualizacji – serwer bez łatek bezpieczeństwa przez miesiące.
- Praca na koncie root zamiast dedykowanego użytkownika z
sudo.
13. FAQ – najczęściej zadawane pytania
Czy Debian 13 nadaje się do produkcji?
Tak. Debian jest znany z długoterminowej stabilności i konserwatywnego podejścia do aktualizacji pakietów, co czyni go popularnym wyborem dla serwerów produkcyjnych, w tym pod Dockera i Kubernetes.
Jaki jest domyślny firewall w Debianie 13?
System bazuje na nftables jako mechanizmie w jądrze, jednak nie ma domyślnie włączonej żadnej zapory – trzeba ją samodzielnie skonfigurować (np. przez UFW, jak w tym poradniku).
Czy zmiana portu SSH naprawdę zwiększa bezpieczeństwo?
Sama zmiana portu nie jest zabezpieczeniem kryptograficznym, ale znacząco redukuje liczbę automatycznych, masowych skanów i prób logowania, co ogranicza szum w logach i obciążenie systemu.
Czy Fail2ban zastępuje firewall?
Nie. Fail2ban reaguje na już wykryte próby ataku i tymczasowo blokuje adresy IP, natomiast firewall (UFW/nftables) kontroluje ruch sieciowy prewencyjnie, zanim dojdzie do próby logowania.
Dlaczego Docker „omija” reguły UFW?
Docker zarządza własnymi łańcuchami iptables/nftables niezależnie od UFW, dlatego porty publikowane przez kontenery (-p) mogą być dostępne z zewnątrz, nawet jeśli UFW ich formalnie nie zezwala. Rozwiązuje to narzędzie ufw-docker.
Czy trzeba wyłączać logowanie hasłem po dodaniu klucza SSH?
Zdecydowanie tak – klucz SSH bez wyłączenia PasswordAuthentication nadal pozostawia serwer podatny na ataki brute-force na hasła.
14. Podsumowanie
Bezpieczny serwer na Debianie 13 opiera się na kilku uzupełniających się warstwach ochrony: silnym uwierzytelnianiu SSH opartym o klucze, restrykcyjnym firewallu, automatycznym blokowaniu atakujących przez Fail2ban oraz świadomej konfiguracji Dockera, która nie omija zabezpieczeń systemowych. Żadna z tych warstw osobno nie daje pełnej ochrony – dopiero razem tworzą solidny fundament pod dalsze wdrożenia, czy to aplikacji webowych, kontenerów Docker, czy usług self-hosted.
Po wykonaniu wszystkich kroków z tego poradnika masz gotowy, produkcyjny fundament serwera Debian 13, na którym możesz bezpiecznie wdrażać kolejne usługi – od reverse proxy (Nginx/Traefik), przez bazy danych, po własne aplikacje w kontenerach Docker.

