[OpenBSD]

[Wstecz: Tabele] [Spis treści] [Dalej: Translacje adresów (NAT)]

PF: Filtrowanie pakietów


Spis treści


Wstęp

Filtrowanie pakietów to selektywne przepuszczanie lub blokowanie pakietów przechodzących przez interfejs sieciowy. Kryteria, którymi kieruje się pf(4) podczas sprawdzania pakietów, są oparte o Warstwę 3 (IPv4 i IPv6) oraz Warstwę 4 nagłówków (TCP, UDP, ICMP, i ICMPv6). Najczęstszym kryterium jest źródłowy i docelowy adres, źródłowy i docelowy port, oraz protokół.

Reguły filtrujące określają kryteria według których podejmowana jest konkretna akcja wobec pakietu: przepuść (ang. pass) lub blokuj (ang. block). Reguły filtrujące są porównywane sekwencyjnie, od pierwszej do ostatniej. Z wyjątkiem sytuacji, gdy pakiet pasuje do reguły ze słowem kluczowym quick, pakiety są porównywane z wszystkimi regułami filtrującymi zanim ostateczna akcja zostanie podjęta. Ostatnia pasująca reguła jest "zwycięzcą" i decyduje o podjętej akcji. Jeśli na początku zestawu reguł znajduje się bezwarunkowe pass all, wówczas wszystkie pakiety, które nie pasowały do żadnej z reguł, będą przepuszczane zgodnie z akcją pass.

Składnia reguł

Ogólna, bardzo uproszczona składnia reguł filtrujących wygląda następująco:
action [direction] [log] [quick] [on interface] [af] [proto protocol] \
   [from src_addr [port src_port]] [to dst_addr [port dst_port]] \
   [flags tcp_flags] [state]
action
Akcja, która ma być podejmowana wobec pasujących pakietów, albo pass albo block. Akcja pass przepuszcza pakiety z powrotem do jądra systemu do dalszego przetwarzania, podczas gdy akcja block podejmuje działanie zgodne z ustawieniem opcji domyślnej polityki blokowania block-policy. Domyślna akcja może być jawnie zmieniona poprzez podanie słów kluczowych block drop lub block return.
direction
Kierunek, w którym dany pakiet zmierza na interfejsie sieciowym, albo in (poł. wchodzi) albo out (poł. wychodzi).
log
Określa, że dany pakiet powinien być zapisany w logach przez pflogd(8). Jeżeli reguła tworzy stan wówczas jedynie pakiet który rozpoczyna połączenie stanowe jest odnotowywany w logach. Aby bezwzględnie zapisywać w logach wszystkie pakiety, należy zastosować opcję log (all).
quick
Jeśli pakiet pasuje do reguły ze słowem kluczowym quick, wówczas reguła ta jest uznawana za ostatnią pasującą i podejmowana jest odpowiednia akcja action.
interface
Nazwa interfejsu sieciowego, lub grupa takich urządzeń, przez który przechodzi pakiet. Interfejsy mogą być dodane do bezwzględnych grup przy pomocy polecenia ifconfig(8). Kilka grup jest automatycznie tworzona przez kernel: Powoduje, że reguła będzie pasować do dowolnego pakietu przechodzącego przez odpowiednio, interfejs ppp lub carp.
af
Rodzina adresów: inet dla IPv4 lub inet6 dla IPv6. PF jest zwykle w stanie zidentyfikować ten parametr na podstawie adresu(ów) źródłowych/przeznaczenia.
protocol
Protokół Warstwy 4 pakietu:
src_addr, dst_addr
Adres źródłowy/docelowy w nagłówku IP. Adres może być podany jako:
src_port, dst_port
Port źródłowy/docelowy w Warstwie 4 nagłówka pakietu. Porty mogą być podawane jako:
tcp_flags
Określa flagi, które muszą być ustawione w nagłówku TCP gdy używamy proto tcp. Są one podawane w postaci: flags check/mask. Na przykład: flags S/SA - PF bierze pod uwagę jedynie flagi S i A (SYN i ACK), a reguła jest dopasowana jeśli tylko flaga SYN jest ustawiona. W OpenBSD 4.1 i późniejszych, flagi S/SA są domyślnie dołączane do wszystkich reguł TCP.
state
Określa, czy informacje o stanie połączenia są przechowywane, gdy pakiety są dopasowywane do tej reguły.

