<h3>1. Założenia dokumentu</h3>
Celem dokumentu jest zaprezentowanie schematycznych, typowych konfiguracji firewalla opartych o filtr pakietów <b>iptables</b> (filtrowanie stanowe - <i>stateful inspection</i>). Przedstawione przykłady obrazują najczęściej spotykane konfiguracje. Skrypty w swojej konstrukcji charakteryzują się prostotą i nie zawierają nadmiarowych rozwiązań. Pozwalają przez to na łatwe zrozumienie, rozbudowę i dodawanie bardziej złożonych funkcji.
Treści punktów 2 i 3 najcześciej występują w tym samym skrypcie (przy zachowanej kolejnośc). Tu zostały one rozdzielone dla zachowania większej czytelności.
<b>Uwaga</b> - dokument nie przedstawia szczegółowego procesu tworzenia firewalli. Należy zatem poszerzać wiedzę korzystając z dodatkowych materiałów poruszających ta tematykę.
<h3>2. Zmienne środowiskowe i moduły</h3>
Zmienne środowiskowe i moduły wykorzystywane są do ułatwienia pisania skrypu jak również zastosowania dostarczanych z systemem dodatkowych, gotowych rozwiązań ułatwiających implementację i poszerzających funkcjonalność firewalla.
<b>a. Zmienne środowiskowe</b>
W skrypcie odwołujemy sie do nich poprzez $ i nazwę zmiennej - <i>$zmienna</i>
Kod: Zaznacz cały
# ścieżka do pliku <i>iptables</i>
IPT=/usr/sbin/iptables
# ścieżka do pliku <i>modprobe</i>
MOD=/sbin/modprobe
# interfejs zewnętrzny, od strony Internetu - tylko router filtrujący
INT_PUB="eth0"
# interfejs wewnętrzny, od strony sieci LAN - tylko router filtrujący
INT_LAN="eth1"
# interfejs wewnętrzny, od strony strefy DMZ (zdemilitaryzowanej) - tylko router filtrujący
INT_DMZ="eth2"
# publiczny adres IP przypisany do zewnętrznego interfejsu - tylko router filtrujący
IP_PUB="XXX.YYY.VVV.ZZZ"
# adres IP sieci LAN - tylko router filtrujący
IP_LAN="192.168.0.0/24"
# adres IP strefy DMZ - tylko router filtrujący
IP_DMZ="192.168.1.0/24"
# adres IP serwera WWW w strefie DMZ - tylko router filtrujący
IP_DMZ_WWW="192.168.1.1/24"
# adres IP serwera SMTP w strefie DMZ - tylko router filtrujący
IP_DMZ_SMTP="192.168.1.2/24"
# adres IP serwera DNS w strefie DMZ - tylko router filtrujący
IP_DMZ_DNS="192.168.1.3/24"
Kod: Zaznacz cały
# ładowanie modułu ip_tables - wymagany, aby funkcjonował filtr pakietów
$MOD ip_tables
# ładowanie modułu ip_conntrack - śledzenie połączeń
$MOD ip_conntrack
# ładowanie modułu ip_conntrack_ftp - śledzenie połączeń ftp
$MOD ip_conntrack_ftp
# ładowanie modułu ip_conntrack_irc - śledzenie połączeń irc
$MOD ip_conntrack_irc
# ładowanie modułu iptable_nat - wymagany do funkcjonowania mechanizmu NAT
# (tylko router/firewall NATujący)
$MOD iptable_nat
# ładowanie modułu ip_nat_ftp - wsparcie dla FTP przy wykorzystaniu NAT
# (tylko router/firewall NATujący)
$MOD ip_nat_ftp
# ładowanie modułu ip_nat_irc - wsparcie dla IRC przy wykorzystaniu NAT
# (tylko router/firewall NATujący)
$MOD ip_nat_irc
# włączenie mechanizmu przeciwko atakom typu SYN-Flood (antiflood syn)
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# włączenie mechanizmu antyspoofingu - filtrowanie fałszywych adresów IP (antispoofing)
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
# włączenie forwardowania pakietów - tylko dla konfiguracji routera/bramy (dla stacji roboczej ustawiamy wartość 0)
echo 1 > /proc/sys/net/ipv4/ip_forward
<b>Uwaga !</b> - uwzględniony w skryptach mechanizm <b>unclean</b> nie funkcjonuje w jądrach z serii 2.6.x (tylko w serii 2.4.x). Więc jeśli korzystamy z serii 2.6.x to należy odpowiednie regułki usunąć lub zahaszować.
<b>a. Stacja robocza / host bastionowy</b>
Założenia:
- komputer podłączony bezpośrednio do Internetu lub do sieci LAN, posiadający jeden interfejs sieciowy,
- nie ma udostępnionych żadnych usług,
- nie pozwala na żadne połączenia przychodzące z zewnątrz, chyba, że są one odpowiedzią na własne już nawiązne lub są spokrewnione,
- maszyna zaufana, wypuszczamy caly ruch wychodzący
<b>REGUŁY</b>
Kod: Zaznacz cały
# ustawiamy domyślną politykę dla poszególnych łańcuchów
# domyślnie połączenia przychodzące odrzucamy
$IPT -P INPUT DROP
# domyślnie wypuszczamy wszystko z naszego hosta
$IPT -P OUTPUT ACCEPT
# nic nie przekazujemy, więc blokujemy
$IPT -P FORWARD DROP
# czyścimy istniejące reguły w łańcuchach
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
# interfejs lokalny traktujemy jako uprzywilejowany
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# odrzucamy przychodzące niepoprawne pakiety - mogą być formą ataku
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A INPUT -m unclean -j DROP
$IPT -A OUTPUT -m unclean -j DROP
# wpuszczamy tylko nawiązane i spokrewnione połączenia (dla poszczególnych protokołów)
$IPT -A INPUT -p all -j ACCEPT -m state --state ESTABLISHED,RELATED
# odrzucamy przychodzące zapytania o IDENT i SOCKS z odpowiedzią port nieosiągalny
# (aby uniknąć opóźnień w trakcie łączenia z serwerami IRC i FTP)
$IPT -A INPUT -p tcp --dport 113 -j REJECT --reject-with icmp-port-unreachable
$IPT -A INPUT -p tcp --dport 1080 -j REJECT --reject-with icmp-port-unreachable
# pozostały ruch przychodzący logujemy
$IPT -A INPUT -j LOG
# pozostały ruch przychodzący odrzucamy, gdyż nie udostępniamy żadnych usług
$IPT -A INPUT -j DROP
Założenia:
- komputer podłączony bezpośrednio do Internetu lub do sieci LAN, posiadający jeden interfejs sieciowy,
- ma udostępnione wybrane usługi dla wybranych adresów IP,
- pozwala na wybrane połączenia przychodzące z zewnątrz, i odpowiedzi na własne już nawiązne lub spokrewnione połączenia,
- maszyna zaufana, wypuszczamy caly ruch wychodzący
<b>REGUŁY</b>
Kod: Zaznacz cały
# ustawiamy domyślną politykę dla poszególnych łańcuchów
# domyślnie połączenia przychodzące odrzucamy
$IPT -P INPUT DROP
# domyślnie wypuszczamy wszystko z naszego hosta
$IPT -P OUTPUT ACCEPT
# nic nie przekazujemy, więc blokujemy
$IPT -P FORWARD DROP
# czyścimy istniejące reguły w łańcuchach
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
# interfejs lokalny traktujemy jako uprzywilejowany
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# odrzucamy przychodzące niepoprawne pakiety - mogą być formą ataku
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A INPUT -m unclean -j DROP
$IPT -A OUTPUT -m unclean -j DROP
# wpuszczamy tylko nawiązane i spokrewnione połączenia (dla poszczególnych protokołów)
$IPT -A INPUT -p all -j ACCEPT -m state --state ESTABLISHED,RELATED
# odrzucamy przychodzące zapytania o IDENT i SOCKS z odpowiedzią port nieosiągalny
# (aby uniknąć opóźnień w trakcie łączenia z serwerami IRC i FTP)
$IPT -A INPUT -p tcp --dport 113 -j REJECT --reject-with icmp-port-unreachable
$IPT -A INPUT -p tcp --dport 1080 -j REJECT --reject-with icmp-port-unreachable
# wpuszczamy przychodzące połączenia na port 10000 (wykorzystany np. przez programy P2P)
$IPT -A INPUT -p tcp --dport 10000 -j ACCEPT -m state --state NEW
# wpuszczamy przychodzące połączenia DCC (program PSI)
$IPT -A INPUT -p tcp --dport 8010 -j ACCEPT -m state --state NEW
# wpuszczamy przychodzące połączenia SSH z wybranego adresu IP (AAA.BBB.CCC.DDD)
$IPT -A INPUT -p tcp -s AAA.BBB.CCC.DDD --dport 22 -j ACCEPT -m state --state NEW
# wpuszczamy przychodzące połączenia do gry STARCRAFT (Battle.NET)
$IPT -A INPUT -p udp --dport 6112:6119 -j ACCEPT -m state --state NEW
$IPT -A INPUT -p tcp --dport 6112:6119 -j ACCEPT -m state --state NEW
# pozostały ruch przychodzący logujemy
$IPT -A INPUT -j LOG
# pozostały ruch przychodzący odrzucamy, gdyż nie udostępniamy żadnych usług
$IPT -A INPUT -j DROP
Założenia:
- osobny komputer z dwoma interfejsami sieciowymi (Internetu i sieć LAN),
- nie ma udostępnionych żadnych usług,
- nie pozwala na żadne połączenia przychodzące z zewnątrz, chyba, że są one odpowiedzią na własne (w tym połączenia przekazywane z sieci LAN) już nawiązne lub są spokrewnione,
- maszyna zaufana, tj. sieć LAN, wypuszczamy i przekazujemy caly ruch wychodzący do Internetu
- firewall wykonuje translację adresów - źródłowy NAT (SNAT dla stałego adresu publicznego) lub maskaradę (MASQUERADE dla dynamicznego adresu publicznego), gdyż dostępny jest tylko 1 adres publiczny za którym należy ukryć sieć lokalną. NALEŻY wybrać jedno z rozwiązań i odhaszować/zahaszować odpowiednią linię w skrypcie.
<b>REGUŁY</b>
Kod: Zaznacz cały
# ustawiamy domyślną politykę dla poszególnych łańcuchów
# domyślnie połączenia przychodzące odrzucamy
$IPT -P INPUT DROP
# domyślnie wypuszczamy wszystko z naszego firewalla
$IPT -P OUTPUT ACCEPT
# domyslnie blokujemy przekazywanie pakietów
$IPT -P FORWARD DROP
# czyścimy istniejące reguły w łańcuchach
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
# czyścimy tablicę NAT
$IPT -F -t nat
# interfejs lokalny traktujemy jako uprzywilejowany
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A FORWARD -o lo -j ACCEPT
# odrzucamy przychodzące na obydwa interfejsy sieciowe niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A INPUT -m unclean -j DROP
# odrzucamy wychodzące z interfejsów sieciowych niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A OUTPUT -m unclean -j DROP
# odrzucamy przekazywane niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A FORWARD -m unclean -j DROP
# wpuszczamy na obydwa interfejsy tylko nawiązane i spokrewnione połączenia (dla poszczególnych protokołów)
$IPT -A INPUT -p all -j ACCEPT -m state --state ESTABLISHED,RELATED
# odrzucamy przychodzące na interfejsy zapytania o IDENT i SOCKS z odpowiedzią port nieosiągalny
# gdyż nie mamy takich usług (aby uniknąć opóźnień w trakcie łączenia z serwerami IRC i FTP)
$IPT -A INPUT -p tcp --dport 113 -j REJECT --reject-with icmp-port-unreachable
$IPT -A INPUT -p tcp --dport 1080 -j REJECT --reject-with icmp-port-unreachable
# pozwalamy na połączenia z firewallem z zaufanej sieci LAN
$IPT -A INPUT -i $INT_LAN -p all -j ACCEPT -m state --state NEW
# pozostały ruch przychodzący na interfejs zewnętrzny logujemy
$IPT -A INPUT -i $INT_PUB -j LOG
# pozostały ruch przychodzący na interfejs zewnętrzny odrzucamy, gdyż nie udostępniamy żadnych usług
$IPT -A INPUT -i $INT_PUB -j DROP
# pozwalamy na wpuszczanie/przekazywanie z zewnątrz do sieci tylko połączeń wcześniej nawiązanych z LAN lub spokrewnionych
# dla wszystkich protokołów
$IPT -A FORWARD -i $INT_PUB -o $INT_LAN -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
# wypuszczanie (przekazywanie) połączeń z sieci LAN do Internetu
$IPT -A FORWARD -i $INT_LAN -o $INT_PUB -p all -j ACCEPT
# logujemy pozostały ruch przekazywany
$IPT -A FORWARD -j LOG
# odrzucamy pozostały ruch przekazywany
$IPT -A FORWARD -j DROP
# wykonujemy translację adresów NAT (SNAT) dla całej sieci - dla statycznego IP publicznego
$IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_LAN -j SNAT --to $IP_PUB
# wykonujemy translację adresów NAT (MASQUERADE) dla całej sieci - dla dynamicznego IP publicznego
# $IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_LAN -j MASQUERADE
Założenia:
- osobny komputer z trzema interfejsami sieciowymi (Internet, sieć LAN, strefa DMZ),
- nie ma udostępnionych żadnych usług,
- domyślnie nie pozwala na żadne połączenia przychodzące z zewnątrz, oprócz odpowiedzi na własne połączenia już nawiązne lub spokrewnione (w tym połączenia przekazywane z sieci LAN i strefy DMZ),
- firewall przekierowuje przychodzące z Internetu i LAN połączenia WWW, SMTP, DNS do odpowiednich serwerów w strefie DMZ,
- maszyna zaufana, tj. sieć LAN i strefa DMZ: wypuszczamy i przekazujemy caly ruch wychodzący do Internetu
- firewall pozwala na ograniczoną komunikację LAN-DMZ (tylko WWW, SMTP, DNS)
- firewall wykonuje translację adresów - źródłowy NAT (SNAT dla stałego adresu publicznego) lub maskaradę (MASQUERADE dla dynamicznego adresu publicznego), gdyż dostępny jest tylko 1 adres publiczny za którym należy ukryć sieć LAN i strefę DMZ. NALEŻY wybrać jedno z rozwiązań i odhaszować/zahaszować odpowiednią linię w skrypcie.
<b>REGUŁY</b>
Kod: Zaznacz cały
# ustawiamy domyślną politykę dla poszególnych łańcuchów
# domyślnie połączenia przychodzące odrzucamy
$IPT -P INPUT DROP
# domyślnie wypuszczamy wszystko z naszego firewalla
$IPT -P OUTPUT ACCEPT
# domyslnie blokujemy przekazywanie pakietów
$IPT -P FORWARD DROP
# czyścimy istniejące reguły w łańcuchach
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
# czyścimy tablicę NAT
$IPT -F -t nat
# interfejs lokalny traktujemy jako uprzywilejowany
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A FORWARD -o lo -j ACCEPT
# odrzucamy przychodzące na interfejsy sieciowe niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A INPUT -m unclean -j DROP
# odrzucamy wychodzące z interfejsów sieciowych niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A OUTPUT -m unclean -j DROP
# odrzucamy przekazywane niepoprawne pakiety
# dla jąder 2.6.x - usunąć lub zahaszować
$IPT -A FORWARD -m unclean -j DROP
# wpuszczamy na interfejsy tylko nawiązane i spokrewnione połączenia (dla poszczególnych protokołów)
$IPT -A INPUT -p all-j ACCEPT -m state --state ESTABLISHED,RELATED
# odrzucamy przychodzące na interfejsy zapytania o IDENT i SOCKS z odpowiedzią port nieosiągalny
# gdyż nie mamy takich usług (aby uniknąć opóźnień w trakcie łączenia z serwerami IRC i FTP)
$IPT -A INPUT -p tcp --dport 113 -j REJECT --reject-with icmp-port-unreachable
$IPT -A INPUT -p tcp --dport 1080 -j REJECT --reject-with icmp-port-unreachable
# pozwalamy na połączenia z firewallem z zaufanej sieci LAN
$IPT -A INPUT -i $INT_LAN -p all -j ACCEPT -m state --state NEW
# pozwalamy na połączenia z firewallem z zaufanej strefy DMZ
$IPT -A INPUT -i $INT_DMZ -p all -j ACCEPT -m state --state NEW
# pozostały ruch przychodzący na interfejs zewnętrzny logujemy
$IPT -A INPUT -i $INT_PUB -j LOG
# pozostały ruch przychodzący na interfejs zewnętrzny odrzucamy, gdyż nie udostępniamy żadnych usług
$IPT -A INPUT -i $INT_PUB -j DROP
# wpuszczanie (przekazywanie) z Internetu do LAN tylko połączeń wcześniej nawiązanych z LAN lub spokrewnionych
# dla wszystkich protokołów
$IPT -A FORWARD -p all -i $INT_PUB -o $INT_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
# wypuszczanie (przekazywanie) połączeń z sieci LAN do Internetu
$IPT -A FORWARD -p all -i $INT_LAN -o $INT_PUB -j ACCEPT
# wpuszczanie (przekazywanie) z Internetu do DMZ tylko połączeń wcześniej nawiązanych z DMZ lub spokrewnionych
# dla wszystkich protokołów
$IPT -A FORWARD -p all -i $INT_PUB -o $INT_DMZ -m state --state ESTABLISHED,RELATED -j ACCEPT
# wypuszczanie (przekazywanie) połączeń ze strefy DMZ do Internetu
$IPT -A FORWARD -p all -i $INT_DMZ -o $INT_PUB -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń WWW z Internetu do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_PUB -o $INT_DMZ --dport 80 --syn -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń SMTP z Internetu do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_PUB -o $INT_DMZ --dport 25 --syn -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń DNS z Internetu do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_PUB -o $INT_DMZ --dport 53 --syn -j ACCEPT
$IPT -A FORWARD -p udp -i $INT_PUB -o $INT_DMZ --dport 53 -j ACCEPT
# wpuszczanie (przekazywanie) z DMZ do sieci LAN tylko połączeń wcześniej nawiązanych z sieci LAN lub spokrewnionych
# dla protokołu TCP
$IPT -A FORWARD -p all -i $INT_DMZ -o $INT_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń WWW z sieci LAN do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_LAN -o $INT_DMZ --dport 80 --syn -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń SMTP z sieci LAN do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_LAN -o $INT_DMZ --dport 25 --syn -j ACCEPT
# wpuszczanie (przekazywanie) nowych połączeń DNS z sieci LAN do serwera WWW w strefie DMZ
$IPT -A FORWARD -p tcp -i $INT_LAN -o $INT_DMZ --dport 53 --syn -j ACCEPT
$IPT -A FORWARD -p udp -i $INT_LAN -o $INT_DMZ --dport 53 -j ACCEPT
# logujemy pozostały ruch przekazywany
$IPT -A FORWARD -j LOG
# odrzucamy pozostały ruch przekazywany
$IPT -A FORWARD -j DROP
# przekierowanie zapytań WWW z Internetu do serwera WWW w strefie DMZ
$IPT -t nat -A PREROUTING -i $INT_PUB --dport 80 -p tcp -j DNAT --to-destination $IP_DMZ_WWW
# przekierowanie zapytań SMTP z Internetu do serwera SMTP w strefie DMZ
$IPT -t nat -A PREROUTING -i $INT_PUB --dport 25 -p tcp -j DNAT --to-destination $IP_DMZ_SMTP
# przekierowanie zapytań DNS z Internetu do serwera DNS w strefie DMZ
$IPT -t nat -A PREROUTING -i $INT_PUB --dport 53 -p tcp -j DNAT --to-destination $IP_DMZ_DNS
# wykonujemy translację adresów NAT (SNAT) dla całej sieci LAN - dla statycznego IP publicznego
$IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_LAN -j SNAT --to $IP_PUB
# wykonujemy translację adresów NAT (MASQUERADE) dla całej sieci - dla dynamicznego IP publicznego
# $IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_LAN -j MASQUERADE
# wykonujemy translację adresów NAT (SNAT) dla całej strefy DMZ - dla statycznego IP publicznego
$IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_DMZ -j SNAT --to $IP_PUB
# wykonujemy translację adresów NAT (MASQUERADE) dla całej sieci - dla dynamicznego IP publicznego
# $IPT -t nat -A POSTROUTING -o $INT_PUB -s $IP_DMZ -j MASQUERADE
<b>a. Listowanie reguł</b>
Komenda:
<i># iptables -v --line-numbers --list -n</i>
wyświetla załadowane reguły dla łańcuchów INPUT, OUTPUT, FORWARD, w ładnie sformatowanej postaci numerycznej wraz z licznikiem przesłanych pakietów i numerami linii.
Natomiast komenda:
<i># iptables -v --line-numbers --list -n -t nat</i>
wyświetla załadowane reguły dla łańcuchów PREROUTING, POSTROUTING, OUTPUT
<b>b. Listowanie połączeń</b>
Komenda:
<i># cat /proc/net/ip_conntrack</i>
wyświetla tablicę aktualnie śledzonych połączeń.
<h3>Posłowie</h3>
Powyższa treść opiera się na doświadczeniu oraz wiedzy autora zdobytej przez studiowanie m.in. następujących materiałów:
- Paweł Krawczyk - "Filtrowanie stateful-inspection w Linuksie i BSD"
- Jacek Artymiak - "Building Firewalls with OpenBSD and PF" (2nd ed.)
- Strony dotyczące tematyki filtrowania pakietów przy pomocy IPTABLES - (<a href="http://forum.slackware.pl/viewtopic.php ... DSYŁACZ</a>)
- inne...
<b>Autor:</b> Skyscraper
<b>Uwagi:</b> Snaj, Hannibal