Firewall iptables i UFW kontrolują, które połączenia serwer WWW akceptuje, a które blokuję - określa to powierzchnię ataku i awarie. W tym praktycznym artykule pokazuję jasne reguły, bezpieczne wartości domyślne i przetestowane polecenia dla SSH, HTTP(S), baz danych, logowania, IPv6 i Dockera - bezpośrednio stosowane na hostach produktywnych.
Punkty centralne
Poniższe kluczowe punkty dają mi szybką orientację przed rozpoczęciem konfiguracji.
- Restrykcyjne Start: Domyślna odmowa dla połączeń przychodzących, w szczególności otwartych
- SSH Zezwól najpierw: Nie ryzykuj dostępu
- UFW jako interfejs: prosta składnia, iptables w tle
- Rejestrowanie aktywować: Sprawdź zasady, rozpoznaj ataki
- Wytrwałość zapewnić: Utrzymanie zasad dotyczących ponownego uruchamiania
Podstawy: iptables i UFW w skrócie
Polegam na iptablesgdy potrzebuję szczegółowej kontroli nad pakietami, łańcuchami i dopasowaniami. Używam UFW, gdy chcę szybko zastosować niezawodne reguły, które kończą się wewnętrznie jako reguły iptables [1]. Pozwala mi to łączyć proste polecenia z możliwościami linuksowego netfiltra bez zagubienia się w szczegółach. W przypadku serwerów internetowych oznacza to: buduję czysty filtr przed Apache, Nginx lub Node, aby docierał tylko pożądany ruch [2]. Taka separacja zmniejsza powierzchnię ataku i pozwala atakom częściej kończyć się niepowodzeniem.
Oba narzędzia wzajemnie się uzupełniają, a ja decyduję, które z nich pasuje do danej sytuacji. UFW wyróżnia się czytelnością, zwłaszcza na Ubuntu i Debianie [3]. iptables daje mi rozszerzone opcje, na przykład dla NAT, określonych interfejsów i złożonych dopasowań. Ważne: dokumentuję moje reguły zwięźle, aby późniejsza konserwacja była łatwa. Jeśli chcesz dowiedzieć się więcej o koncepcji bezpieczeństwa, możesz znaleźć jasne wprowadzenie tutaj: Zapora sieciowa jako tarcza ochronna.
Konfiguracja początkowa: bezpieczne ustawianie domyślnych zasad
Zaczynam od Domyślne-Zasady: Blokuj przychodzące, zezwalaj na wychodzące. W ten sposób zapobiegam przypadkowemu udostępnianiu nowych usług. Zawsze zezwalam na pętlę zwrotną, aby wewnętrzne procesy działały stabilnie. Akceptuję istniejące połączenia, aby uniknąć ich anulowania. Ta sekwencja minimalizuje błędy podczas aktywacji zapory [2][5].
Używam UFW do ustawienia bazy za pomocą kilku poleceń. Następnie szczegółowo sprawdzam stan, aby natychmiast zauważyć błędy wpisywania. W przypadku szczególnie wrażliwych hostów ograniczam również porty wychodzące. Zmniejsza to ryzyko wycieku danych, jeśli usługa została naruszona. Często używam następujących poleceń:
# UFW: Reguły domyślne
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Alternatywna bardziej rygorystyczna polityka wychodząca
sudo ufw default deny outgoing
sudo ufw allow out 53
sudo ufw allow out 80
sudo ufw allow out 443
# Sprawdź status
sudo ufw status verbose
Filtrowanie stanowe: stany i sekwencja
Czysty przepływ paczek wzrasta i spada wraz z Conntrack stwierdza. Najpierw akceptuję nawiązane połączenia, wcześnie odrzucam nieprawidłowe pakiety i pozostawiam otwartą pętlę zwrotną. Zmniejsza to obciążenie i zapobiega efektom ubocznym spowodowanym późnymi spadkami. Dla iptables, celowo ustawiam kolejność:
# iptables: solidna podstawa
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Zawsze zezwalaj na pętlę zwrotną
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Zezwalaj na istniejące/powiązane połączenia
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Wczesne odrzucanie nieprawidłowych pakietów
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
W przypadku UFW, ESTABLISHED/RELATED są już brane pod uwagę wewnętrznie. Zwracam również uwagę na to, czy wolę DROP (cichy) lub ODRZUĆ (aktywne, szybsze przełączanie awaryjne). Dla sieci wewnętrznych preferuję REJECT, w sieci publicznej zazwyczaj DROP.
Podstawowe zasady dla serwerów internetowych: SSH, HTTP i HTTPS
Przełączam SSH najpierw, w przeciwnym razie łatwo się zablokuję. Następnie zezwalam na HTTP i HTTPS, aby serwer WWW był dostępny. Ustawiam tylko te porty, których naprawdę potrzebuję. Później opcjonalnie dodaję ograniczenie szybkości lub Fail2ban, aby ograniczyć brutalne próby logowania. Każdą zmianę sprawdzam natychmiast za pomocą poleceń status lub list.
Polecenia są proste. UFW oferuje mówiące aliasy dla portów internetowych, co zwiększa czytelność. Dzięki iptables mogę ustawić dokładne porty i protokoły. Następnie zapisuję reguły iptables, aby przetrwały restart. Oto minimalne kroki:
# SSH
sudo ufw allow 22
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# HTTP/HTTPS
sudo ufw allow http
sudo ufw allow https
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Bezpieczne SSH: Ograniczaj i otwieraj selektywnie
Oprócz uwolnienia, tłumię ataki za pomocą Ograniczenie prędkości lub białych list. UFW zapewnia prostą ochronę:
# Ograniczenie szybkości SSH (UFW)
sudo ufw limit 22/tcp komentarz "Ograniczenie szybkości SSH"
Ustawiam dokładniejsze limity za pomocą iptables. Zapobiega to masowemu zgadywaniu haseł bez wykluczania legalnych administratorów:
# SSH: Limit prób połączeń na źródło
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --name SSH --update --seconds 60 --hitcount 10 -j DROP
Tam, gdzie to możliwe, zezwalam na SSH tylko z Adresy IP administratorów i pracować z kluczami SSH. Zmiana portów nie zastąpi bezpieczeństwa, ale może zmniejszyć hałas. Dokumentuję wyjątki i regularnie je sprawdzam.
Zabezpieczanie baz danych i ograniczanie źródeł IP
Nigdy nie otwieram portów bazy danych globalnie, ale tylko lokalny lub dla zdefiniowanych źródłowych adresów IP. Uniemożliwia to skanerom znalezienie otwartych portów MySQL, PostgreSQL lub MongoDB. Dla aplikacji lokalnych, 127.0.0.1 jest wystarczające jako cel; kontroluję zewnętrzny dostęp administratora ściśle poprzez IP. Krótko dokumentuję zmiany, na przykład w wiki serwera. Oszczędza mi to czas podczas audytów.
Często używam poniższych przykładów w projektach. Sprawdzam poprawność każdego dozwolonego adresu IP z wyprzedzeniem. UFW pozwala na czystą notację "od-do", iptables implementuje tę samą logikę technicznie. Używam dodatkowych reguł zezwalających dla tymczasowych okien konserwacyjnych i usuwam je później. Dzięki temu interfejs jest niewielki:
# Tylko lokalnie: MySQL
sudo ufw allow from 127.0.0.1 to any port 3306
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT
# Zezwól na pojedynczy adres IP
sudo ufw allow from 203.0.113.10
iptables -A INPUT -s 203.0.113.10 -j ACCEPT
# Zezwól na port dla określonego adresu IP
sudo ufw allow from 10.1.2.3 to any port 4444
iptables -A INPUT -p tcp -s 10.1.2.3 --dport 4444 -j ACCEPT
# Blokuj znanych atakujących
sudo ufw deny from 192.0.2.24
iptables -A INPUT -s 192.0.2.24 -j DROP
Czysta obsługa logowania, interfejsów i IPv6
Przełączam Rejestrowanie do weryfikacji reguł i rozpoznawania widocznego ruchu. Poziom "on" w UFW jest wystarczający dla większości hostów, wyższych poziomów używam tylko wybiórczo. Analizuję logi za pomocą journalctl, fail2ban lub narzędzi SIEM. Pozwala mi to rozpoznać wzorce ze skanowania lub prób brute force. W przypadku anomalii szybko dostosowuję reguły [2].
Często wiążę zasady z konkretnymi Interfejstakich jak eth0 w sieciach publicznych. Zapobiega to niepotrzebnemu wpływowi na sieci wewnętrzne. UFW może "zezwolić na eth0 do dowolnego portu 80", iptables używa -i dla interfejsów wejściowych. Dla IPv6, sprawdzam aktywację w /etc/default/ufw dla "IPV6=yes" i używam ip6tables dla natywnych reguł [2]. Ta separacja pozwala uniknąć luk w hostach z dwoma stosami.
ICMP i ICMPv6: Dostępność bez luk
Pozostawiam niezbędne ICMP-typy, aby działało wykrywanie MTU ścieżki, limity czasu i diagnostyka. ICMP nie jest wrogiem, ale rdzeniem protokołu IP. Ograniczam tylko nadmierne echa.
# IPv4: Ogranicz echo, zezwalaj na ważne typy ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/sekundę --limit-burst 20 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
# UFW: ogólnie zezwalaj na ICMP (możliwe dostrojenie w before.rules)
sudo ufw allow in proto icmp
Na stronie IPv6 ICMPv6 jest absolutnie niezbędny (wykrywanie sąsiadów, reklama routera). Zezwalam na podstawowe typy i ograniczam żądania echa:
# IPv6 (ip6tables)
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -m limit --limit 5/sekundę --limit-burst 20 -j ACCEPT
Prawidłowe stosowanie ograniczeń wychodzących i NAT/maskarady
Ograniczam ruch wychodzący, gdy Profil ryzyka i zgodność. Zezwalam na DNS i HTTPS i blokuję wszystko inne z wyjątkiem zdefiniowanych celów. Zmniejsza to ilość eksfiltrowanych danych w przypadku przejęcia usługi. Tworzę zdefiniowane wyjątki dla aplikacji, które wymagają aktualizacji lub interfejsów API. Jasno dokumentuję te wyjątki i regularnie je sprawdzam.
Do konfiguracji routingu używam NAT/Masquerading przez UFW-Before-Rules lub raw z iptables. Zwracam uwagę na kolejność łańcuchów, aby pakiety były przepisywane poprawnie. Po wprowadzeniu zmian testuję łączność i opóźnienia. W przypadku systemów produkcyjnych planuję okno konserwacji i tworzę kopię zapasową konfiguracji. Pozwala mi to zachować możliwość śledzenia ścieżek sieciowych [7].
Szczegóły wychodzące: usługi i protokoły systemowe
Dzięki ścisłej polityce dotyczącej połączeń wychodzących zezwalam w szczególności na DNS (53/udp), HTTPS (443/tcp) i w razie potrzeby NTP (Dla serwerów pocztowych dodaję 25/tcp i 587/tcp. Nie rozwiązuję wyjątków opartych na domenie na poziomie pakietu, ale za pośrednictwem serwerów proxy lub logiki aplikacji.
# UFW: typowe usługi systemowe
sudo ufw allow out 123/udp # NTP
sudo ufw allow out 25/tcp # SMTP - tylko jeśli serwer pocztowy
sudo ufw allow out 587/tcp # Submission - tylko w razie potrzeby
# iptables: konkretne zezwolenie
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT
Docker i zapory sieciowe: unikanie pułapek
Docker ustawia swój własny iptables-reguł, które mogą wpływać na moją politykę. Dlatego sprawdzam łańcuchy NAT i FORWARD po każdym uruchomieniu kompilacji lub demona. Celowo uwalniam odsłonięte porty i unikam "-p 0.0.0.0:PORT". Zamiast tego wiążę je z adresem IP zarządzania lub odwrotnym proxy. Dzięki temu wektor ataku jest mniejszy i bardziej widoczny [1].
Utrzymuję aktywne zapory sieciowe hosta pomimo Dockera. Kontroluję również grupy zabezpieczeń na poziomie infrastruktury, jeśli są dostępne. W przypadku konfliktów między UFW i Dockerem używam udokumentowanych obejść lub ustawiam reguły w DOCKER-USER. Ważne jest, aby mieć jasne obowiązki: host zawsze blokuje, kontenery otwierają się tylko jawnie. Taka kolejność zapobiega nieświadomym zwolnieniom.
# DOCKER-USER: wymusza globalną politykę hosta przed regułami Dockera
iptables -N DOCKER-USER 2>/dev/null || true
iptables -I DOCKER-USER -s 192.0.2.24 -j DROP
iptables -A DOCKER-USER -j RETURN
Precyzyjne ustawienia UFW: Sekwencja, profile i ruch kierowany
Gdy liczy się precyzja, używam "wkładka", "ponumerowane" i profile aplikacji. W ten sposób utrzymuję sekwencję reguł w czystości i używam przetestowanych definicji usług.
Sekwencja kontroli #
sudo ufw insert 1 deny in from 198.51.100.0/24
# Widok numerowany i ukierunkowane usuwanie
sudo ufw status numbered
sudo ufw delete 3
# Profile aplikacji (np. Nginx Full)
sudo ufw app list
sudo ufw app info "Nginx Full"
sudo ufw allow "Nginx Full"
# Domyślne blokowanie ruchu routowanego (przekazywanie)
sudo ufw default deny routed
Bardziej złożone wyjątki przechowuję w before.rules Odpowiednio after.rules. Tam mogę precyzyjnie umieścić dostrajanie ICMP lub NAT bez utraty czytelności standardowych reguł.
Trwałe reguły: Zapisywanie i przywracanie
Zasady UFW są następujące trwały i automatycznie przetrwać restarty. To znacznie upraszcza administrację na hostach Debian/Ubuntu. W iptables zapisuję reguły po zmianach i przywracam je przy starcie. Używam do tego iptables-save/restore lub netfilter-persistent. Bez tych kroków tracę zmiany po ponownym uruchomieniu [5].
Systematycznie testuję trwałość: planuję restart, a następnie sprawdzam status. Jeśli liczniki i łańcuchy są poprawne, konfiguracja jest solidna. Jeśli brakuje reguł, poprawiam ścieżkę ładowania w kontekście init lub systemd. Ta procedura zapobiega niespodziankom podczas konserwacji. Dokumentacja i kopia zapasowa plików reguł uzupełniają procedurę.
# Debian/Ubuntu: Trwałość dla iptables
sudo apt-get install -y iptables-persistent
sudo netfilter-persistent save
# Ręczna kopia zapasowa
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
Przywracanie # (jeśli wymagane)
sudo iptables-restore < /etc/iptables/rules.v4
sudo ip6tables-restore < /etc/iptables/rules.v6
Wydajność i ochrona: limity, zestawy i dostrajanie jądra
Gdy obciążenie jest wysokie, zmniejszam liczbę kontrolek i używam ukierunkowanych Limity stawek. W przypadku dużych list bloków pracuję z ipset, aby skrócić czas wyszukiwania. Używam również systemowych mechanizmów ochrony:
# Contain SYN flood (jądro)
sudo sysctl -w net.ipv4.tcp_syncookies=1
# Ograniczenie szybkości połączeń HTTP na źródłowy adres IP (przykład)
iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW
-m hashlimit --hashlimit-name http_rate --hashlimit-above 50/second
--hashlimit-burst 100 --hashlimit-mode srcip -j DROP
Utrzymuję rozmiar Tabela Conntrack w skrócie. Jeśli jest wiele jednoczesnych połączeń, zwiększam nf_conntrack_max, ale wcześniej testuję efekty.
Zarządzanie, testy i zapobieganie błędom
Odchodzę SSH zanim aktywuję "odmowę przychodzącą". Następnie testuję z drugiej sesji, czy dostęp pozostaje stabilny. Sprawdzam każdą nową regułę za pomocą "ufw status verbose" lub "iptables -L -v". Pozwala mi to rozpoznać liczniki trafień i sprawdzić, czy pakiety lądują w oczekiwanym łańcuchu. Wykonuję kopię zapasową plików firewalla przed wprowadzeniem jakichkolwiek większych zmian.
Aby zapewnić kompleksowe bezpieczeństwo, łączę zaporę sieciową z krokami wzmacniającymi system. Obejmują one bezpieczne ustawienia SSH, zarządzanie poprawkami i minimalne usługi. Lubię używać praktycznego przewodnika jako listy kontrolnej: Uodparnianie serwerów dla systemu Linux. Regularnie powtarzam te kontrole i przestrzegam ustalonych okien konserwacyjnych. Dzięki temu moje serwery są w niezawodnej formie.
Zaawansowane testy i obserwacja
Sprawdzam wpływ zewnętrzny za pomocą Skanowanie portów z sieci zewnętrznej i zweryfikować otwarte gniazda wewnętrznie. Na początku dokładnie monitoruję logi, aby wcześnie rozpoznać fałszywe wnioski.
Gniazda otwarte #
ss -lntup
# Przegląd iptables compact
sudo iptables -S
sudo iptables -L -v -n
# UFW: szczegółowy status i dzienniki
sudo ufw status verbose
journalctl -k | grep -i ufw
# Kontrola zewnętrzna (z innego hosta/sieci)
nmap -Pn -p 22,80,443
W przypadku zmian wysokiego ryzyka planuję Poziom awaryjny włączony. Pracuję w Screen/Tmux i, jeśli to konieczne, ustawiam kontrolowany czasowo reset, jeśli się zablokuję. Po udanym teście ponownie anuluję akcję awaryjną.
# Przykład: automatyczna dezaktywacja jako kotwica awaryjna (używaj ostrożnie)
echo "ufw disable" | at now + 2 minutes
# Usuń ponownie po udanym teście: atrm
Porównanie dostawców usług hostingowych: Koncentracja na integracji zapory sieciowej
Jeśli chodzi o hosting, polegam na Bezpieczeństwo blisko platformy. Dostosowane zasady, szybkie wdrażanie reguł i dobre monitorowanie opłacają się. W bieżących porównaniach webhoster.de imponuje zgrabnie zintegrowanymi opcjami zapory ogniowej i szybkim wsparciem. Ci, którzy preferują konfiguracje panelowe, korzystają z jasnych instrukcji dotyczących Zapora sieciowa Plesk. Poniższa tabela kategoryzuje kluczowe kryteria.
| Dostawca | Integracja z zaporą sieciową | Wydajność | Wsparcie | Umieszczenie |
|---|---|---|---|---|
| webhoster.de | indywidualna konfiguracja. | Bardzo wysoka | top | 1 |
| Dostawca B | Standard | wysoki | dobry | 2 |
| Dostawca C | Standard | dobry | Zadowalający | 3 |
Praktyczne przykłady: Od testu do reguły produkcyjnej
Rozpoczynam każdy zestaw reguł w Ekran lub w drugiej sesji SSH. W ten sposób nadal mogę się uratować w przypadku błędu operacyjnego. Dopiero gdy host testowy działa poprawnie, stosuję reguły w środowisku produkcyjnym. Reguły ścieżki powrotu i plan wycofania zapewniają mi dodatkowe bezpieczeństwo. Na koniec zwięźle dokumentuję zmiany w dzienniku zmian.
Używam powtarzających się bloków konstrukcyjnych dla serwerów internetowych: zezwalam na SSH, zwalniam HTTP/S, wiążę porty wewnętrzne lokalnie, loguję się, ograniczam ICMP, blokuję zbędne protokoły. Następnie dbam o reguły mirroringu IPv6, aby nie pozostały żadne luki. Zawsze sprawdzam łańcuchy Docker osobno, ponieważ ustawiają one własne ścieżki. Na koniec weryfikuję dostęp poprzez zewnętrzne kontrole i monitorowanie. Dzięki temu interfejs jest czysty i identyfikowalny [1][2].
Podsumowanie dla administratorów
Z wyraźnym Zasady i kilka poleceń, niezawodnie zabezpieczam serwery internetowe. Domyślna odmowa przychodząca, najpierw SSH, zwolnienie HTTP/S - to stanowi stabilną podstawę. Porty baz danych tylko lokalnie lub przez białą listę, logowanie aktywne, obserwowanie IPv6, sprawdzanie łańcuchów dockera. Trwałe przechowywanie i regularne testy zapobiegają przykrym niespodziankom. Ta rutyna zapewnia dostępność usług i znacznie zmniejsza ryzyko.
Niezależnie od tego, czy używam bezpośrednio UFW, czy iptables, kluczowa jest jasna, ekonomiczna polityka. Krótko dokumentuję, regularnie weryfikuję i ograniczam wyjątki do minimum. Ograniczenie połączeń wychodzących zatrzymuje niepotrzebne połączenia i ogranicza szkody w przypadku naruszenia bezpieczeństwa. Dzięki praktycznemu spojrzeniu na logi, szybciej rozpoznaję anomalie i odpowiednio reaguję. Dzięki temu serwer WWW jest odporny, a powierzchnia ataku niewielka.