Domyślne blokowanie

Zaleca się przyjmować domyślną politykę blokowania wszystkiego ("default deny"), a jedynie selektywne przepuszczanie konkretnego ruchu. Takie podejście zalecane jest nie tylko ze względów bezpieczeństwa, ale sprawia, że pisanie zestawu reguł jest znacznie prostsze.

Aby wprowadzić domyślną politykę blokowania pierwsze dwie reguły powinny wyglądać tak:

block in  all
block out all

Spowoduje to blokowanie całego ruchu na wszystkich interfejsach w obu kierunkach.

Przepuszczanie ruchu

Ruch musi być precyzyjnie przepuszczany przez firewall albo będzie zatrzymany przez domyślną politykę blokowania. W tym miejscu do akcji wchodzą kryteria takie jak port źródłowy/docelowy, adres źródłowy/docelowy oraz protokół. Jeśli jakiś ruch ma być przepuszczany przez firewall, to reguły powinny być napisane tak restrykcyjnie jak to tylko możliwe. Ma to zapewnić przepuszczanie pożądanego i tylko pożądanego ruchu.

Kilka przykładów:

# Przepuść ruch na dc0 z sieci lokalnej, 192.168.0.0/24,
# zmierzający do 192.168.0.1. Przepuść także cały powracający
# do tej sieci ruch na dc0.
pass in  on dc0 from 192.168.0.0/24 to 192.168.0.1
pass out on dc0 from 192.168.0.1 to 192.168.0.0/24


# Przepuść ruch TCP z zewnątrz na fxp0 zmierzający do serwera www.
# Nazwa interfejsu, fxp0, jest użyta jako adres docelowy, więc
# pakiety będą pasować do tej reguły jedynie jeśli są przeznaczone
# dla tej maszyny OpenBSD.
pass in on fxp0 proto tcp from any to fxp0 port www

Słowo kluczowe quick

Jak już zostało to wcześniej napisane, każdy pakiet jest porównywany z całym zestawem reguł od góry do dołu. Domyślnie, pakiet po porównaniu jest przekazywany do kolejnej reguły, i dlatego może być wielokrotnie zmieniany jego status, zanim osiągnie koniec zestawu reguł. "Ostatnia pasująca reguła wygrywa". Jest od tego wyjątek: opcja quick w regule filtrującej skutkuje przerwaniem dalszego porównania i powoduje podjęcie akcji z obecnej reguły. Oto kilka przykładów:

Źle:

block in on fxp0 proto tcp from any to any port ssh
pass  in all

W tym przypadku, linia block może być porównywana, ale nigdy nie będzie miała żadnego efektu, ponieważ po niej znajduje się linia, która wszystko przepuszcza.

Lepiej:

block in quick on fxp0 proto tcp from any to any port ssh
pass  in all

Te reguły są porównywane nieco inaczej. Jeśli linia block pasuje, dzięki opcji quick, pakiet będzie zablokowany, a reszta reguł tego zestawu będzie zignorowana.

Śledzenie stanów

Jedną z ważnych możliwości Packet Filter jest śledzenie stanów (ang. keeping state) lub kontrolowanie stanów (ang. stateful inspection). Kontrolowanie stanów odnosi się do zdolności PF do śledzenia stanu, lub przebiegu, połączenia sieciowego. Poprzez przechowywanie informacji o każdym połączeniu w tabeli stanów, PF jest w stanie szybko określić, czy pakiet przechodzący przez firewall należy do już nawiązanego połączenia. Jeśli tak jest, pakiet jest przepuszczany bez przechodzenia zestawu reguł.

Śledzenie stanów ma wiele zalet, włączając uproszczenie zestawu reguł i lepszą wydajność filtrowania pakietów. PF jest w stanie dopasowywać pakiety poruszające się w obu kierunkach danego połączenia, co oznacza, że reguły przepuszczające powracający ruch nie są potrzebne. A ponieważ pakiety pasujące do połączenia stanowego nie przechodzą zestawu reguł, czas zużywany na przetwarzanie tych pakietów może być bardzo znacząco zmniejszony.

