artykuły
Powrót do listy artykułów

Temat artykułu: Firewall cz.2 - techniki zaawansowane
Tekst napisał pitt2k dnia 08-01-2003

W artykule tym chciałbym przedstawić zaawansowane techniki tworzenia firewalli przy użyciu linuxowego IPTABLES.

PART I - trochę teorii


W poprzednim artykule o firewallu zostały opisane trzy podstawowe łańcuchy reguł: INPUT, FORWARD, OUTPUT. Przy budowie prostej ściany ogniowej w zupełnościone wystarczą. Jednak jeśli chcemy zbudować solidną zaporę musimy przeanalizować całą drogę przez którą przechodzi pakiet dokładniej.



Pakiet przychodzi z lewej strony. Po zweryfikowaniu sumy kontrolnej IP pakiet wpada do łańcucha NF_IP_PRE_ROUTING (w skrocie PREROUTING).
Następnie zostaje określona trasa routingu dla pakietu tzn. zapada decyzja, czy pakiet jest skierowany do procesu lokalnego czy może musi być przesłany (routowany) gdzie indziej.
Jeżeli pakiet jest pakietem o adresie docelowym mówiącym, że ma trafić do procesu lokalnego (działającego na maszynie z firewallem) jest on przesyłany do łańcucha NF_IP_LOCAL_IN (w skrócie INPUT). Jeżeli jednak pakiet ma trafić do innej maszyny musi zostać przesłany poprzez łańcuch NF_IP_FORWARD (w skrócie FORWARD).
Łańcuch NF_IP_LOCAL_OUT jest wykorzystywany dla pakietów generowanych lokalnie i wysyłanych na inne maszyny w sieci.
Kiedy pakiet wychodzi z firewalla musi przejść przez jeszcze jeden łańcuch zwany NF_IP_POST_ROUTING (w skrócie POSTROUTING). Pakiety przechodzące przez łańcuchy FORWARD i OUTPUT przechodzą przez ten ostatni łańcuch !!!

Mamy do wyboru kilka wariantów co może się stać z pakietem wędrującym przez naszego firewalla.

Operator Opis
ACCEPT kontynuuje podróż pakietu
DROP odrzuca pakiet (pakiet nie kontynuuje swojej drogi)
STOLEN pakiet zostaje przechwycony
QUEUE kolejkuje pakiet (zazwyczaj w przestrzeni użytkownika)
REPEAT pakiet przechodzi cały łańcuch od początku



Zasadniczo możemy robić z naszymi pakietami trzy rzeczy:
  1. Filtrowanie pakietów
    Tabela 'filter' nigdy nie zmienia pakietów, tylko je filtruje. Wykorzystujemy do tego celu 3 łańcuchy: INPUT, FORWARD i OUTPUT.

  2. NAT (Network Address Translation)
    Tabela 'nat' wykorzystuje trzy łańcuchy: PREROUTING, POSTROUTING dla translacji źródłowej i docelowej. A dla translacji docelowej dla pakietów lokalnych łańcuch OUTPUT.
    W tabeli tej tylko pierwszy pakiet przechodzi przez łańcuchy, a następne są przepuszczane oczywiście pod warunkiem, że są pakietami z tego samego połączenia.
    Tabela NAT jest używana do źródłowego NAT (SNAT), docelowego NAT (DNAT), maskarady (MASQUERADING) oraz tzw. 'transparent proxying' (specjalna wersja DNAT).

  3. Zmiana pakietów
    Można użyć tabeli 'mangle' do zmiany zawartosci pakietów, a w szczegolności bitów TOS.


PART II - filtrowanie pakietów


Podsumujmy:
Pakiety przychodzące z sieci i mające trafić do lokalnego komputera przechodzą przez łańcuch INPUT.
Pakiety które mają trafić do innej sieci lub komputera muszą być routowane, więc przechodzą przez łańcuch FORWARD.
Pakiety wychodzące z lokalnego komputera muszą przejść przez łańcuch OUTPUT.

Podstawowe operatory:

Operator Opis
-A (append rule) dodaje nową regułkę do łańcucha
-I (insert rule) wstawia nową regułkę do łańcucha
-D (delete rule) usuwa regułkę z łańcucha
-R (replace rule) zamienia regułkę w łańcuchu
-L (list rule) wyświetla regułki z łańcucha


