[OpenBSD]

[Wstecz: Przekierowani ruchu] [Spis treści] [Dalej: Opcje ]

PF: Skracanie zestawów reguł


Spis treści


Wstęp

PF oferuje kilka sposobów na uproszczenie zestawu reguł. Na początek warto obejrzeć parę dobrych przykładów użycia makr i list. Dodatkowo składnia PF umożliwia używanie skrótów pozwalających na dalsze uproszczenie pliku konfiguracyjnego. W praktyce prostszy zapis reguł jest łatwiejszy do zrozumienia i zarządzania nim.

Makra

Podstawową zaletą makr jest możliwość zastąpienia występujących w pliku konfiguracyjnym adresów IP, numerów portów, nazw interfejsów itp., przez nazwy symboliczne. Jeśli zmieni się adres IP serwera, wystarczy tylko uaktualnić definicję makra, bez konieczności marnowania czasu i energii na znajdywanie i modyfikowanie wszystkich wystąpień tego adresu w zestawie reguł.

Powszechnym zwyczajem w zestawie reguł PF jest definiowanie makra dla każdego interfejsu sieciowego. Za każdym razem gdy karta sieciowa będzie wymieniona na inną, korzystającą z innego sterownika, na przykład wymiana karty firmy 3Com na kartę firmy Intel, wystarczy uaktualnić makrodefinicję i filtr znów będzie pracował. Podobnie sprawa ma się gdy używa się ten sam zestaw reguł na różnych komputerach. Niektóre posiadają inne karty sieciowe, więc użycie makra do określenia interfejsów sieciowych pozwala na zastosowanie tego samego zestawu reguł bez wielkich zmian. Korzystanie z makrodefinicji w plikach konfiguracyjnych do określania adresów IP, nazw interfejsów czy numerów portów jest dobrym nawykiem.

# makrodefinicja dla każdego interfejsu sieciowego
IntIF = "dc0"
ExtIF = "fxp0"
DmzIF = "fxp1"

Inną, szeroko stosowaną, praktyką jest używanie makr do definiowania adresów IP oraz bloków sieci. Takie podejście doskonale obniża ilość modyfikacji, które należy przeprowadzić na zestawie reguł, w przypadku zmiany adresu IP.

# zdefiniowanie sieci
IntNet = "192.168.0.0/24"
ExtAdd = "24.65.13.4"
DmzNet = "10.0.0.0/24"

Za każdym razem gdy wewnętrzna sieć zostanie powiększona lub zmieni się jej adres, wystarczy tylko zaktualizować makro:

IntNet = "{ 192.168.0.0/24, 192.168.1.0/24 }"

Gdy tylko zestaw reguł zostanie przeładowany, wszystko będzie działać jak poprzednio

Listy

Poniższy zestaw reguł, którego umieszczenie we własnym zestawie reguł jest bardzo dobrym rozwiązaniem, blokuje adresy opisane w RFC 1918, z których ruch nigdy nie powinny znaleźć się w Internecie, a jeśli już tak się zdarzy najczęściej powoduje to problemy.
block in quick on tl0 inet from 127.0.0.0/8 to any
block in quick on tl0 inet from 192.168.0.0/16 to any
block in quick on tl0 inet from 172.16.0.0/12 to any
block in quick on tl0 inet from 10.0.0.0/8 to any
block out quick on tl0 inet from any to 127.0.0.0/8
block out quick on tl0 inet from any to 192.168.0.0/16
block out quick on tl0 inet from any to 172.16.0.0/12
block out quick on tl0 inet from any to 10.0.0.0/8

A teraz sposób na uproszczenie powyższego zapisu:

block in &nbsdp;quick on tl0 inet from { 127.0.0.0/8, 192.168.0.0/16, \
   172.16.0.0/12, 10.0.0.0/8 } to any
block out quick on tl0 inet from any to { 127.0.0.0/8, \
   192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

W bardzo prosty sposób zestaw reguł z ośmiu linii został zredukowany do dwóch. Jeszcze lepszym rozwiązaniem jest użycie makr w połączeniu z listą:

NoRouteIPs = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
   10.0.0.0/8 }"
ExtIF = "tl0"
block in  quick on $ExtIF from $NoRouteIPs to any
block out quick on $ExtIF from any to $NoRouteIPs