Gdy reguła tworzy stan, pierwszy pakiet pasujący do niej tworzy "połączenie stanowe" pomiędzy nadawcą i odbiorcą. Wówczas, nie tylko pakiety pochodzące od nadawcy, zmierzające do odbiorcy, ale i pakiety odbiorcy, skierowane do nadawcy pasują do reguły i nie są sprawdzane przez zestaw reguł filtrujących.

Począwszy od OpenBSD 4.1, wszystkie reguły automatycznie tworzą stany w tabeli stanów gdy pakiet pasuje do danej reguły. We wcześniejszych wersjach OpenBSD reguła filtra musiała zawierać opcję keep state.

Przykładowo, korzystając z OpenBSD 4.1 i późniejszych:

pass out on fxp0 proto tcp from any to any

Dla OpenBSD 4.0 i wcześniejszych natomiast:

pass out on fxp0 proto tcp from any to any keep state

Reguły te zezwalają na wychodzenie ruchu TCP na interfejsie fxp0 i przepuszczają ruch powrotny pakietów stanowiących odpowiedź. Śledzenie stanów poza swoją funkcjonalnością, zapewnia także znaczący wzrost wydajności firewalla, ponieważ wyszukania stanów są dużo szybsze niż porównywanie pakietu z zestawem reguł filtrujących.

Opcja modulate state działa podobnie do keep state z tą różnicą, że odnosi się jedynie do pakietów TCP. Przy użyciu modulate state, Inicjujący Numer Sekwencyjny (ISN) wychodzącego połączenia jest losowy. Jest to przydatne do ochrony połączeń nawiązanych przez różne systemy operacyjne, które nie najlepiej radzą sobie z generowaniem numeru ISN. Począwszy od OpenBSD 3.5, opcja modulate state może być używana w regułach, które odnoszą się także do innych niż TCP protokołów.

Śledź stan wychodzących pakietów TCP, UDP i ICMP oraz generuj ISN dla TCP:

pass out on fxp0 proto { tcp, udp, icmp } from any \
    to any modulate state

Inną zaletą śledzenia stanów jest to, iż odpowiedni ruch ICMP będzie przepuszczany przez firewall. Na przykład, jeśli połączenie TCP przechodzi przez firewall, jest ono śledzone stanowo i w momencie gdy nadejdzie komunikat ICMP "gaszący źródło" (ang. source-quench) odwołujący się do tego połączenia, będzie on dopasowany do odpowiedniego wpisu stanowego i przepuszczony przez firewall.

Zakres (ang. scope) wpisów w tabeli stanów jest globalnie kontrolowany poprzez opcje czasu wykonywania state-policy, niemniej można go określić dla poszczególnych reguł indywidualnie poprzez słowa kluczowe reguł śledzenia stanów: if-bound, group-bound i floating. Słowa kluczowe użyte dla pojedynczej reguły mają to samo znaczenie co w przypadku globalnej polityki stanów state-policy. Przykład:

pass out on fxp0 proto { tcp, udp, icmp } from any \
    to any modulate state (if-bound)

Reguła ta narzuca wymóg, aby pakiety które pasują do tej reguły były przekazywane przez interfejs fxp0.

Proszę zwrócić uwagę, że reguły nat, binat, i rdr bezwarunkowo tworzą stan dla pasujących połączeń tak długo, jak dane połączenie jest przekierowywane przez daną regułę.

Śledzenie stanów dla UDP

Każdy od czasu do czasu słyszy opinie, że "nie można utworzyć stanu z UDP, ponieważ UDP jest bezstanowym protokołem!". Mimo iż jest prawdą, że sesje komunikacyjne UDP nie mają żadnej formy stanu (formalnego rozpoczęcia i zakończenia komunikacji), nie ma to żadnego wpływu na zdolność PF do tworzenia stanowych sesji UDP. W tym przypadku protokołów bez pakietów "inicjujących" i "kończących" połączenie, PF po prostu śledzi ile czasu upłynęło odkąd pasujący pakiet został przepuszczony. Jeśli czas przekroczy ustaloną wartość, wpis stanu jest usuwany. Czas "przeterminowania" może być dostrojony w sekcji opcje pliku pf.conf.