Podstawowe przełączniki:

Przełącznik Opis
-p (protocol) protokół (tcp/udp/icmp/...)
-s (source address) adres źródłowy
-d (destination address) adres docelowy
-i (incoming interface) urządzenie z którego pochodzi pakiet
-o (outgoing interface) urządzenie do którego pakiet zmierza


Poniżej przedstawiam kilka dodatków, którymi możemy łatwo opisać pakiety,które chcemy wyłapać:

Dodatek Opis
TCP wyłapujemy pakiet po porcie źródłowym lub docelowym oraz flagach TCP
UDP wyłapujemy pakiet po porcie źródłowym lub docelowym
ICMP wyłapujemy pakiet po typie komunikatu ICMP
MAC wyłapujemy pakiet po adresie MAC karty sieciowej
MARK wyłapujemy pakiet po 'nfmark'
OWNER wyłapujemy pakiet po identyfikatorze użytkownika, grupy, procesu lub sesji (tylko dla lokalnych pakietów)
LIMIT wyłapujemy po ilości pakietów w czasie. Przydatne do wyśledzenia ataku typu 'flood'
STATE wyłapujemy pakiety po stanie w którym się znajdują
Wyróżniamy następujące stany:
  • INVALID
  • ESTABLISHED
  • NEW
  • RELATED
pakiet błędny
pakiet należy do osiagniętego połączenia
pakiet tworzący nowe połączenie
pakiet należący do połączenia np. pakiet ICMP typu 'error message'


Rozszerzenia docelowe przy filtrowaniu:

Rozszerzenie Opis
LOG tworzy loga za pomocą syslog()
ULOG tworzy loga za pomocą demona w przestrzeni użytkownika (bardziej elastyczne)
REJECT nie tylko wyrzuca pakiet, ale także wysyła wiadomość z błędem do nadawcy pakietu
MIRROR retransmituje pakiet po sprawdzeniu źródła i miejsca docelowego dla pakietu


PART III - NAT (Network Address Translation)


Poprzednie wersje kernela oferowały specjalny przypadek NAT a mianowicie maskarade (MASQUERADING). W tej wersji mamy do czynienia z innymi rodzajami NAT.
NAT dzieli się na źródłowy (source NAT - SNAT) oraz docelowy (destination NAT - DNAT).
SNAT zmienia źródłowy adres pakietu kiedy pakiet przechodzi przez łańcuch POSTROUTING. Maskarada jest specjalną wersją SNAT.
Z kolei DNAT zmienia docelowy adres pakietu kiedy przychodzi on przez łańcuch OUTPUT lub PREROUTING. Możemy dzięki temu zastosować tzw. 'post forwarding'oraz 'transparent proxying'. Port forwarding służy do przekazania pakietu do wewnątrz sieci lokalnej będącej za NAT-em (lub maskaradą).

Rozszerzenia dostępne dla NAT

Rozszerzenie Opis
SNAT Zamienia adres źródłowy na inny
Przykład:
iptables -t nat -A POSTROUTING -j SNAT --to-source 1.2.3.4
MASQUERADE SNAT dla połączeń z dynamicznym adresem IP. Bardzo podobne do SNAT, ale gdy połączenie zostaje przerwane wszystkie śledzenia połączeń zostają zresetowane
Przykład:
iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0
DNAT Zamienia adres docelowy na inny. Dzieje się to w łańcuchu PREROUTING.
Przykład:
iptables -t nat -A PREROUTING -j DNAT --to-destination 1.2.3.4:8080 -p tcp --dport -i eth1
REDIRECT Jak sama nazwa wskazuje przekazuje pakiety do lkalnej sieci (będącej za maskaradą). Generalnie robi to samo co DNAT dla adresu z przychodzącej lokalizacji.
Przykład:
iptables -t nat -A PREROUTING -j REDIRECT --to-port 3128 -i eth1 -p tcp --dport 80


PART IV - przykład zaawansowanego firewalla


Scenariusz:



Nasze wymagania:

  1. Filtrowanie pakietów
    • PING do każdej sieci
    • TRACEROUTE do każdej sieci
    • Dostęp do DNS
  2. DMZ (strefa zdemilitaryzowana)
    1. SMTP - serwer mailowy
      • SMTP do Internetu
      • Akceptacja SMTP z sieci LAN i z Internetu
      • Akceptacja POP3 z sieci LAN
    2. DNS - serwer nazw
      • DNS do Internetu
      • Akceptacja DNS z sieci LAN, Internetu i z serwera filtrującego
    3. WWW - serwer Web
      • Akceptacja HTTP z sieci LAN i Internetu
      • Dostęp z sieci wewnętrznej
  3. LAN - sieć wewnętrzna
    • Pozwól WWW, FTP, TRACEROUTE, SSH do Intenetu
    • Pozwól SMTP do serwera mailowego
    • Pozwól POP3 do serwera mailowego
    • Pozwól DNS do serwera nazw
    • Pozwól WWW do serwera Web
    • Pozwól PING do serwera filtrującego


Rozwiązanie:

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done

iptables -A INPUT -i ! lo -j DROP
iptables -A OUTPUT -i ! lo -j DROP
iptables -A FORWARD -j DROP

ifconfig eth0 192.84.219.0 netmask 255.255.255.0
ifconfig eth1 192.168.1.0 netmask 255.255.255.0
pppd

route add default ppp0



iptables -N internal-dmz
iptables -N external-dmz
iptables -N internal-external
iptables -N dmz-internal
iptables -N dmz-external
iptables -N external-internal
iptables -N icmp-accept
iptables -N NEVER
iptables -N LOGDROP

iptables -A NEVER -j LOG --log-level alert --log-prefix "filter ERROR: "
iptables -A NEVER -j DROP

iptables -A LOGDROP -m limit -j LOG --log-prefix "filter: "
iptables -A LOGDROP -j DROP

iptables -A FORWARD -i eth1 -o eth0 -j internal-dmz
iptables -A FORWARD -i eth1 -o ppp0 -j internal-external
iptables -A FORWARD -i eth0 -o ppp0 -j dmz-external
iptables -A FORWARD -i eth0 -o eth1 -j dmz-internal
iptables -A FORWARD -i ppp0 -o eth0 -j external-dmz
iptables -A FORWARD -i ppp0 -o eth1 -j external-internal
iptables -A FORWARD -j NEVER


Definicja lancucha icmp-accept:

iptables -A icmp-accept -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A icmp-accept -p icmp --icmp-type source-quench -j ACCEPT
iptables -A icmp-accept -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A icmp-accept -p icmp --icmp-type parameter-problem -j ACCEPT

iptables -A internal-dmz -p tcp -d $MAILSERVER --dport smtp -j ACCEPT
iptables -A internal-dmz -p tcp -d $MAILSERVER --dport pop-3 -j ACCEPT
iptables -A internal-dmz -p udp -d $NAMESERVER --dport domain -j ACCEPT
iptables -A internal-dmz -p tcp -d $NAMESERVER --dport domain -j ACCEPT
iptables -A internal-dmz -p tcp -d $WEBSERVER --dport www -j ACCEPT
iptables -A internal-dmz -p tcp -d $WEBSERVER --dport rsync -j ACCEPT
iptables -A internal-dmz -p icmp -j icmp-accept
iptables -A internal-dmz -j LOGDROP

iptables -A external-dmz -p tcp -d $MAILSERVER --dport smtp -j ACCEPT
iptables -A external-dmz -p udp -d $NAMESERVER --dport domain -j ACCEPT
iptables -A external-dmz -p tcp -d $NAMESERVER --dport domain -j ACCEPT
iptables -A external-dmz -p tcp -d $WEBSERVER --dport www -j ACCEPT
iptables -A external-dmz -p icmp -j icmp-accept
iptables -A external-dmz -j DROP

iptables -A internal-external -p tcp --dport www -j ACCEPT
iptables -A internal-external -p tcp --dport ssh -j ACCEPT
iptables -A internal-external -p udp --dport 33434:33500 -j ACCEPT
iptables -A internal-external -p tcp --dport ftp -j ACCEPT
iptables -A internal-external -p tcp --dport 1024:65535 -j ACCEPT
iptables -A internal-external -p icmp --icmp-type ping -j ACCEPT
iptables -A internal-external -j LOG
iptables -A internal-external -j REJECT