Należy wziąć pod uwagę, że makrodefinicje i listy upraszczają plik pf.conf, ale jest on później rozwijany przez pfctl(8) w zestaw wielu reguł. Powyższy przykład po rozwinięciu przyjmie następującą postać:

block in  quick on tl0 inet from 10.0.0.0/8 to any
block in  quick on tl0 inet from 172.16.0.0/12 to any
block in  quick on tl0 inet from 192.168.0.0/16 to any
block in  quick on tl0 inet from 127.0.0.0/8 to any
block out quick on tl0 inet from any to 10.0.0.0/8
block out quick on tl0 inet from any to 172.16.0.0/12
block out quick on tl0 inet from any to 192.168.0.0/16
block out quick on tl0 inet from any to 127.0.0.0/8

Jak można zobaczyć, rozszerzenia PF są udogodnieniem jedynie dla osoby piszącej i utrzymującej plik pf.conf, natomiast nie jest to uproszczenie reguł sprawdzanych przez pf(4).

Makra mogą być nie tylko pomocą w przypadku adresów i portów, mogą być używane w dowolnym miejscu pliku /etc/pf.conf, np.:

pre = "pass in quick on ep0 inet proto tcp from "
post = "to any port { 80, 6667 } keep state"

# klasa Davida
$pre 21.14.24.80 $post

# dom Nicka
$pre 24.2.74.79 $post
$pre 24.2.74.178 $post

Powyższy zapis zostanie rozwinięty do następującej postaci:

pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
   port = 6667 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
   port = 6667 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
   port = 6667 keep state

Składnia PF

Składnia PF została jeszcze bardziej dopracowana aby uzyskać większą elastyczność podczas definiowania reguł. PF posiada zdolność wywnioskowania właściwego słowa kluczowego, które nie zostało użyte w sposób bezpośredni podczas definiowania regułki. PF zezwala także na dużą swobodę jeśli chodzi o kolejność używania słów kluczowych, dzięki czemu nie trzeba uczyć się ich na pamięć.

Skracanie regułek

Aby określić politykę "domyślnego blokowania", należało użyć dwóch reguł:

block  in all
block out all

Obecnie można skrócić to do jednej:

block all

Kiedy kierunek ruchu pakietów nie jest podany, PF przyjmuje, że chodzi zarówno o datagramy przychodzące jak i wychodzące.

Podobnie, klauzula "from any to any jak i "all" mogą zostać pominięte, np.:

block in on rl0 all
pass  in quick log on rl0 proto tcp from any to any port 22 keep state

może zostać uproszczone do:

block in on rl0
pass  in quick log on rl0 proto tcp to port 22 keep state

Pierwsza regułka zablokuje ruch wszystkich pakietów przybywających z każdego kierunku i wychodzących w dowolnym kierunku na interfejsie rl0, natomiast druga przepuszcza ruch TCP na porcie 22 na interfejsie rl0.

Uproszczenie regułki return

Zestaw reguł, który zablokuje wszystkie porty, a na wywołanie któregoś z nich odpowie komunikatem TCP RST lub ICPM Unreachable, mógłby wyglądać tak:

block in all
block return-rst in proto tcp all
block return-icmp in proto udp all
block out all
block return-rst out proto tcp all
block return-icmp out proto udp all

Ale może zostać uproszczony do:

block return

Gdy PF natrafi na słowo return, ma już dość informacji aby wysłać właściwą odpowiedź (lub nie udzielić jej wcale), w zależności od protokołu, przy użyciu którego przesyłane były odrzucone pakiety.

Kolejność słów kluczowych

Kolejność, w jakiej wszystkie słowa kluczowe mogą zostać podane, jest w większości przypadków dość swobodna. Regułę można zapisać tak:

pass in log quick on rl0 proto tcp port 22 \
   flags S/SA keep state queue ssh label ssh

Albo tak:

pass in quick log on rl0 proto tcp port 22 \
   queue ssh keep state label ssh flags S/SA

Inne, podobne kombinacje, będą także działać.

[Wstecz: Przekierowani ruchu] [Spis treści] [Dalej: Opcje ]


[wstecz] www@openbsd.org
$OpenBSD$