Opcje dla śledzenia stanów

Reguły tworzące wpisy w tabeli stanów mogą posiadać różne opcje kontrolujące zachowanie stanu.
max number
Ogranicza liczbę stanów jakie dana reguła może utworzyć do maksymalnej wartości ustalonej przez number. Jeżeli to maksimum zostało osiągnięte, pakiety które normalnie tworzyły by stan, nie będą pasowały do tej reguły aż do czasu gdy liczba istniejących stanów spadnie poniżej tego limitu.
no state
zapobiega przed utworzeniem wpisu stanu.
source-track
Opcja ta włącza śledzenie liczby utworzonych stanów dla każdego źródłowego adresu IP. Opcja ta posiada dwa formaty: Całkowita liczba źródłowych adresów IP śledzonych globalnie, może być kontrolowana poprzez opcję startową src-nodes.
max-src-nodes number
Kiedy korzystamy z opcji source-track, parametr max-src-nodes będzie ograniczał liczbę źródłowych adresów IP, które mogą jednocześnie generować stan. Opcja ta może być użyta tylko w połączeniu z source-track rule.
max-src-states number
Kiedy wykorzystywana jest opcja source-track, max-src-states będzie ograniczało liczbę jednoczesnych wpisów w tabeli stanów które mogą być utworzone przez pojedyńczy źródłowy adres IP. Zakres tego limitu (tj. stany utworzone tylko przez tą regułę lub stany utworzone przez wszystkie reguły które korzystają z source-track) jest zależny od użycia opcji source-track.

Opcje podawane są w nawiasach, zaraz po użyciu jednego ze słów kluczowych (keep state, modulate state, or synproxy state). Opcje oddzielone są przecinkami. W OpenBSD 4.1 i późniejszych, opcja keep state, jest wstawiana domyślnie do wszystkich reguł filtra. Pomimo tego, używając opcji dla filtrowania stanowego, konieczne jest użycie jednego ze słów kluczowych przed określonymi opcjami.

Przykład:

pass in on $ext_if proto tcp to $web_server \
    port www keep state \
    (max 200, source-track rule, max-src-nodes 100, max-src-states 3)

Powyższy przykład powoduje:

Dodatkowe ograniczenia mogą być ustawione dla śledzenia połączeń TCP dla których zakończyła się negocjacja protokołu.

max-src-conn number
Ogranicza maksymalna liczbę jednoczesnych połączeń TCP, które zakończyły negocjację połączenia, dla pojedyńczego hosta.
max-src-conn-rate number / interval
Ogranicza tempo powstawania nowych połączeń do konkretnej wartości w jednostce czasu (interval).

Każda z tych opcji automatycznie przywołuje opcję source-track rule, oraz jest niekompatybilna z source-track global.

Ponieważ opcje te dotyczą tylko połączeń TCP które zakończyły negocjację, bardziej agresywne zachowania mogą być użyte dla przestępczego adresu IP.

overload <tablica>
Umieści adres IP przestępczego hosta w tablicy.
flush [global]
Zabije wszystkie stany pasujące do tej reguły i utworzone przez ten adres IP. Kiedy podane jest global, zostaną zabite wszystkie stany pasujące do tego źródłowego adresu IP, niezależnie od tego jaka reguła utworzyła stan.

Przykład:

table <abusive_hosts> persist
block in quick from <abusive_hosts>

pass in on $ext_if proto tcp to $web_server \
    port www flags S/SA keep state \
    (max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush)

Powyższe reguły wykonują:

Flagi TCP

Dopasowanie pakietów TCP na podstawie flag jest najczęściej wykorzystywane przy filtrowaniu pakietów, które otwierają nowe połączenie. Flagi TCP i ich nazwy są podane poniżej:

Aby PF sprawdzał flagi TCP podczas przetwarzania reguł filtrujących wykorzystywane jest słowo kluczowe flags. Jego składnia jest następująca:

flags check/mask
flags any

