IP Filter
to fajna, mała paczka ściany ogniowej. Robi prawie wszystko co
inne, darmowe (ipfwadm, ipchains, ipfw), ale oprócz tego jest
również przenośna między platformami i potrafi parę ciekawych
rzeczy których inne nie robią.
3.
Wprowadzenie do zaawansowanych ścian ogniowych
Ta sekcja została napisana w ten sposób, by przeczytać ją
bezpośrednio po porzedniej części. Poniżej zawarto zarówno
koncepcje projektowania zaawansowanych ścian ogniowych, jak i
zaawansowane możliwości zawarte w programie ipfilter. W
momencie gdy ta sekcja będzie ci doskonale znana, powinieneś
być w stanie zbudować bardzo silną ścianę ogniową.
3.1 Gwałtowna paranoja lub polityka Domyślnego
Blokowania ( ang. Default-Deny )
Istnieje pewien poważny problem gdy blokujemy usługi na
podstawie portów: czasami się one przesuwają . Programy które
bazują na RPC są w tym naprawdę okropne - lockd, statd, nawet
nfsd słucha na portach innych niż 2049. Jest bardzo trudno
przewidzieć, a nawet gorzej zautomatyzować proces dostrajania
się w kółko i na okrągło. A co jeśli zapomnisz o usłudze?
Zamiast zmagać się z bałaganem, zacznijmy od stanu zupełnie
czystego. Aktualny zestaw reguł wygląda tak:
Tak, naprawdę zaczynamy od nowa. Pierwszą regułę której
użyjemy będzie:
block in all
Nie przechodzi żaden ruch sieciowy. Żaden. Nawet tyci-tyci.
Jesteś w tym momencie raczej bezpieczny. Konfiguracja
użyteczna, ale bezpieczna. Najlepsze w tym wszystkim to to, że
niewiele musisz teraz zrobić by nadal pozostać bezpiecznym,
ale stać się też troszkę użytecznym. Powiedzmy że maszyna
pracuje jako serwer WWW, nic więcej, nic mniej. Nie wykonuje
nawet zapytań DNS. Chce tylko odbierać połączenia na port
80/tcp
i to wszystko. Możemy to zrobić. Wykonamy
to dokładając drugą regułę, którą już znasz:
block in on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
Maszyna przyjmie ruch na port 80 dla 20.20.20.1 i odrzuci
wszystko inne. Dla podstawowych zastosowań ścian ogniowych to
wszystko co potrzeba.
3.2 Zezwolenie na
ruch wynikające z innych reguł; reguła `keep state'
Zadaniem twojej ściany ogniowej jest zabezpieczenie przed
niechcianym ruchem z punktu B do punktu A. Mamy generalne
reguły które mówią `jeśli tylko ten pakiet jest do portu
23, to go puszczamy'. Mamy generalne reguły mówiące
`jeśli tylko ten pakiet ma flagę FIN ustawioną, to go
puszczamy'. Nasze ściany ogniowe nie znają początku,
środka ani końca sesji TCP/UDP/ICMP. Mają tylko reguły które
sprawdzają w stosunku do wszystkich pakietów. Musimy mieć
nadzieję, że pakiet który ma flagę FIN ustawioną nie jest tak
naprawdę skanem FIN, sprawdzającym nasze usługi. Mamy nadzieję
że pakiet do portu 23 nie jest próbą przechwycenia naszej
sesji telnetowej. A co jeśli byłaby szansa na zidentyfikowanie
i zautoryzowanie poszczególnych sesji TCP/UDP/ICMP i rozróżnić
te które są skanami portów czy też atakami DoS? Jest taki
sposób, i nazywa się utrzymywaniem stanu ( ang.
keep state ).
Chcemy wygody i bezpieczeństwa w jednym. Wielu ludzi
również i dlatego Cisco ma klauzulę `established' ( nawiązane
) i pozwala przejść nawiązanym sesjom TCP. IPFW też ma również
`established', IPFWADM ma `setup/established' (
konfigurujące/nawiązane ). Wszystkie mają tą opcję, ale nazwa
jest bardzo myląca. Kiedy ją pierwszy raz zobaczyliśmy,
myśleliśmy że nasz filtr pakietów śledzi każdą sesję i
sprawdza co się w niej dzieje, że wie czy połączenie naprawdę
jest nawiązane czy nie. Tak naprawdę, wszystkie wierzą
pakietowi że jest tym czym twierdzi że jest, a każdy może
przecież kłamać. Czytają sekcję flag nagłówka pakietu TCP i tu
pojawia się problem bo nie mają opcji podobnego analizowania
pakietów UDP/ICMP. Każdy kto potrafi spreparować nagłówki
pakietów może pokonać taką ścianę ogniową.
No to co takiego szczególnego robi IPF, możesz zapytać?
Cóż, inaczej niż w innych ścianach ogniowych, IPF naprawdę
potrafi śledzić połączenia i stwierdzić czy połączenie jest
nawiązane czy nie. I robi to zarówno dla pakietów TCP, UDP i
ICMP, nie tylko TCP. IPF nazywa to właśnie utrzymywaniem
stanu. Słowo kluczowe do zastosowania w regule brzmi
keep state
.
Do tej pory, mówiliśmy że pakiety przychodzą, zestaw reguł
zostaje sprawdzony, pakiety wychodzą i znowu sprawdzany jest
zestaw reguł. Dokładniej rzecz biorąc, to co się dzieje
wygląda tak: pakiety przychodzą, sprawdzana jest tabela
stanów, potem być może sprawdzany jest zestaw reguł
dotyczących połączeń przychodzących, pakiety wychodzą,
sprawdzana jest tabela stanów, i znów być może
sprawdzany jest zestaw reguł dotyczących połączeń
wychodzących. Tabela stanów to lista sesji TCP/UDMP/ICMP które
są przepuszczane bez pytania przez ścianę ogniową, pomijając
cały zestaw reguł. Brzmi jak poważna dziura w bezpieczeństwie?
Poczekaj, to najwspanialsza rzecz która mogła przytrafić się
twojej ścianie ogniowej.
Wszystkie sesje TCP/IP mają początek, środek i koniec (
aczkolwiek czasami jest nimi ten sam, jeden pakiet ). Nie
możesz mieć końca bez środka, a środka bez początku. To
oznacza, że wszystko co tak naprawdę potrzebujesz filtrować to
początek sesji TCP/UDP/ICMP. Jeśli początek sesji ma prawo
przejść przez ścianę ogniową, cała reszta ( środek i koniec )
również. Utrzymywanie stanu umożliwia Ci zignorowanie środka i
końca, a skupienie się na blokowaniu/przepuszczaniu nowych
sesji. Jeśli nowa sesja jest przepuszczana, wszystkie pakiety
należące do niej również zostaną przepuszczone. Jeśli ma
zostać zablokowana, żaden z pakietów który ma do niej należeć
nie zostanie przepuszczony. Poniżej przykład dla pracy z
serwerem ssh (i nic poza serwerem ssh):
block out quick on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
Pierwszą rzeczą którą możesz zauważyć, to brak komendy
`pass out
'. W rzeczywistości, jest tylko jedna,
zawierająca wszystko reguła block out
. Pomimo
tego, zestaw reguł jest kompletny. Dzieje się tak, ponieważ
poprzez utrzymywanie stanu tworzony jest cały zestaw reguł. W
momencie, w którym pierwszy pakiet SYN dociera do serwera,
tworzona jest pozycja w tabeli stanu i reszta sesji ssh jest
również przepuszczana bez żadnej interferencji ze strony
ściany ogniowej. Poniżej kolejny przykład:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
W tym przypadku, serwer nie serwuje żadnych usług. Tak
naprawdę, nie jest serwerem a klientem. I ten klient nie chce
by żadne nieautoryzowane pakiety docierały do jego stosu IP.
Jednakże, chce mieć pełen dostępu do internetu i naturalnie
potrzebuje możliwości odpowiadania na pakiety które należą do
połączeń przez niego inicjowanych. Ten prosty zestaw reguł
tworzy listę stanów dla każdej nowej wychodzącej sesji TCP. I
znowu, ponieważ tworzona jest nowa pozycja w liście stanów,
nowe sesje TCP mają swobodę w komunikowaniu się tam i z
powrotem tak jak chcą, bez niepotrzebnego zainteresowania ze
strony ściany ogniowej. Wspomnieliśmy również, że działa to
również dla UDP i ICMP:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
Tak Wirginio, możemy pingować. Teraz utrzymujemy stany
połączeń TCP, UDP, ICMP. Możemy wykonywać połączenia
wychodzące tak jakby nie było żadnej ściany ogniowej, a
jednocześnie wszyscy hipotetyczni atakujący nie mogą wejść z
powrotem. Jest to bardzo wygodne bo nie ma potrzeby śledzić na
których portach słuchamy, a jedynie porty na które chcemy by
można się było dostawać.
Utrzymywanie stanu jest bardzo wygodne, ale jednocześnie
może być trochę zagmatwane. Możesz sobie strzelić w stopę w
bardzo dziwne sposoby. Rozważmy następujący zestaw reguł:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
Na pierwszy rzut oka, wygląda na całkiem poprawną
konfigurację. Umożliwiamy na nawiązywanie sesji przychodzących
na port 23 i wychodzących wszędzie. Naturalnie, pakiety
wychodzące na port 23 będą miały pakiety odpowiedzi, ale
zestaw reguł jest ustawiony w ten sposób że reguła `pass
out
' wygeneruje pozycję w liście stanów i wszystko
będzie działało poprawnie. Przynajmniej tak ci się tylko
wydaje.
Przykra prawda polega na tym, że po 60 sekundach
bezczynności pozycja w tablicy stanów zostanie zamknięta ( w
przeciwieństwie do normalnych 5 dni ). Dzieje się tak ponieważ
mechanizm śledzący połączenia `nie widział' oryginalnego
pakietu SYN przeznaczonego do portu 23, a jedynie SYN ACK. IPF
jest bardzo dobry w śledzeniu sesji TCP od początku do końca,
ale nie jest zbyt dobry w odgadywaniu poprawności połączenia
od połowy. Powinieneś przepisać reguły na takie:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
Dodatkowe słowo w regułach spowoduje że pierwszy pakiet
utworzy pozycję w tablicy stanów i wszystko będzie działało
tak jak się tego spodziewałeś. W momencie gdy 3-stopniowy
proces nawiązywania połączenia ( ang.
handshake ) był widziany przez mechanizm utrzymywania
stanu, połączenie oznaczane jest jako będące w trybie 4/4.
Oznacza to, że jest ono skonfigurowane na długoterminowa
wymianę danych, dopóki nie zostanie zamknięte ( kiedy to
zmieniany jest również tryb ). Możesz sprawdzić aktualne tryby
w tablicy stanów poleceniem `ipfstat
-s
'.
3.3 UDP ze sprawdzaniem
stanów
UDP nie ma stanów, więc naturalnie wykonanie dobrej roboty
w śledzeniu stanu połączenia jest tutaj dużo trudniejsze. Mimo
to ipf
robi dobrą robotę. Kiedy maszyna A wysyła
pakiet UDP do maszyny B z portu źródłowego X na port docelowy
Y, ipf
pozwoli na odpowiedź z maszyny B do A z
portu źródłowego Y na port docelowy X. Jest to krótkoterminowa
pozycja w tabeli stanów, stworzona tylko na 60 sekund.
Poniżej przykład tego co się dzieje gdy wykonujemy nslookup
by pobrać adres IP maszyny http://www.3com.com:
$ nslookup www.3com.com
Generowany jest pakiet DNS:
17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
Pakiet pochodzi z 20.20.20.1
i z portu 2111, a
skierowany jest do 198.41.0.5
na port 53.
Tworzona jest 60-sekundowa pozycja w liście stanów. Jeśli w
tym czasie nadejdzie pakiet z 198.41.0.5
portu 53
przeznaczony dla 20.20.20.1
na port 2111,
zostanie przepuszczony. Jak możesz sprawdzić, milisekundy
później:
17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
Pakiet pasuje do kryteriów opisywanych przez pozycję w
liście stanów i jest przepuszczany. W tym samym momencie w
którym pakiet wchodzi, pozycja znika z listy stanów i żaden
nowy pakiet nie może zostać wpuszczony, nawet gdyby twierdził
że jest z dokładnie tego samego źródła.
3.4 ICMP ze sprawdzaniem stanów
IPFilter traktuje stany ICMP dokładnie tak, jak możnaby się
spodziewać rozumiejąc jak ICMP używany jest z TCP i UDP, i
przy zrozumieniu jak działa komenda `keep state
'.
Są generalnie dwa typy wiadomości ICMP: zapytania i
odpowiedzi. Gdy wpisujesz regułę taką jak na przykład:
pass out on tun0 proto icmp from any to any icmp-type 8 keep state
by zezwolić na wychodzące odpowiedzi na żądanie echa (
typowy ping ), wpuszczony zostanie pakiet icmp-type
0
, który jest zwyczajową odpowiedzią. Pozycja w liście
stanów ma domyślny czas wygaśnięcia niekompletnego stanu 0/0
wynoszący 60 sekund. W związku z tym, jeśli utrzymujesz stan
każdej wychodzącej wiadomości icmp która wywołuje odpowiedź
icmp, potrzebujesz reguły `proto icmp [...] keep
state
'.
Jednakże, większość wiadomości ICMP to wiadomości o
statusie generowane przez błędy w UDP ( i czasami TCP ). W
IPFilter w wersjach 3.4.x i wyższych każda wiadomość o błędzie
ICMP ( powiedzmy icmp-type 3 code 3
- port
niedostępny, lub icmp-type 11
- przekroczony czas
), która pasuje do aktywnego wpisu w liście stanów, powoduje
że pakiet ICMP jest wpuszczany. Na przykład, w starszych
wersjach IPFilter, jeśli chciałeś by działał traceroute
musiałeś użyć:
pass out on tun0 proto udp from any to any port 33434><33690 keep state
pass in on tun0 proto icmp from any to any icmp-type timex
a teraz możesz uzyskać to samo poprzez wpis:
pass out on tun0 proto udp from any to any port 33434><33690 keep state
By zabezpieczyć się przed wślizgnięciem się nieproszonych
pakietów ICMP przez Twoją ścianę ogniową, nawet gdy aktywny
wpis w tabeli stanów istnieje, przychodzący pakiet ICMP jest
sprawdzany nie tylko pod kątem poprawnego adresu źródłowego i
przeznaczenia ( i portów, jeśli to go dotyczy ), ale jeszcze
małej części danych w pakiecie określającej w wyniku którego
pakietu ta wiadomość ICMP została wygenerowana.
3.5 Wykrywanie skanów FIN; słowa kluczowe `flags' i
`keep frags'
Wróćmy do czterolinijkowego zestawu reguł z poprzedniej
sekcji:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
Jest on prawie, ale nie całkiem satysfakcjonujący. Problem
polega na tym, że nie tylko pakiety SYN mogą dotrzeć do portu
23, ale również inne, stare pakiety. Możemy to zmienić przez
zastosowanie słowa kluczowego `flags
':
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
pass out quick on tun0 proto tcp from any to any flags S keep state
block in quick all
block out quick all
Obecnie tylko pakiety TCP, skierowane do 20.20.20.1 na port
23 z ustawioną tylko flagą SYN mogą dotrzeć i utworzyć pozycję
w liście stanów. Samotna flaga SYN ustawiona jest tylko w
pierwszym pakiecie sesji TCP ( zwanej pakietem nawiązującym
połączenie TCP ) i to jest to co chcieliśmy tak naprawdę
uzyskać. Są przynajmniej dwie zalety takiego zapisu: nie dotrą
do ciebie żadne inne pakiety które mogłyby namieszać w tabeli
stanów. Po drugie, skany FIN i XMAS nie powiodą się ponieważ
mają ustawione również inne flagi oprócz SYN. Aktualnie,
wszystkie przychodzące pakiety muszą być albo nawiązującymi
połączenie albo już do niego należeć. Jeśli nadejdzie
cokolwiek innego, jest albo spreparowane albo jest skanem
portów. Istnieje jednak jeden wyjątek - gdy dociera do nas
pakiet sfragmentowany. IPF jest przygotowany na obsługę takich
sytuacji, z pomocą słowa kluczowego `keep frags
'.
Przy jego zastosowaniu, IPF będzie potrafił śledzić również
sesje z pakietami, które są sfragmentowane i pozwoli im
przejść. Przepiszmy te trzy reguły by logować pakiety
spreparowane i zezwolić na obsługę pakietów
sfragmentowanych:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags
pass out quick on tun0 proto tcp from any to any keep state flags S keep frags
block in log quick all
block out log quick all
Taki zapis działa, ponieważ każdy pakiet który powinien być
wpuszczony, zostanie najpierw wpisany do tabeli stanów, zanim
reszta reguł zdąży go zablokować. Jedynym skanem którego ten
zapis nie wykryje jest skan SYN. Jeśli naprawdę jesteś tym
zaniepokojony, być może powinieneś logować również wszystkie
pakiety SYN.
3.6 Odpowiadanie na
zablokowane pakiety
Jak do tej pory, wszystkie nasze zablokowane pakiety byłu
zrzucane na podłogę, i bez względu na to czy zostały
zalogowane czy nie, nie odsyłaliśmy niczego do hosta który
przysłał nam pakiet. Czasami nie jest to najbardziej pożądane
rozwiązanie, ponieważ robiąc coś takiego, informujemy go że
mamy działający filtr pakietów. Wydaje się dużo lepszym
rozwiązaniem wprowadzenie w błąd atakującego, że nie działa
żaden filtr pakietów i nie ma żadnych usług przy pomocy
których możnaby się włamać. Tutaj dochodzimy do dużo bardziej
wyrafinowanego blokowania.
Kiedy na systemie Unixowym nie działa usługa, zwykle wysyła
on zdalnemu systemowi jakiś rodzaj odpowiedzi. W przypadku
TCP, jest to pakiet RST (Reset). Kiedy blokujemy pakiet TCP,
IPF może faktycznie odesłać pakiet RST do nadawcy jeśli
użyjemy słowa kluczowego `return-rst
'.
Podczas gdy do tej pory pisaliśmy:
block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23
pass in all
Możemy teraz napisać:
block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23
block in log quick on tun0
pass in all
Potrzebujemy dwóch reguł `block
', ponieważ
`return-rst
' działa tylko dla TCP, a my nadal
chcemy zablokować protokoły takie jak UDP, ICMP i inne. Kiedy
użyjemy takich reguł, strona zdalna otrzyma komunikat
`connection refused
' ( połączenie odrzucone ),
zamiast `connection timed out
' ( upłynął czas na
nawiązanie połączenia ).
Możliwe jest również odsyłanie wiadomości z błędami, gdy
ktoś wysyła pakiet UDP do portu w twoim systemie. Do tej pory
pisaliśmy:
block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
Używając słowa kluczowego return-icmp
możemy
teraz napisać:
block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
Zgodnie z książką TCP/IP Illustrated,
port-unreachable
( port nieosiągalny ) jest
prawidłowym komunikatem ICMP odpowiedzi jeśli na danym porcie
nie nasługuje żadna usługa. Możesz użyć dowolnego typu ICMP,
ale port-unreachable
jest prawdopodobnie
najlepszą odpowiedzią. Jest również domyślna w przypadku
użycia `return-icmp
'.
Jednak, gdy zaczniesz używać `return-icmp
',
zauważysz że nie jest to bardzo skryte, ponieważ zwraca pakiet
ICMP z adresem ściany ogniowej, a nie adresem maszyny dla
której pakiet był przeznaczony. Zostało to naprawione w
ipfilter w wersji 3.3 i dodano nowe słowo kluczowe:
`return-icmp-as-dest
'. Nowy format wygląda
tak:
block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111
Powinieneś być bardzo uważny i generować pakiety odpowiedzi
tylko w sytuacjach, w których dobrze wiesz na co odpowiadasz.
Na przykład, odpowiadanie return-icmp
na
broadcast w sieci lokalnej może skończyć się zalaniem
pakietami sieci.
3.7 Wymyślne techniki
logowania
Bardzo ważne jest, by zauważyć, że sama obecność słowa
kluczowego `log
' zapewnia tylko dostępność
pakietu dla urządzenia logującego ipfilter:
/dev/ipl
. Tak naprawdę aby zobaczyć tą
informację, musisz mieć uruchomione narzędzie
ipmon
( lub inne, które czyta
/dev/ipl
). Typowe użycie słowa
`log
' jest skojarzone z poleceniem ipmon
-s
, które dopiero loguje informacje do syslog. Od
ipfilter 3.3, można nawet kontrolować zachowanie logujące
syslog poprzez użycie słowa `log level
', tak jak
w regułach poniżej:
block in log level auth.info quick on tun0 from 20.20.20.0/24 to any
block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21
W dodatku, możesz ograniczać informacje które są logowane.
Na przykład, możesz nie być zainteresowany faktem, że ktoś
próbował twój port telnetu 500 razy, a jedynie, że w ogóle
próbował to robić. Służy do tego opcja `log
first
' logująca tylko pierwszy pakiet. Oczywiście,
pierwszeństwo dotyczy tylko jednej sesji i dla typowego
zablokowania pakietu, trudno będzie ci uzyskać efekt by to
robiło dokładnie to co chciałeś. Jednakże przy połączeniu tego
z poleceniami `pass
' i `keep state
',
może być to bardzo pomocne narzędzie w śledzeniu ruchu.
Inna użyteczna opcja którą możesz wykorzystać przy
logowaniu, to zachowanie interesujących fragmentów pakietu
oprócz normalnej informacji logowanej z pakietem. IPFilter
zaloguje pierwsze 128 bajtów pakietu jeśli użyjesz słowa
`log body
'. Powinieneś starać się ograniczać
takie logowanie, ponieważ czyni to twoje logi bardzo
szczegółowymi. Dla niektórych zastosowań jest to jednak
wygodne - można sprawdzić dokładniej pakiet, lub wysłać te
informacje do jakiejś aplikacji do dalszej analizy.
3.8 Złożenie tego wszystkiego razem
Mamy teraz całkiem szczelną ścianę ogniową, ale nadal
możemy ją jeszcze uszczelnić. Część oryginalnego zestawu reguł
usuneliśmy, część została jako użyteczna. Sugerowałbym
wrócenie do wszystkich dotyczących zabezpieczenia przed
fałszowaniem. To sprawia, że zostajemy z:
block in on tun0
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in quick on tun0 from 0.0.0.0/8 to any
block in quick on tun0 from 169.254.0.0/16 to any
block in quick on tun0 from 192.0.2.0/24 to any
block in quick on tun0 from 204.152.64.0/23 to any
block in quick on tun0 from 224.0.0.0/3 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state
3.9 Zwiększanie wydajności przez
tworzenie grup reguł
Rozszerzmy użycie naszej ściany ogniowej poprzez stworzenie
bardziej skomplikowanej, i mamy nadzieję bardziej przystającej
do świata rzeczywistego konfiguracji przykładowej. Na potrzeby
tego przykładu, zmienimy nazwy interfejsów i numerację sieci.
Załóżmy, że mamy trzy interfejsy na swojej ścianie ogniowej,
xl0
, xl1
i xl2
.
xl0
jest podłączony do sieci zewnętrznej
20.20.20.0/26
xl1
jest podłączony do naszej sieci
zdemilitaryzowanej 20.20.20.64/26
xl2
jest podłączony do naszej chronionej
sieci 20.20.20.128/25
Zdefiniujemy od razu cały zestaw reguł, ponieważ jak do tej
pory powinieneś już umieć je czytać:
block in quick on xl0 from 192.168.0.0/16 to any
block in quick on xl0 from 172.16.0.0/12 to any
block in quick on xl0 from 10.0.0.0/8 to any
block in quick on xl0 from 127.0.0.0/8 to any
block in quick on xl0 from 0.0.0.0/8 to any
block in quick on xl0 from 169.254.0.0/16 to any
block in quick on xl0 from 192.0.2.0/24 to any
block in quick on xl0 from 204.152.64.0/23 to any
block in quick on xl0 from 224.0.0.0/3 to any
block in log quick on xl0 from 20.20.20.0/24 to any
block in log quick on xl0 from any to 20.20.20.0/32
block in log quick on xl0 from any to 20.20.20.63/32
block in log quick on xl0 from any to 20.20.20.64/32
block in log quick on xl0 from any to 20.20.20.127/32
block in log quick on xl0 from any to 20.20.20.128/32
block in log quick on xl0 from any to 20.20.20.255/32
pass out on xl0 all
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state
pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state
pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state
pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state
block out on xl1 all
pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
block out on xl2 all
pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
Z tego arbitralnego przykładu, od razu można zauważyć że
nasz zestaw reguł powoli staje się coraz mniej czytelny. By
sprawy pogorszyć, w momencie gdy dodamy reguły dla naszej
sieci zdemilitaryzowanej (DMZ), musimy dodać dodatkowe reguły
testujące dla każdego pakietu, co pogorszy wydajność połączeń
xl0-xl2
. Jeśli zbudujesz ścianę ogniową z
regułami takimi jak te, a masz dużą przepustowość łącza i
średnio dużo mocy obliczeniowej procesora, każdy kto ma stację
roboczą w sieci podłączonej do interfejsu xl2
przyjdzie do ciebie by umieścić twoją głowę na talerzu. Zatem,
by utrzymać połączenie głowy z torsem, możesz przyśpieszyć
znacznie porównywanie przez stworzenie grup reguł. Pozwalają
one na zapisanie swoich reguł w formie drzewa, zamiast w
postaci linearnej - więc jeśli pakiet nie ma nic wspólnego z
pewnym zestawem testów ( powiedzmy, reguł dotyczących
xl1
), nie będą one w ogóle brane pod uwage. Jest
to coś w rodzaju posiadania wielu ścian ogniowych na tej samej
maszynie.
Poniżej przykład z którym zaczniemy:
block out quick on xl1 all head 10
pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
block out on xl2 all
W tym bardzo prostym przykładzie, widzimy małą zapowiedź
potęgi grup reguł. Jeśli pakiet nie jest przeznaczony dla
interfejsu xl1
, nagłówek ( head
)
dla grupy 10 ( group 10
) w ogóle nie będzie
pasował i nie zostanie uwzględniony przy porównywaniu. Jeśli
pakiet pasuje do reguły xl1
, słowo kluczowe
quick
spowoduje ucięcie przetwarzania na poziomie
podstawowym/korzenia ( grupa reguł 0 ) i skoncentruje się na
testowaniu reguł które dotyczą grupy 10, w tym wypadku
sprawdzenia flagi SYN w pakietach przeznaczonych dla
80/tcp
. W ten sposób, możemy przepisać powyższe
reguły tak by zmaksymalizować wydajność naszej ściany
ogniowej.
block in quick on xl0 all head 1
block in quick on xl0 from 192.168.0.0/16 to any group 1
block in quick on xl0 from 172.16.0.0/12 to any group 1
block in quick on xl0 from 10.0.0.0/8 to any group 1
block in quick on xl0 from 127.0.0.0/8 to any group 1
block in quick on xl0 from 0.0.0.0/8 to any group 1
block in quick on xl0 from 169.254.0.0/16 to any group 1
block in quick on xl0 from 192.0.2.0/24 to any group 1
block in quick on xl0 from 204.152.64.0/23 to any group 1
block in quick on xl0 from 224.0.0.0/3 to any group 1
block in log quick on xl0 from 20.20.20.0/24 to any group 1
block in log quick on xl0 from any to 20.20.20.0/32 group 1
block in log quick on xl0 from any to 20.20.20.63/32 group 1
block in log quick on xl0 from any to 20.20.20.64/32 group 1
block in log quick on xl0 from any to 20.20.20.127/32 group 1
block in log quick on xl0 from any to 20.20.20.128/32 group 1
block in log quick on xl0 from any to 20.20.20.255/32 group 1
pass in on xl0 all group 1
pass out on xl0 all
block out quick on xl1 all head 10
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10
pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10
pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10
pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state group 10
pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state group 10
pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
block out on xl2 all
pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
Teraz możesz poobserwować grupy reguł w akcji. Dla
komputera w sieci xl2
, kompletnie pomijamy
wszystkie testy w grupie 10, kiedy nie komunikujemy się z
żadnymi komputerami w tej sieci.
Zależnie od Twojej sytuacji, korzystne może być
pogrupowanie reguł według protokołu, różnych maszyn, bloków
sieciowych, lub czegokolwiek - tak by sprawić, że przepływ
informacji będzie płynny.
3.10 słowo
kluczowe - `Fastroute' daje niewykrywalności ( ang.
stealth )
Nawet mimo faktu, że przekazujemy część pakietów a inne
blokujemy, zachowujemy się tak, jak dobrze zachowujący się
router powinien się zachowywać - zmniejszamy TTL pakietu i
niniejszym oznajmiamy całemu światu że tak, jest tutaj
przejście ( ang. hop ). Możemy jednak ukryć swoją
obecność przed zbyt dociekliwymi aplikacjami takimi jak
unix'owy traceroute, który używa pakietów UDP z różnymi TTL by
zmapować ilość przejść pomiędzy dwoma komputerami. Jeśli
chcemy, by nadchodzące traceroute działało, ale nie chcemy
oświadczać że mamy tu ścianę ogniową która spowoduje dodanie
jednego przejścia, możemy zrobić to regułą taką jak ta:
block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465
Obecność słowa `fastroute
' zasygnalizuje
ipfilter żeby nie przekazywać pakietu do stosu IP dla
wykonania routingu, co spowodowałoby zmniejszenie TTL pakietu.
Pakiet zostanie po prostu od razu umieszczony na interfejsie
wyjściowym przez ipfilter i nic nie zostanie zmienione.
ipfilter oczywiście sprawdzi systemową tablicę routingu by
sprawdzić na jakim interfejsie powinien wystawić pakiet, ale
wykona zadanie przeroutowania pakietu sam.
Istnieje również powód, dla którego używamy tu słów
`block quick
'. Gdybyśmy użyli słowa
`pass
' i mielibyśmy włączone przekazywanie ( ang.
forwarding ) pakietów IP w kernelu, skończyłoby się
to na tym, że dostalibyśmy dwie ścieżki którymi pakiet mógłby
wyjść, a to prawdopodobnie spowodowałoby błąd kernel
panic.
Trzeba również dodać, że większość kerneli Uniksowych ( a w
szczególności te, na których ipfilter zwykle pracuje ), mają
dużo bardziej wydajny kod routingu niż ten w ipfilter, a w
związku z tym nie powinieneś myśleć o słowie
`fastroute
' jako o sposobie na zwiększenie
szybkości pracy swojej ściany ogniowej. Powinno być ono
używane tylko w przypadku gdy ukrycie się jest
najważniejsze.
4. NAT i proxy
Poza otoczeniem firmowym, jedną z największych zalet
technologii ścian ogniowych jest możliwość połączenia wielu
komputerów przez jeden interfejs zewnętrzny, często bez zgody,
wiedzy czy nawet podejrzeń ze strony dostawcy internetowego.
Ci którzy znają Linuksa nazywają to Maskaradą IP ( ang. IP
Masquerading ), ale dla reszty świata jest ona znana pod
nazwą Translacja Adresów Sieciowych, lub w skrócie NAT ( ang.
Network Address Translation ).
4.1 Mapowanie wielu adresów w jeden
Najprostszym zastosowaniem NAT jest dokładnie to co robi
jego odpowiednik - Linuksowa Maskarada IP. Zapisuje się to w
jednej prostej regule:
map tun0 192.168.1.0/24 -> 20.20.20.1/32
Bardzo proste. Zawsze gdy pakiet wychodzi przez interfejs
tun0
ze źródłowym adresem pasującym do maski CDIR
192.168.1.0/24
, adres jest zamieniany jeszcze na
stosie IP, tak by zawierał adres źródłowy
20.20.20.1
a dopiero wtedy zostaje wysłany do
swojego celu przeznaczenia. System utrzymuje listę jakie
zmapowane połączenia są w trakcie tak by mógł wykonać czynność
odwrotną gdy nadejdzie odpowiedź ( skierowana do
20.20.20.1
) i odesłać ją do oryginalnego
nadawcy.
Jest jednak pewien minus reguły którą teraz wpisaliśmy. W
wielu przypadkach, nie wiemy jaki mamy adres IP naszego
zewnętrznego interfejsu ( jeśli używasz tun0
czy
ppp0
i typowego ISP ), więc ustawienie tablicy
NAT staje się raczej problematyczne. Na szczęście NAT jest na
tyle mądry, że potrafi zaakceptować adres w postaci 0/32.
Sygnalizuje to, że musi sprawdzić sobie sam jaki właściwie
adres ma interfejs zewnętrzny i prawidłowo zmodyfikować
pakiet. Spójrz niżej:
map tun0 192.168.1.0/24 -> 0/32
Możemy teraz załadować nasze reguły do ipnat i połączyć się
ze światem zewnętrznym bez konieczności edytowania
czegokolwiek. Musisz jednak uruchomić `ipf -y
' by
odświeżyć adres przypisany połaczeniu jeśli się rozłączysz i
wdzwonisz ponownie, lub gdy wygaśnie Twoja dzierżawa na adres
przydzielony przez DHCP.
Niektórzy z was mogą się zastanawiać, co dzieje się z
portem źródłowym gdy wykonywane jest mapowanie. W przypadku
naszej reguły, port źródłowy pakietu nie zostaje zmieniony w
stosunku do oryginału. Są jednak przypadki gdy nie chcemy by
tak się działo - może po drodze jest jeszcze jedna ściana
ogniowa, lub wiele maszyn próbuje używać tego samego portu.
Może to powodować kolizje i pakiet jest przepuszczany bez
mapowania. ipnat pomaga w tym momencie, poprzez dostarczenie
słowa kluczowego `portmap
':
map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
Nasza reguła wrzuca wszystkie mapowane połączenia ( które
mogą używać protokołu tcp, udp lub jednocześnie tcp/udp ) w
zakres portów od numeru 20000 do 30000.
Możemy jeszcze ułatwić sobie życie, używając polecenia
`auto
' by poinformować ipnat by sam określił
sobie jakich portów może użyć i zaalokował je proporcjonalnie
wśród adresów, używanych w puli:
map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto
Pamiętaj, że reguły mapujące odnoszą się tylko do
protokołów, które określiłeś ( np. tcp, udp lub tcp/udp ), i
nie odnoszą się do innych, takich jak ICMP czy IPsec ESP/AH.
Dla nich, musisz dodać dodatkowe mapowania odnoszące się do
wszystkich innych protokołów:
map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
map tun0 192.168.1.0/24 -> 0/32
4.2 Mapowanie wielu adresów w
przydzieloną pulę adresów
Innym częstym zastosowaniem NAT jest wzięcie małej,
statycznie przydzielonej puli adresów i zmapowanie wielu
komputerów w tą mniejszą przestrzeń adresową. Jest to proste
do uzyskania przy użyciu tego co już wiesz o słowach
kluczowych `map
' i `portmap
'.
Zapiszmy to jak poniżej:
map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000
Zdarza się również, że zdalna aplikacja wymaga, by
wszystkie połączenia przychodziły z tego samego IP. Możemy
pomóc, instruując NAT by statycznie zmapował sesje z danej
maszyny na pulę adresów i wykonał trochę magii z wybraniem
portu. Robi się to, stosując słowo kluczowe
`map-block
', tak jak poniżej:
map-block tun0 192.168.1.0/24 -> 20.20.20.0/24
Tak jak słowo `map
', `map-block
'
ma również swoją wersję `portmap
'. Używa się jej
albo ze słowem kluczowym `auto
':
map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 auto
lub ze słowem `ports
', jeśli chcesz wskazać
konkretne numery portów należące do określonych adresów
IP:
map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 ports 64
4.3 Mapowania jeden do jednego
Czasami zdarza się, że chcemy by komputer za ścianą ogniową
z danym IP pojawiał się z innym IP. Jednym z takich przykładów
może być labolatorium komputerowe, dołączone do różnych sieci,
a mające wziąć udział w testach. Nie chcemy rekonfigurować
całego labolatorium, ponieważ możemy postawić przed nim
komputer wykonujący NAT i zmienić adresy w jednym miejscu.
Można to wykonać za pomocą słowa kluczowego
`bimap
', od mapowania dwukierunkowego. Bimap
posiada pewne dodatkowe zabezpieczenia zapewniające, że wie
jaki jest stan połączenia, podczas gdy słowo
`map
' używane jest tylko do zaalokowania adresu i
portu źródłowego oraz odpowiedniej modyfikacji pakietu.
bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
spowoduje zmapowanie dla jednej maszyny.
4.4 NAT według Zasad
Często zdarza się, że musimy zapewnić funkcjonowanie NATu
zależne od adresów źródłowych i przeznaczenia. Na przykład,
chcemy prowadzić NAT dla wszystkich, oprócz określonej
podsieci:
map tun0 from 192.168.1.0/24 ! to 5.0.0.0/20 -> 20.20.20.1/32
Można również zastosować taką konstrukcję:
map tun0 from 192.168.1.5/32 port = 5555 to 1.2.3.4/32 -> 20.20.20.2/32
map tun0 from 192.168.1.0/24 to 5.0.0.0/20 -> 20.20.20.2/32 portmap auto
4.5 Usługi fałszujące
A co to ma do rzeczy? Wiele. Powiedzmy że mamy serwer WWW
pracujący na 20.20.20.5
, a ponieważ staliśmy się
ostatnio bardzo podejrzliwi co do bezpieczeństwa naszej sieci,
chcemy by serwer nie pracował na porcie 80, ponieważ wymaga to
krótkiego momentu pracy z przywilejami roota. Ale jak
uruchomić go na mniej uprzywilejowanym porcie 8000 w świecie
'wszystko kropka com'? Jak ktokolwiek znajdzie nasz serwer?
Możemy użyć usług przekierowania NATu by rozwiązać ten
problem, instruując go by przemapował wszystkie połączenia
przeznaczone dla 20.20.20.5:80
na
20.20.20.5:8000
. Używa się do tego słowa
kluczowego `rdr
':
rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
Możemy również podać protokół, jeśli chcielibyśmy na
przykład przekierować usługę UDP zamiast TCP ( która jest
domyślna ). Na przykład, gdybyśmy chcieli zastawić zasadzkę na
naszej ścianie ogniowej i udawać zainstalowanego Back Orifice
dla Windows, możemy ochronić naszą sieć przez prostą
regułę:
rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
Możliwe jest modyfikowanie zachowania słowa
`rdr
' w zależności od adresów źródłowego i
docelowego:
rdr tun0 from 10.1.1.1/32 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8001
rdr tun0 from 10.1.1.1/32 port = 12345 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8002
Należy jednak zaznaczyć bardzo ważną sprawę. Nie możesz
łatwo użyć tego jako lustra, tzn.:
rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
Taka konstrukcja nie zadziała, jeśli .5 i .6 są w tym samym
segmencie LAN. Funkcja `rdr
' jest wykonywana na
każdym pakiecie, który trafia do ściany ogniowej na określonym
interfejsie. Gdy nadchodzi pakiet który pasuje do reguły, jego
adres docelowy jest zmieniany, pakiet trafia do ipf w celu
przefiltrowania i gdy tylko przetrwa boje z regułami filtra,
jest wysyłany do kodu routującego Uniksa. Ponieważ pakiet
pochodzi z tego samego interfejsu, którym będzie musiał
opuścić system by dotrzeć do maszyny docelowej, system jest w
kropce. Lustra po prostu nie działają. Nie działa również
podawanie adresu interfejsu z którego pakiet właśnie nadszedł.
Pamiętaj że adresy docelowe dla `rdr
' muszą
istnieć po drugiej stronie ściany ogniowej, w sieci do której
prowadzi inny interfejs niż ten, którym wszedł pakiet
pierwotny.
4.6 Transparentne proxy; W
końcu przekierowanie do czegoś się przydaje.
Ponieważ właśnie instalujesz ścianę ogniową możesz
zdecydować, że jest to dobry moment na zastosowanie proxy dla
wielu wychodzących połączeń. Dzięki temu możesz jeszcze
bardziej zacieśnić swoje reguły filtrowania chroniące sieć.
Może się również zdarzyć tak, że natrafisz na sytuację, której
proces mapowania NAT nie może aktualnie poprawnie obsłużyć.
Taką sytuację można obejść następującą konstrukcją:
rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
Ten wpis mówi, że każdy pakiet z interfejsu
xl0
przeznaczony dla dowolnego adresu (
0.0.0.0
) na port ftp, zostanie przepisany tak by
połączyć się z proxy, które pracuje na systemie wykonującym
NAT na porcie 21.
Ten specyficzny przykład proxy FTP prowadzi do pewnych
komplikacji, kiedy chodzi o serwery WWW czy inne automatycznie
logujące się klienty, które nie wiedzą o wymaganiach
komunikacji z proxy. Istnieją łaty dla ftp-gw z TIS Firewall
Toolkit które w połączeniu z procesem NAT pozwalają na
zapewnienie funkcjonalności, dzięki której można sprawdzić
gdzie chciałeś wejść i wysłać cię tam automatycznie. Wiele
paczek proxy pracuje obecnie również w środowisku
transparentnego proxy ( na przykład Squid, znajdujący się pod
adresem http://squid.nlanr.net/,
pracuje w porządku ).
Takie zastosowanie słowa kluczowego `rdr
' jest
często użyteczne gdy chcesz zmusić użytkowników do
autoryzowania się na proxy ( na przykład, gdy chcesz by twoi
inżynierowie mogli przeglądać strony WWW, ale wolałbyś żeby
raczej ludzie z call-center tego nie robili ).
4.7 Filtrowanie przekierowanych usług
Wielu użytkowników chce połączyć filtrowanie i translację
adresów, by zapewnić usługi tylko określonym komputerom za ich
ścianą ogniową. Na przykład, by zapewnić dostęp do serwera WWW
za twoją maszyną 20.20.20.5
( która tak naprawdę
ma adres 192.168.0.5
w sieci wewnętrznej )
Twojemu przyjacielowi który ma adres 172.16.8.2
,
możesz wpisać następujący wiersz do
ipnat.rules
:
rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
a następujący wiersz do ipf.rules
:
pass in on tun0 proto tcp from 172.16.8.2/32 to 192.168.0.5/32 port = 8000 flags S keep state
Na pierwszy rzut oka może to wyglądać trochę dziwnie, ale
dlatego że NAT odbywa się pierwszy, a w jego trakcie adres
docelowy i port docelowy jest przepisywany zanim zajmie się
nim kod filtrujący pakietu.
4.8 Magia ukryta w NAT; proxy aplikacji
Ponieważ ipnat dostarcza metody na przepisywanie pakietów w
trakcie ich podróży przez ścianę ogniową, staje się wygodnym
miejscem do wbudowania proxy poziomu aplikacji, zbudowanej
pomiędzy tą aplikacją a ścianą ogniową. Na przykład: FTP.
Możemy kazać naszej ścianie ogniowej sprawdzać pakiety, które
przez nią przechodzą i gdy zauważy, że ma do czynienia z
aktywną sesją FTP, dopisze sobie pewne tymczasowe reguły.
Dzieje się to trochę na wzór keep state
i
sprawia, że połączenie FTP będzie działało. Realizujemy to
reguła podobną do tej:
map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
Musisz pamiętać by umieścić wyrażenie `proxy
'
przed jakimikolwiek regułami `portmap
', ponieważ
w innym przypadku `portmap
' wykona przepisanie
pakietu zanim `proxy
' będzie miało szansę na
zajęcie się nim. Pamiętaj, że reguły ipnat działają na
zasadzie pierwszy pasujący. Istnieją również proxy dla
rcmd
( które, jak sądzimy, są berkeley'owskimi
komendami r-*
, i i tak powinny być zabronione,
więc nie przyglądaliśmy im się ), oraz raudio
dla
strumieni Real Audio PNM. W każdym bądź razie obydwa proxy
powinny zostać ustawione przed jakimikolwiek regułami
`portmap
', jeśli zamierzasz robić NAT.
4.9 Jeszcze więcej magii; NAT jako równoważenie
obciążenia
Jeśli ipnat i tak już przepisuje nam pakiety, możemy użyć
go do obsługi prostszych właściwości drogich urządzeń
równoważących obciążenie. Będzie przypisywał mapowaniom wiele
adresów docelowych - uzyskamy to stosując słowo kluczowe
`round-robin
':
rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5, 192.168.0.6, 192.168.0.7 port 8000
5. Ładowanie i manipulowanie regułami
filtra; Narzędzie ipf
Reguły Filtra IP ładowane są przez narzędzie
ipf
. Reguły można przechować w dowolnym pliku,
ale normalnie stosuje się pliki /etc/ipf.rules
,
/usr/local/etc/ipf.rules
lub
/etc/opt/ipf/ipf.rules
.
Filtr IP ma dwa zestawy reguł, zestaw aktywny i nieaktywny.
Domyślnie, wszystkie operacje przeprowadzane są na zestawie
aktywnym. Możesz pracować na zestawie nieaktywnym przez
dodanie `-I
' do linii poleceń ipf
.
Zestawy zamienia się miejscami przez użycie opcji
`-s
'. Jest to bardzo przydatne podczas testowania
nowych zestawów reguł, bez usuwania starego zestawu.
Reguły można również usuwać z listy, stosując opcję
`-r
', ale generalnie bezpieczniejsze jest po
prostu usunąć cały zestaw reguł nad którym pracujesz przy
użyciu opcji `-F
' i załadować go po wykonaniu
zmian.
Podsumowując, najłatwiejszym sposobem by załadować zestaw
reguł jest użycie polecenia `ipf -Fa -f
/etc/ipf.rules
'. Jeśli chodzi o bardziej skomplikowane
manipulowanie zestawami reguł, sprawdź stronę podręcznika
ipf(1)
.
6. Ładowanie i
manipulowanie regułami NAT; narzędzie ipnat
Reguły NAT ładowane są przez narzędzie ipnat
.
Reguły NAT można przechowywać w dowolnym pliku, ale normalnie
stosuje się pliki `/etc/ipnat.rules
',
`/usr/local/etc/ipnat.rules
' lub
`/etc/opt/ipf/ipnat.rules
'.
Reguły można również usuwać z listy, stosując opcję
`-r
', ale generalnie bezpieczniejsze jest po
prostu usunąć cały zestaw reguł nad którym pracujesz przy
użyciu opcji `-C
' i załadować go po wykonaniu
zmian. Żadne aktywne mapowania nie są usuwane przy użyciu
`-C
', ale można je usunąć poleceniem
`-F
'.
Reguły NAT i aktualne mapowania można sprawdzić używając
opcji `-l
'.
Podsumowując, najłatwiejszym sposobem by załadować zestaw
reguł jest użycie polecenia `ipnat -CF -f
/etc/ipnat.rules
'.
7. Monitoring i
odpluskwianie
Przyjdzie kiedyś moment, że zainteresujesz się tym, co tak
naprawdę robi Twoja ściana ogniowa, a ipfilter byłby
niekompletny bez pełnego zestawu narzędzi
monitorujących.
7.1 Narzędzie ipfstat
W swojej najprostszej formie, ipfstat
wyświetla tabelę interesujących danych dotyczących tego, jak
Twoja ściana ogniowa daje sobię radę, czyli między innymi
ilość pakietów które zostały przepuszczone i zablokowane, czy
zostały zalogowane czy nie, ile jest aktywnych pozycji w
liście stanów i tak dalej. Poniżej przykład czegoś, co mógłbyś
zobaczyć po uruchomieniu tego narzędzia:
# ipfstat
input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
input packets logged: blocked 99286 passed 0
output packets logged: blocked 0 passed 0
packets logged: input 0 output 0
log failures: input 3898 output 0
fragment state(in): kept 0 lost 0
fragment state(out): kept 0 lost 0
packet state(in): kept 169364 lost 0
packet state(out): kept 431395 lost 0
ICMP replies: 0 TCP RSTs sent: 0
Result cache hits(in): 1215208 (out): 1098963
IN Pullups succeeded: 2 failed: 0
OUT Pullups succeeded: 0 failed: 0
Fastroute successes: 0 failures: 0
TCP cksum fails(in): 0 (out): 0
Packet log flags set: (0)
none
Jest również w stanie pokazać aktualną listę reguł. Użycie
flagi `-i
' lub `-o
' pokaże listę
reguł dla odpowiednio pakietów wchodzących i wychodzących.
Dodanie opcji `-h
' doda trochę użytecznych
informacji, podając również 'licznik trafień' dla każdej
reguły. Na przykład:
# ipfstat -ho
2451423 pass out on xl0 from any to any
354727 block out on ppp0 from any to any
430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
Z przykładu powyżej widać, że prawdopodobnie dzieje się coś
nienormalnego, ponieważ mamy bardzo dużo zablokowanych
pakietów wychodzących, nawet przy użyciu reguły `pass
out
'. Coś może wymagać tutaj dalszego zainteresowania,
albo po prostu pracuje bez zarzutu. ipfstat
nie
może powiedzieć Ci czy Twoje reguły są dobre czy złe, może
tylko poinformować co dzieje się przy ich użyciu.
W dalszym procesie odpluskwiania reguł, możesz zechcieć
użyć opcji `-n
' która pokaże numery reguł przy
każdej z nich:
# ipfstat -on
@1 pass out on xl0 from any to any
@2 block out on ppp0 from any to any
@3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
Ostatnią naprawdę interesującą informacją w
ipfstat
, jest zrzut tabeli stanów. Wykonuje się
to dodając opcję `-s
':
# ipfstat -s
281458 TCP
319349 UDP
0 ICMP
19780145 hits
5723648 misses
0 maximum
0 no memory
1 active
319349 expired
281419 closed
100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
pkts 196 bytes 17394 987 -> 22 585538471:2213225493 16592:16500
pass in log quick keep state
pkt_flags & b = 2, pkt_options & ffffffff = 0
pkt_security & ffff = 0, pkt_auth & ffff = 0
Widzimy, że mamy aktualnie jedno połączenie TCP. Dane
wyjściowe będą się delikatnie różnić od wersji do wersji, ale
generalnie informacje są te same. Widzimy dla tego połączenia,
że jest ono w pełni nawiązane ( state 4/4
na
końcu linijki, inne stany są niekompletne i opiszemy je
później ). Możemy również odczytać że wpis ten ma czas
życia ( ang. time to live ) 240 godzin, co jest
absurdalnie długim czasem, ale ustawianym domyślnie dla
nawiązanej sesji TCP. Licznik ten jest zmniejszany z każdą
sekundą bezczynności, aż w końcu połączenie zostanie zerwane
jeśli zostanie pozostawione bezczynnie. Licznik jest również
zerowany na wartość 864000 za każdym razem, gdy użyjemy wpisu,
więc połączenie nie zostanie zamknięte w trakcie jego
używania. Możemy również odczytać, że przepuściliśmy przez to
połączenie 196 pakietów składających się na około 17kB danych.
Oprócz tego można odczytać porty po obu stronach - 987 i 22,
co oznacza że ten wpis symbolizuje połączeniu z adresu
100.100.100.1
portu 987
na adres
20.20.20.1
na port 22
. Bardzo duże
numery w drugiej linijce to numery sekwencyjne TCP
wygenerowane dla tego połączenia, pomagające zabezpieczyć je
przed wpuszczeniem dodatkowych, spreparowanych pakietów.
Pokazane jest również okno TCP. Trzecia linia stanowi wynik
reguły która została wygenerowana przez regułę keep
state
i pokazuje ona że jest to połączenie
przychodzące.
Czytaj
dalej >>>