[Wstecz: Redundantny firewall z CARP i pfsync] [Spis treści]
[ KOMP1 ] [ KOMP3 ]
| |
---+------+-----+------- xl0 [ OpenBSD ] fxp0 -------- ( Internet )
|
[ KOMP2 ]
Do sieci wewnętrznej przyłączonych jest kilka maszyn, co prawda na schemacie zaznaczone są trzy, ale w tym przypadku ich ilość nie ma żadnego znaczenia. Komputery te wykorzystywane są do codziennych zadań takich jak: przeglądanie stron www, wysyłanie poczty elektronicznej, rozmów, itd., za wyjątkiem KOMP3, który służy również jako niewielki serwer WWW. Przestrzeń adresowa sieci wewnętrznej zawiera się w bloku 192.168.0.0 / 255.255.255.0.
Router zbudowany na bazie OpenBSD to komputer z procesorem Celeron 300 i dwiema kartami sieciowymi: 3Com 3c509B (xl0) i Intel EtherExpress Pro/100 (fxp0). Połączony jest on z Internetem ethernetowym, a do udostępniania połączenia innym komputerom wykorzystywany jest NAT. Adres IP dla zewnętrznego interfejsu uzyskiwany jest dynamicznie od Dostawcy Usług Internetowych.
ext_if = "fxp0"
int_if = "xl0"
tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"
comp3 = "192.168.0.3"
Pierwsze dwie linie określają na jakich interfejsach będzie odbywać się filtrowanie. Dzięki zdefiniowaniu ich w tym miejscu, w sytuacji gdy będziemy chcieli przenieść nasz system na inną maszynę, z innym sprzętem, będziemy mogli zmienić tylko te dwie linie, a pozostała część zestawu reguł będzie wciąż użyteczna. Trzecia linia zawiera listę portów TCP (SSH i ident/auth), do których ruch z Internetu ma być przepuszczany. W czwartej linii określone są typy komunikatów ICMP, które będą akceptowane przez nasz "firewall". Ostatnia linia określa adres IP komputera KOMP3.
Uwaga: Jeśli połączenie internetowe odbywa się poprzez PPPoE, wtedy filtrowanie oraz translacja pakietów odbywać się będzie na interfejsie tun0 a nie na fxp0.
set block-policy return
set loginterface $ext_if
Każdy system UNIX posiada interfejs pętli zwrotnej nazywany "loopback". Jest to wirtualny interfejs sieciowy używany przez procesy do komunikacji z innymi aplikacjami uruchomionymi w lokalnym systemie. Cały ruch na tym interfejsie powinien być przepuszczany bez żadnych ograniczeń. W OpenBSD interfejs "loopback" nazywa się: lo(4). Najlepszym pomysłem jest wyłączenie jakiegokolwiek filtrowania na tym interfejsie. W tym celu skorzystaj z opcji set skip.
set skip on loZauważ, że wyłączyliśmy filtrowanie dla całej grupy interfejsów lo, w ten sposób w sytuacji gdy później dodamy interfejsy "loopback", nie będziemy musieli się martwić o dodawanie tej opcji do istniejącego zestawu reguł.
scrub in
nat on $ext_if from !($ext_if) to any -> ($ext_if)
Wyrażenie "!($ext_if)", może być oczywiście łatwo zastąpione przez "$int_if", jednak jeżeli dodasz wiele wewnętrznych interfejsów, będziesz musiał dodać wiele reguł NAT, tymczasem w takim rozwiązaniu, NAT będzie obsługiwany na wszystkich zabezpieczonych interfejsach.
Jako że adres IP dla zewnętrznego interfejsu sieciowego jest uzyskiwany dynamicznie, nazwa interfejsu na którym odbywa się mapowanie adresów została wzięty w nawiasy, dzięki temu PF zostanie powiadomione o każdej zmianie adresu.
Ponieważ, chcemy mieć działające FTP-proxy, umieścimy w naszej konfiguracji również zakotwiczenie NAT:
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
Proszę zauważyć, że regułka ta obsługuje jedynie połączenia FTP na porcie 21. Jeśli zajdzie potrzeba umożliwienia korzystania z innych numerów portów, konieczne będzie podanie ich w postaci listy, na przykład: from any to any port { 21, 2121}
Ostatnia reguła rdr służy do przekierowania prób połączeń z portem 80 protokołu TCP firewalla. Poprawne połączenia z tym portem pochodzą od użytkowników chcących uzyskać dostęp do serwera WWW. Połączenia te powinny zostać przekierowane do komputera KOMP3:
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
block in
W tym miejscu każdy ruch usiłujący wejść przez interfejs będzie blokowany, nawet ten pochodzący z sieci wewnętrznej. Kolejne regułki będą umożliwiały przejście datagramów zgodnie z wytycznymi podanymi wcześniej.
Pamiętaj, że pf może zablokować każdy ruch wchodzący lub wychodzący przez interfejs. Możesz sobie znacznie uprościć życie, jeżeli zdecydujesz się na filtrowanie ruchu w jednym kierunku, zamiast starać się bezpośrednio filtrować pewne rzeczy, przepuszczając inne. W naszym przypadku, zdecydowaliśmy się na filtrowanie przychodzącego ruchu, lecz gdy dany ruch zostanie raz przepuszczony przez interfejs, nie będziemy starali się go blokować. Zatem zrobimy coś takiego:
pass out keep state
Potrzebyjemy mieć zakotwiczenie dla ftp-proxy(8):
anchor "ftp-proxy/*"Dobrze jest blokować sfałszowane adresy (ang. antispoof):
antispoof quick for { lo $int_if }
Następna regułka otwiera porty dla usług, które mają być udostępnione w Internecie. Na początek ruch który jest kierowany do samego firewall-a:
pass in on $ext_if inet proto tcp from any to ($ext_if) \
port $tcp_services flags S/SA keep state
Podanie portów w postaci makra $tcp_services sprawia, że łatwo dodać kolejne usługi, które mają zostać udostępnione. Wystarczy wyedytować makro i ponownie załadować zestaw reguł. Podobnie sprawa ma się z usługami bazującymi na protokole UDP, potrzeba tylko utworzyć makro $udp_services i dodać bardzo podobną regułkę, jak ta pokazana powyżej, z opcją proto udp.
Dodatkowo, obok reguły rdr, która przekierowuje ruch skierowany do serwera WWW do komputera KOMP3, konieczne jest przepuszczenie tego ruchu przez firewall:
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
flags S/SA synproxy state
Aby odrobinę poprawić bezpieczeństwo zastosowano TCP SYN Proxy, który dodatkowo zabezpiecza serwer przed atakami z zewnątrz.
Przepuszczenie pakietów ICMP:
pass in inet proto icmp all icmp-type $icmp_types keep state
Podobnie jak makro $tcp_services, makro $icmp_types może być w łatwy sposób zmienione by umożliwić przepuszczanie innych typów pakietów ICMP przez firewall. Proszę zwrócić uwagę, że regułka ta odnosi się do wszystkich interfejsów sieciowych.
Kolejne regułki przepuszczają ruch z lub do sieci wewnętrznej. Przykład zakłada, że użytkownicy na wewnętrznym interfejsie dokładnie wiedzą co robią i nie będą powodować problemów. To niekoniecznie prawidłowe założenie, mniejsza swoboda może być bardziej odpowiednia w wielu przypadkach.
pass in quick on $int_if
Ruch TCP, UDP i ICMP jest przepuszczany do Internetu, ze względu na wcześniejszą regułę "pass out keep state". Informacja o stanie jest zachowywana, zatem pakiety które są odpowiedzią, będą przepuszczane przez firewall.
# makra
ext_if = "xl0"
int_if = "fxp0"
tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"
comp3 = "192.168.0.3"
# opcje
set block-policy return
set loginterface $ext_if
set skip on lo0
# normalizacja datagramów
scrub in
# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0)
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
# regułki filtra pakietów
block in
pass out keep state
anchor "ftp-proxy/*"
antispoof quick for { lo $int_if }
pass in on $ext_if inet proto tcp from any to ($ext_if) \
port $tcp_services flags S/SA keep state
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
flags S/SA synproxy state
pass in inet proto icmp all icmp-type $icmp_types keep state
pass in quick on $int_if
|
[Wstecz: Redundantny firewall z CARP i pfsync] [Spis treści]