Część mask mówi PF aby sprawdzać jedynie podane flagi, a część check określa która flaga(i) powinny być "ustawione" w nagłówku, aby dopasowanie miało miejsce. Użycie klucza any zezwala na ustawienie dowolnej kombinacji flag w nagłówku.

pass in on fxp0 proto tcp from any to any port ssh flags S/SA

Powyższa reguła przepuszcza ruch TCP z ustawioną jedynie flagą SYN, biorąc pod uwagę tylko flagi SYN i ACK. Pakiet z flagami SYN i ECE będzie pasował do powyższej reguły, jednak pakiet z SYN i ACK lub tylko ACK już nie.

W OpenBSD 4.1 i późniejszych, domyślne flagi stosowane od reguł TCP to flags S/SA. W połączeniu z domyślnym dla OpenBSD 4.1 zachowaniem keep state w regułach filtra, poniższe dwie linie są równoważne:

pass out on fxp0 proto tcp all flags S/SA keep state
pass out on fxp0 proto tcp all

Każda reguła do której pasuje pakiet TCP z ustawiona flagą SYN i wygaszona flagą ACK utworzy odpowiedni stan. Domyślne zachowanie może być zmienione poprzez użycie opcji flags, jak to zostało pokazane wcześniej.

W OpenBSD 4.0 i wcześniejszych flagi domyślne nie były stosowane w regułach filtra. Każda reguła musiała mieć określone pasujące flagi oraz bezpośrednio użytą opcję keep state.

pass out on fxp0 proto tcp all flags S/SA keep state

Przy korzystaniu z flag trzeba być bardzo ostrożnym - należy rozumieć co się robi i dlaczego, no i należy uważać na rady innych, ponieważ często są one błędne. Niektórzy np. sugerują tworzenie stanu "jedynie gdy flaga SYN jest ustawiona, i żadna inna". Taka reguł wyglądała by tak:

     . . . flags S/FSRPAUEW  to zły pomysł!!

W teorii, tworzy się połączenie stanowe na początku sesji TCP, a sesja powinna rozpocząć się od flagi SYN, i żadnej innej. Problem polega na tym, że niektórzy użytkownicy rozpoczynają połączenia wraz z flagą ECN, i będą odrzuceni przez taką regułę. Dużo lepszą praktyką jest nie określanie żadnych flag i pozwolenie PF-owi by zastosował domyślne flagi do twoich reguł. Jeśli naprawde chcesz sam określić swoje flagi poniższa kombinacja powinna być bezpieczna:

. . . flags S/SAFR

Jest to praktyczne i bezpieczne. Jeśli ruch podlega normalizacji scrub, wówczas można nie sprawdzać także flag FIN i RST. Normalizacja powoduje, że PF porzuca nadchodzące pakiety z nieprawidłową kombinacja flag (taką jak SYN i FIN lub SYN i RST) a także normalizuje potencjalnie niejasne kombinacje (takie jak SYN i FIN).

TCP SYN Proxy

Domyślnie gdy klient nawiązuje połączenie TCP z serwerem PF przepuszcza pakiety związane z "potrójnym uzgodnieniem" (ang. handshake) pomiędzy dwoma uczestniczącymi końcami gdy tylko nadejdą. PF ma jednak zdolność do pośredniczenia (ang. to proxy) w "potrójnym uzgodnieniu". Dzięki temu, to PF dokona poprawnego "potrójnego uzgodnienia" z klientem, następnie zainicjuje "potrójne uzgodnienie" z serwerem i dopiero wtedy zacznie przekazywać pakiety pomiędzy oboma węzłami. Najważniejszą korzyścią tego procesu jest to, iż żaden pakiet nie zostanie wysłany do serwera zanim klient nie dokona poprawnego "potrójnego uzgodnienia". Eliminuje to zagrożenie ataków typu "TCP SYN flood" na serwer danej usługi.

"TCP SYN proxy" jest uruchamiane przy pomocy słów kluczowych synproxy state w regułach filtrujących. Na przykład:

pass in on $ext_if proto tcp from any to $web_server port www \
   flags S/SA synproxy state

Tu, połączenia do serwera WWW będą nawiązywanie za pośrednictwem "TCP SYN proxy" przez PF.

Ze względu na swoje działanie, synproxy state zawiera funkcjonalności keep state i modulate state.