iptables -A dmz-internal -p tcp ! --syn -s $MAILSERVER smtp -j ACCEPT
iptables -A dmz-internal -p udp -s $NAMESERVER domain -j ACCEPT
iptables -A dmz-internal -p tcp ! --syn -s $NAMESERVER domain -j ACCEPT
iptables -A dmz-internal -p tcp ! --syn -s $WEBSERVER www -j ACCEPT
iptables -A dmz-internal -p tcp ! --syn -s $WEBSERVER rsync -j ACCEPT
iptables -A dmz-internal -p icmp -j icmp-accept
iptables -A dmz-internal -j NEVER

iptables -A dmz-external -p tcp -s $MAILSERVER smtp -j ACCEPT
iptables -A dmz-external -p udp -s $NAMESERVER domain -j ACCEPT
iptables -A dmz-external -p tcp -s $NAMESERVER domain -j ACCEPT
iptables -A dmz-external -p tcp ! --syn -s $WEBSERVER www -j ACCEPT
iptables -A dmz-external -p icmp -j icmp-accept
iptables -A dmz-external -j NEVER

iptables -A external-internal -p tcp ! --syn --sport www -j ACCEPT
iptables -A external-internal -p tcp ! --syn --sport ssh -j ACCEPT
iptables -A external-internal -p tcp ! --syn --sport ftp -j ACCEPT
iptables -A external-internal -p tcp ! --syn --sport 1024:65535 -j ACCEPT
iptables -A external-internal -p icmp --icmp-type pong -j ACCEPT
iptables -A external-internal -j DROP



iptables -N external-if
iptables -N dmz-if
iptables -N internal-if

iptables -A INPUT -i ppp0 -j external-if
iptables -A INPUT -i eth0 -j dmz-if
iptables -A INPUT -i eth1 -j internal-if

iptables -A external-if -p icmp --icmp-type pong -j ACCEPT
iptables -A external-if -j icmp-accept
iptables -A external-if -j DROP

iptables -A dmz-if -p tcp ! --syn -s $NAMESERVER 53 -j ACCEPT
iptables -A dmz-if -p udp -s $NAMESERVER 53 -j ACCEPT
iptables -A dmz-if -p icmp --icmp-type pong -j ACCEPT
iptables -A dmz-if -j icmp-accept
iptables -A dmz-if -j NEVER

iptables -A internal-if -p icmp --icmp-type ping -j ACCEPT
iptables -A internal-if -p icmp --icmp-type pong -j ACCEPT
iptables -A internal-if -j icmp-accept
iptables -A internal-if -j LOGDROP

iptables -D 1 input
iptables -D 1 forward
iptables -D 1 output

Legenda:

Nazwa łańcucha Opis
internal-dmz regułki określające zasady dla pakietów z sieci LAN do strefy serwerów DMZ
external-dmz regułki określające zasady dla pakietów z sieci INTERNET do strefy serwerów DMZ
internal-external regułki określające zasady dla pakietów z sieci LAN do sieci INTERNET
dmz-internal regułki określające zasady dla pakietów ze strefy serwerów DMZ do sieci LAN
dmz-external regułki określające zasady dla pakietów ze strefy serwerów DMZ do sieci INTERNET
external-internal regułki określające zasady dla pakietów z sieci INTERNET do sieci LAN
icmp-accept regułki określające szczegółowe zasady dla pakietów ICMP
NEVER regułki określające zasady dla pakietów które nigdy nie powinny się pojawić na danym interfejsie
LOGDROP regułki określające zasady tworzenia logów


Podsumowanie:

Jak widać filtrowanie pakietów daje nam bardzo duże możliwości. Niestety istnieje też poważna wada takiego rozwiązania: czym bardziej zaawansowany firewall tym większe prawdopodobieństwo popełnienia błędu ! Dlatego przestrzegam przed tego typu rozwiązaniami.
Pozostaje mi życzyć miłych chwil spędzonych przy konfiguracji naszego firewalla ;-)