"SYN proxy" nie będzie działać jeśli PF jest uruchomiony na moście (ang. bridge(4)).

Blokowanie sfałszowanych pakietów

Fałszowaniem (ang. spoof) określa się zmianę adresu źródłowego pakietu mające na celu albo ukrycie prawdziwego pochodzenia datagramu, albo podszycie się pod inny segment sieci. Gdy użytkownik pomyślnie podszyje się pod inny adres, może rozpocząć sieciowy atak bez ujawniania jego prawdziwego źródła lub spróbować uzyskać kontrolę nad usługami, które są dostępne dla wąskiej grupy konkretnych adresów IP.

PF oferuje pewną ochronę przed podszywaniem się pod inne adresy poprzez słowo kluczowe antispoof:

antispoof [log] [quick] for interface [af]
log
Określa, że pasujące pakiety powinny być logowane przez pflogd(8).
quick
Jeśli pakiet pasuje do tej reguły, wówczas jest jest ona uznawana za regułę "zwycięską" i nie następuje dalsze porównywanie reguł z zestawu.
interface
Nazwa interfejsu sieciowego na którym ma być aktywowana ochrona przed spoofing-iem. Może to być także lista interfejsów sieciowych.
af
Rodzina adresów dla której ma być aktywowana ochrona przed spoofing-iem. inet dla IPv4 lub inet6 dla IPv6.

Przykład:

antispoof for fxp0 inet

Gdy zestaw reguł jest ładowany, każde wystąpienie antispoof jest rozszerzane do dwóch reguł filtrujących. Zakładając, że interfejs fxp0 ma adres IP 10.0.0.1 i maskę podsieci 255.255.255.0 (np, /24), powyższa reguła antispoof byłaby przekształcona w:

block in on ! fxp0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.1 to any

Reguły te realizują dwa zadania:

UWAGA: Reguły filtrujące, w które antispoof się przekształca będą blokować także pakiety wysyłane przez interfejs zwrotny (ang. loopback) na lokalny adres. W każdym razie najlepiej opuszczać filtrowanie pakietów na interfejsie zwrotnym, a staje się to konieczne w przypadku korzystania z reguł antispoof:

set skip on lo0

antispoof for fxp0 inet

Korzystanie z antispoof powinno być ograniczone do interfejsów, które mają przypisany adres IP. Użycie antispoof na interfejsie bez adresu IP spowoduje powstanie następujących reguł filtrujących:

block drop in on ! fxp0 inet all
block drop in inet all

Przy takich regułach istnieje ryzyko blokowania całego nadchodzącego ruchu na wszystkich interfejsach.

Unicast Reverse Path Forwarding

Od wersji OpenBSD 4.0, PF zawiera obsługę Unicast Reverse Path Forwarding (uRPF). W sytuacji gdy pakiet przechodzi przez sprawdzanie uRPF, źródłowy adres IP pakietu jest sprawdzany w tablicy routingu. Gdy znaleziony w tablicy routingu wpis dotyczący interfejsu wyjściowego jest taki sam jak interfejsu z którego pakiet właśnie nadszedł, wówczas sprawdzenie uRPF powoduje jego przepuszczenie. Gdy interfejsy nie pasują, istnieje możliwość że pakiet posiada podmieniony adres źródłowy.

Sprawdzenie uRPF moze być wykonywane poprzez użycie flagi urpf-failed w zestawie reguł filtra:

block in quick from urpf-failed label uRPF

Zwróć uwagę, że sprawdzanie uRPF ma sens tylko w środowiskach gdzie routing jest symetryczny.

uRPF dostarcza taką samą funkcjonalność jak reguły antispoof.

Pasywne rozpoznawanie systemów operacyjnych

Pasywne rozpoznawanie systemów operacyjnych (ang. Passive OS Fingerprinting, OSFP) to sposób pasywnego rozpoznawania systemu operacyjnego zdalnego węzła na podstawie pewnych charakterystycznych cech jego pakietów TCP SYN. Informacje te mogą być wykorzystywane jako kryteria w regułach filtrujących.

PF rozpoznaje system operacyjny zdalnego węzła dzięki porównywaniu jego charakterystyk pakietów TCP SYN z plikiem zawierającym "odciski palców" (ang. fingerprints file) różnych systemów operacyjnych, którym domyślnie jest /etc/pf.os. Jeśli PF jest włączony, aktualna lista "odcisków" może być wyświetlona poniższą komendą:

# pfctl -s osfp

W regule filtrującej, rozpoznawanie "odcisków" może być określane poprzez rodzinę systemów operacyjnych, wersje lub gałąź/poziom poprawek. Każda z tych składowych jest wylistowana na wyjściu dopiero co wyżej wspomnianej komendy pfctl. Aby określić "odcisk" systemu w regule filtrującej, używamy słowa kluczowego os:

pass  in on $ext_if from any os OpenBSD keep state
block in on $ext_if from any os "Windows 2000"
block in on $ext_if from any os "Linux 2.4 ts"
block in on $ext_if from any os unknown

Specjalna klasa systemów unknown pozwala dopasować pakiety, dla których "odciski" nie zostały rozpoznane.

WARTO PAMIĘTAĆ następujące fakty:

Opcje IP

Domyślnie PF blokuje wszystkie pakiety IP z ustawionymi opcjami. Może to utrudnić rozpoznanie systemu operacyjnego przez takie narzędzia jak nmap. Jeśli zachodzi konieczność uruchomienia aplikacji, która wymaga przepuszczania tych pakietów, jak np. wysyłanych do grupy odbiorców (ang. multicast) lub IGMP, można skorzystać z dyrektywy allow-opts:
pass in quick on fxp0 all allow-opts

Przykład zestawu reguł filtrujących

Poniżej znajduje się przykład zestawu reguł filtrujących. Maszyna z PF pełni rolę firewalla oddzielającego małą sieć wewnętrzną od Internetu. Poniżej przedstawiona jest tylko konfiguracja odpowiadająca za filtrowanie, regułki kolejkowanie, nat, rdr itp zostały pominięte.

ext_if  = "fxp0"
int_if  = "dc0"
lan_net = "192.168.0.0/24"

# table containing all IP addresses assigned to the firewall
table <firewall> const { self }

# nie filtruj na interfejsie zwrotnym (loopback)
set skip on lo0

# normalizacja przychodzących pakietów
scrub in all

# ustawienie polityki domyślnego blokowania
block all

# aktywuj ochronę przed spoofing-iem na wszystkich interfejsach.
block in quick from urpf-failed

# zezwalaj na połączenia ssh z sieci lokalnej jedynie z zaufanego
# hosta - 192.168.0.15. korzystaj z "block return", aby TCP RST
# od razu było wysyłane w odpowiedzi na blokowane połączenia
# korzystaj z "quick", aby reguła nie była nadpisana przez
# znajdujące się poniżej reguły "pass"
block return in quick on $int_if proto tcp from ! 192.168.0.15 \
   to $int_if port ssh

# przepuszczaj cały ruch z i do lokalnej sieci.
# reguły te utworzą wpisy w tabeli stanów zgodnie z domyślnym
# dołączeniem opcji "keep state"
pass in  on $int_if from $lan_net to any
pass out on $int_if from any to $lan_net

# wypuszczaj tcp, udp i icmp na interfejsie zewnętrznym (Internet). 
# połączenia tcp będą modulowane, połączenia udp/icmp będą
# śledzone poprzez stany
pass out on $ext_if proto { tcp udp icmp } all modulate state

# zezwalaj na połączenia ssh na interfejsie zewnętrznym pod warunkiem,
# że NIE są one skierowane do firewall-a (np, nie są skierowane
# do maszyny z sieci lokalnej). twórz logi dla pakietów inicjujących
# połączenia, aby można było potem stwierdzić, kto próbował się
# połączyć. używamy "tcp syn proxy" dla nadchodzących połączeń.
# flagi domyślne "S/SA" będą automatycznie dołączane do reguł 
# PF-a.
pass in log on $ext_if proto tcp from any to ! <firewall> \
   port ssh synproxy state

[Wstecz: Tabele] [Spis treści] [Dalej: Translacje adresów (NAT)]


[wstecz] www@openbsd.org
$OpenBSD$