<!doctype linuxdoc system>

<!-- $Id: pf.sgml,v 1.4 2002/09/01 18:47:06 szopen Exp $ -->

<article>

<title>Filtr Pakietów OpenBSD HOWTO</title>
<author>Wouter Coene</author>
<date>Wersja oryginału: version 20020405.2, generated April 5, 2002</date>
<p>Oryginał tego dokumentu znajduje się pod adresem: <url url="http://www.inebriated.demon.nl/pf-howto/"></p>
<author>Tłumaczenie: Łukasz Bromirski, <tt>l.bromirski@mr0vka.eu.org</tt></author>
<date>Wersja tłumaczenia: Wersja 1.3, 2002/09/03 15:04:13</date>
<p>Oryginał tłumaczenia znajduje się pod adresem: <url url="http://mr0vka.eu.org/docs/tlumaczenia/pf/index.html"></p>

<toc>

<sect>Wprowadzenie

<p>
 Filtr pakietów OpenBSD ( OpenBSD PF) jest paczką ściany ogniowej potrafiącą śledzić stany połączeń,
 włączoną jako część kernela OpenBSD od wersji OpenBSD 3.0. Ten dokument opisuje jak uruchomić i
 zarządzać zestawem reguł PF i mapowań NAT.
</p>

<sect1> Do kogo adresowany jest ten dokument

<p>
 Dokument ten adresowany jest do administratorów sieci i systemów, z przynajmniej podstawową znajomością
 sieci i protokołów sieciowych. Wiedza o innych systemach ścian ogniowych nie jest wymagana, ale może
 pomóc w opanowaniu bardziej skomplikowanych tematów.
</p>

<sect1> Status

<p>
 Dokument jest ciągle rozbudowywany, więc nie wszystko jeszcze jest opisane.
</p>

<p>
 Na wykonanie czeka:
 
 <itemize>
  <item>Network Address Translation
  <item>IPv6
  <item>więcej informacji o poleceniu `pfctl'
  <item>AuthPF
 </itemize>

<sect1>Prawa autorskie i licencja

<p>
<tscreen><verb>
   The OpenBSD Packet Filter HOWTO version 20020405.2
   Copyright (C) Wouter Coene, 2001, 2002.
   
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are
   met:
   
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in
       the documentation and/or other materials provided with the
       distribution.
     * The name of the author may not be used to endorse or promote
       products derived from this software without specific prior written
       permission.
     * This software may not be mass-distributed for sale without
       informing the author at least two weeks in advance.
       
   THIS DOCUMENT IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
</verb></tscreen>

<sect1> Kontakt z autorem

<p>
 Możesz skontaktować się z Wouter Coene przez e-mail pisząc na adres
 wouter[at]inebriated.demon.nl, lub zwykłą pocztą:

<tscreen><verb>
De Deel 17
3471 EN Kamerik
The Netherlands
</verb></tscreen>

<sect> Podstawy ścian ogniowych

<p>
 Ściana ogniowa ma za zadanie chronić twoją sieć przed potancjalnymi atakami pochodzącymi z innej sieci.
 Wykonuje to zadanie poprzez sprawdzanie pakietów krążących między tymi dwoma sieciami i ograniczaniu
 ruchu na podstawie typów, celów a nawet zawartości tych pakietów.
</p>

<p>
 Sekcja ta wyjaśnia jak rozpocząć pracę ze ścianą ogniową przy użyciu PF. Na użytek tej sekcji używać będę
 firmowej sieci i ściany ogniowej jako przykładu. Sieć jest typową siecią TCP/IP z adresem 
 <tt>260.250.1.0/24</tt>. Pod adresem <tt>260.250.1.3</tt> pracuje firmowy serwer WWW, a ściana ogniowa
 ma dwa interfejsy, <tt>xl0</tt> i <tt>xl1</tt>. Sieć firmowa podłączona jest do interfejsu <tt>xl1</tt>
 a połączenie do internetu do interfejsu <tt>xl0</tt>.
</p>

<sect1> Podstawy reguł

<p>
 Komponent PF odpowiedzialny za ścianę ogniową używa zestawu reguł do opisania akcji, które zostaną podjęte
 w stosunku do określonych pakietów. Reguły te czytane są z pliku i ładowane do kernela OpenBSD przy
 użyciu komendy `<tt>pfctl</tt>' ( po więcej informacji dotyczących ładowania zestawu reguł, odsyłam
 do sekcji <ref id="loading" name="Ładowanie zestawu reguł"> ).
</p>

<p>
 Taki plik z regułami może wyglądać tak:

<tscreen><verb>
block in all
pass  in all
</verb></tscreen>

 Popatrzmy co się tu dzieje. Pierwsza reguła mówi PF by zablokować wszystkie przychodzące pakiety. W 
 przeciwieństwie do innych ścian ogniowych, PF nie przerywa przeglądania reguł gdy znajdzie pasującą.
 Zamiast tego, zaznacza to, że pakiet ma być zablokowany, ale przechodzi do następnej reguły.
</p>

<p>
 Następna reguła mówi PF by wpuścić wszystkie przychodzące pakiety skierowane do dowolnego komputera.
 Ponownie, PF notuje że pakiet ma zostać przepuszczony i przechodzi do następnej reguły.
</p>

<p>
 Ponieważ nie ma już następnej reguł, PF sprawdza co zamierzał zrobić. W tym przypadku, ostatnia pasująca
 reguła mówiła o przepuszczeniu pakietu, więc dokładnie to robi.
</p>

<p>
 Cóż, nie wygląda to zbyt użytecznie, więc spróbujmy czegoś bardziej interesującego. Zezwólmy na dostęp do
 firmowego serwera WWW pracującego pod adresem 260.250.1.3. Możesz spróbować czegoś takiego:

<tscreen><verb>
block in all
pass  in from any to 260.250.1.3/32
</verb></tscreen>

 Ponownie, pierwsza reguła mówi PF, że powinien zablokować ten pakiet.
</p>

<p>
 Druga reguła mówi PF żeby przepuścić pakiety, które skierowane są do <tt>260.250.1.3</tt>, gdzie
 `<tt>/32</tt>' oznacza że PF powinien dopasować adres w pełnym, 32 bitowym zakresie.
</p>

<p>
 Ale co z ruchem powrotnym, mógłbyś spytać. Cóż, jest to raczej proste, po prostu pozwalamy na ruch z
 <tt>260.250.1.3</tt> wszędzie.

<tscreen><verb>
block in all
pass  in from any to 260.250.1.3/32
pass  in from 260.250.1.3/32 to any
</verb></tscreen>

<sect1> Trochę bardziej zaawansowane zestawy reguł

<p>
 Przypuścmy że zdecydowano, że kolejny zestaw stron zostanie uruchomiony na firmowym serwerze WWW, ale 
 zawiera delikatne informacje firmowe, więc nie powinien być dostępny z zewnątrz. Serwer ten, w 
 przeciwieństiwe do poprzedniego, uruchomimy na niestandardowym porcie 8000 TCP.
</p>

<p>
 Teraz nie będziesz filtrował tylko na podstawie adresu docelowego, ale również na podstawie portu TCP,
 by upewnić się że nikt spoza firmowej sieci nie połączy się z portem 8000:

<tscreen><verb>
block in all
pass  in proto tcp from any to 260.250.1.3/32 port = 80
pass  in proto tcp from 260.250.1.3/32 port = 80 to any
</verb></tscreen>

 Jak widzisz, nie filtrujemy jedynie na podstawie portu, ale wskazujemy również, że przejść mogą pakiety
 tylko należące do protokołu TCP.
</p>

<sect1> Utrzymywanie stanu/śledzenie połaczeń<label id="23">

<p>
 Komponent odpowiedzialny za obsługę ściany ogniowej, potrafi zapamiętać jakie sesje TCP, UDP i ICMP 
 zostały stworzone i potrafi filtrować pakiety na podstawie informacji z tej tabeli. Nazywamy to
 <bf>utrzymywaniem stanu/śledzeniem połączeń</bf> ( ang. <em>keeping state</em> ).
</p>

<p>
 W momencie w którym PF zobaczy regułę mówiącą o utworzeniu stanu i śledzeniu tego połaczenia, tworzy nowy
 wiersz w tabeli, bazując na informacjach z pakietu. Powoduje to, że następne pakiety będą przepuszczane
 bez przechodzenia przez fazę sprawdzania.
</p>

<p>
 Śledzenie połączeń składa się z bardzo drobiazgowego sprawdzania numerów sekwencyjnych z informacjami
 zapisanymi w tabeli stanów i odrzucania tych, które nie pasują do niej, co zmniejsza prawdopodobieństwo
 że komputery za ścianą ogniową ze słabą implementacją TCP staną się ofiarą ataku TCP. W procesie
 śledzenia stanu dla sesji UDP, PF umożliwia pojedyńczemu pakietowi odpowiedzi przejście przez
 ścianę ogniową z powrotem, w ramach pakietu który stworzył wiersz w tabeli stanów.
</p>

<p>
 Przypuśćmy, że pracownicy naszej firmy, korzystający z komputerów w sieci firmowej, powinni móc oglądać
 strony WWW. Wymaga to przepuszczania zarówno połączeń TCP na port 80, jak również przepuszczania zapytań
 DNS na port 53.
</p>

<p>
 Przy użyciu silnika śledzącego połączenia PF, możemy zapewnić bezpieczną pracę takiej konfiguracji.
 Przy okazji, możemy wykorzystać śledzenie połączeń, do kontrolowania połączeń do naszego firmowego serwera
 WWW, dzięki czemu zwiększamy bezpieczeństwo konfiguracji:

<tscreen><verb>
block in all
pass  in proto udp from 260.250.1.0/24 to any port = 53 keep state
pass  in proto tcp from 260.250.1.0/24 to any port = 80 keep state
pass  in proto tcp from any to 260.250.1.3/32 port = 80 keep state
</verb></tscreen>

<p>
 Trzecia reguła zezwala komputerom w sieci wewnętrznej na połączenia HTTP do zewnętrznych serwerów, przez
 poinstruowanie PF by tworzył nowe wpisy w tabeli stanów dla każdego z tych połączeń. Ostatnia reguła mówi
 to samo, ale dla połączeń z sieci zewnętrznej do naszego firmowego serwera WWW, co sprawia że reguła
 zezwalająca na ruch w odwrotną stronę nie jest już potrzebna.
</p>

<p>
 Używanie mechanizmy utrzymywania stanów i śledzenia połączeń wydaje się obciążać ścianę ogniową dodatkową
 pracą i w wyniku tego zmniejszeniem przepustowości. Co ciekawe jednak, w wykonaniu PF sprawdzanie tabeli
 stanów jest szybsze niż sprawdzanie reguł. Typowy zestaw z 50 regułami to około 50 porównań, a tabela
 stanów z 50,000 wpisów to tylko około 16 porównań, co wynika z konstrukcji tabeli - w postaci binarnego
 drzewa. Ta informacja, w połączeniu ze zwiększonym bezpieczeństwem sprawia, że powinieneś używać śledzenia
 połączeń i utrzymywania stanów nawet dla prostych zadań, które łatwo można zrealizować bez tego
 mechanizmu.
</p>

<sect1> Wyłamywanie się z zestawu reguł: słowo kluczowe `quick'

<p>
 Czasami przydatne byłoby, gdyby PF przestawał w pewnym momencie przeglądać reguł i zrobił coś na podstawie
 tego czy pakiet pasuje do reguły czy nie. Można to zrealizować za pomocą słowa kluczowego
 `<tt>quick</tt>'. Reguła z tym słowem, pasująca do pakietu, spowoduje przerwanie przeglądania reguł.
</p>

<p>
 Jest to niebywale przydatne przy ochronie twojej sieci przed sfałszowanymi pakietami, tak jak pokazuje
 to poniższy przykład:

<tscreen><verb>
block in all
block in quick from 10.0.0.0/8 to any
block in quick from 172.16.0.0/12 to any
block in quick from 192.168.0.0/16 to any
block in quick from 255.255.255.255/32 to any
pass  in all
</verb></tscreen>

<p>
 Ten zestaw reguł mówi PF by natychmiast odrzucał pakiety z <tt>10.0.0.0/8</tt>, <tt>172.16.0.0/12</tt>,
 <tt>192.168.0.0/16</tt> oraz z <tt>255.255.255.255/32</tt>. Pozostałe pakiety zostaną przepuszczone.
</p>

<p>
 Skutkuje to również przyśpieszeniem przetwarzania reguł, które sprawdzane są z dużym ruchem, jeśli
 zostanie użyte poprawnie.
</p>

<sect1> Wskazywanie interfejsów sieciowych

<p>
 Możliwe jest również sprawdzanie interfejsów sieciowych, którym pakiet dotarł do systemu. Zaadaptujmy
 nasze poprzednie reguły sprawdzające pakiety, do nowej funkcjonalności, zachowując strukturę naszej 
 sieci firmowej:

<tscreen><verb>
block in all
block in quick on xl0 from 10.0.0.0/8 to any
block in quick on xl0 from 172.16.0.0/12 to any
block in quick on xl0 from 192.168.0.0/16 to any
block in quick on xl0 from 255.255.255.255/32 to any
pass  in all
</verb></tscreen>
</p>

<sect1> Sprawdzanie flag TCP

<p>
 By umożliwić blokowanie nieprawidłowych pakietów, możesz poinstruować PF by filtrował na podstawie flag
 TCP. Używa się do tego słowa kluczowego `<tt>flags</tt>', po którym następuje lista flag które mają być
 ustawione i ewentualnie opcjonalny slasz po którym następuje maska flag.
</p>

<p>
 PF dla każdego pakietu TCP, zamaskuje flagi które zostały wskazane, a następnie sprawdzi te które powinny
 być ustawione. W związku z tym `<tt>flags S/SA</tt>' mówi, że z flag <tt>SYN</tt> i <tt>ACK</tt>, tylko
 flaga <tt>SYN</tt> powinna być ustawiona.
</p>

<p>
 PF rozpoznaje następujące flagi:

<descrip>

<tag/F/FIN, dla zamykania połączeń
<tag/S/SYN, dla otwierania połączeń
<tag/R/RST, dla resetowania połączeń
<tag/P/PSH, dla upewniania się że wszystkie dane dotarły
<tag/A/ACK, dla potwierdzania pakietów
<tag/U/URG, by zaznaczyć że pakiet jest pilny

</descrip>

<p>
 Na przykład, pakiet żądający nowego połączenia, ma ustawioną tylko flagę <tt>SYN</tt>, a pakiet
 potwierdzający połączenie ma ustawione zarówno <tt>SYN</tt> jak i <tt>ACK</tt>. Z kolei pakiet oznaczający,
 że żądanie o połączenie zostało odrzucone ma ustawione flagi <tt>ACK</tt> i <tt>RST</tt>.
</p>

<p>
 Użycie niepoprawnej kombinacji flag TCP jest bardzo popularną metodą skanowania komputerów by sprawdzić
 otwarte porty. Przez użycie słowa `<tt>flags</tt>' możesz obronić swój system przed takimi skanami i zmusić
 skanery portów do użycia technik, które są dużo prostsze do wykrycia.
</p>

<p>
 Zmodyfikujmy nasz przykład używający śledzenia połączeń z powyższej sekcji. Chcemy wymusić, by tylko 
 pakiety TCP, które spośród flag <tt>SYN</tt> i <tt>ACK</tt> mają ustawioną flagę <tt>SYN</tt>, przechodziły
 i tworzyły nowe wpisy w tabeli stanów:

<tscreen><verb>
block in all
pass  in proto udp from 260.250.1.0/24 to any port = 53 keep state
pass  in proto tcp from 260.250.1.0/24 to any port = 80 \
                                    flags S/SA keep state
pass  in proto tcp from any to 260.250.1.3/32 port = 80 \
                                    flags S/SA keep state
</verb></tscreen>

<p>
 Powinno to zapobiec technikom skanowania opisanym powyżej, przed przejściem przez naszą ścianę ogniową.
</p>

<sect1> Zestawy

<p>
 Oprócz podawania pojedyńczych adresów źródłowych i docelowych, możemy również wskazywać zestawy
 komputerów. Wykonuje się to przez otoczenie ich w nawiasy klamrowe, a same adresy rozdziela się
 przecinkami.
</p>

<p>
 Jeśli twój stary zestaw reguł wyglądał tak:

<tscreen><verb>
block in quick on xl0 from 10.0.0.0/8 to any
block in quick on xl0 from 172.16.0.0/12 to any
block in quick on xl0 from 192.168.0.0/16 to any
block in quick on xl0 from 255.255.255.255/32 to any
</verb></tscreen>

 Możesz teraz napisać:

<tscreen><verb>
block in quick on xl0 from { 10.0.0.0/8, 172.16.0.0/12, \
              192.168.0.0/16, 255.255.255.255/32 } to any
</verb></tscreen>

 Możemy ten zapis wykorzystać również do wskazania interfejsów, protokołów i portów. Program <tt>pfctl</tt>
 rozdzieli takie reguły na pojedyńcze dla każdej kombinacji, a dzięki temu PF może zoptymalizować Twój
 zestaw reguł używając techniki opisanej w sekcji 
 <ref id="2.9" name="Optymalizacja zestawu reguł: pomijanie">. Dodatkowo, zwiększa to czytelność reguł w
 przypadku wielu zestawów komputerów, interfejsów, protokołów czy portów.
</p>

<sect1> Rozwijanie zmiennych

<p>
 PF wspiera również rozwijanie zmiennych, na zasadach takich jak <bf>powłoka</bf> ( ang. <em>shell</em> ).
 Zmienne definiowane są przez przypisanie im wartości, a rozwija się je przez poprzedenie ich nazwy
 znakiem dolara ( `<tt>$</tt>' ):

<tscreen><verb>
webserver="260.250.1.3/32"
pass  in from any to $webserver port = 80 keep state
</verb></tscreen>

 Wartość zmiennej musi znajdować się w cudzysłowiu.
</p>

<sect1> Optymalizacja zestawu reguł: pomijanie<label id="2.9">

<p>
 W przeciwieństwie do IPFilter, PF z OpenBSD nie obsługuje słowa kluczowego `<tt>group</tt>'. Twórcy PF
 wybrali schemat zwany <bf>pomijaniem</bf> ( ang. <em>skip</em> ), w którym zestaw reguł optymalizowany
 jest automatycznie.
</p>

<p>
 Załóżmy, że Twój zestaw reguł wygląda tak:

<tscreen><verb>
block in quick on xl0 from 10.0.0.0/8 to any
block in quick on xl0 from 172.16.0.0/12 to any
block in quick on xl0 from 192.168.0.0/16 to any
block in quick on xl0 from 255.255.255.255/32 to any
</verb></tscreen>

 Dla każdego pakietu przychodzącego, zestaw reguł sprawdzany jest od góry do dołu. Wyobraź sobie pakiet,
 który dotarł interfejsem <tt>xl1</tt>. Sprawdzana jest pierwsza reguła, która nie pasuje. Ponieważ
 wszystkie pozostałe reguły dotyczą pakietów z interfejsu <tt>xl0</tt> PF może je pominąć.
</p>

<p>
 Kiedy ładujesz zestaw reguł, następujące parametry porównywane pomiędzy kolejnymi regułami
 ( w tej kolejności ):

<enum>
<item>interfejs
<item>protokół
<item>adres źródłowy
<item>port źródłowy
<item>adres docelowy
<item>port docelowy
</enum>

 Dla każdej reguły, PF automatycznie wylicza tak zwane <bf>kroki do pominięcia</bf>
 ( ang. <em>skip step</em> ), dla każdego z tych parametrów. Parametry te mówią PF ile reguł ma te same
 parametry.
</p>

<p>
 Jeśli nadchodzący pakiet dociera do interfejsu <tt>xl1</tt> i sprawdzany jest przez nasz zestaw reguł,
 PF stwierdza, że pakiet nie pasuje do pierwszej reguły, a ponieważ następne 3 również nie dotyczą tego
 interfejsu, pomija je.
</p>

<p>
 Chcąc zmaksymalizować wydajność swojego zestawu reguł, powinieneś posortować go według: interfejsów,
 protokołu, adresu źródłowego, potem portu, w końcu adresu docelowego i również portu.
</p>

<sect1> Składanie tego wszystkiego razem

<p>
 Poskładajmy kawałki zestawu reguł, które do tej pory poznaliśmy. Poniżej wynik:

<tscreen><verb>
# ustawiamy trochę zmiennych
external="xl0"
internal="xl1"
corporate="260.250.1.0/24"
webserver="260.250.1.3/32"
spoofed="{ 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, \
                                  255.255.255.255/32 }"
# domyślnie blokujemy wszystko
block in all

# zezwalamy na oglądanie stron WWW z sieci firmowej
pass  in quick on $internal proto udp from $corporate to any \
                                          port = 53 keep state
pass  in quick on $internal proto tcp from $corporate to any \
                               port = 80 flags S/SA keep state

# odrzucamy sfałszowane pakiety
block in quick on $external from $spoofed to any

# zezwalamy na dostęp do firmowego serwera WWW z Internetu
pass  in quick on $external proto tcp from any to $webserver \
                               port = 80 flags S/SA keep state
</verb></tscreen>

 Masz - bezpieczna ściana ogniowa. Oczywiście, to nie wystarczy by zabezpieczyć sieć firmową. Ale to
 pierwsza linia obrony i zdaje się dobrze wykonywać swoją robotę.
</p>

<sect1> Ładowanie zestawu reguł<label id="loading">

<p>
 Kiedy już jesteś szczęśliwy ze swoim zestawem reguł, możesz je zapisać jako <tt>/etc/pf.conf</tt> i
 zresetować maszynę, albo napisać:

<tscreen><verb>
pfctl -R /etc/pf.conf
</verb></tscreen>

 Aby OpenBSD ładował automatycznie reguły, dodaj linijkę <tt>pf=YES</tt> w pliku
 <tt>/etc/rc.conf</tt>.
</p>

<sect> Filtrujące mosty

<p>
 Most to urządzenie sieciowe, które łączy dwa lub więcej segmentów sieciowych razem. Zwykle to pojedyńczy
 komputer, który replikuje przychodzące pakiety z jednego segmentu do drugiego. OpenBSD może również
 zostać użyty jako most, co sprawia że możliwe jest filtrowanie ruchu pomiędzy segmentami sieci.
</p>

<p>
 Ta sekcja opisuje jak skonfigurować filtrujący most przy użyciu OpenBSD i PF. Sieci użyte w przykładzie
 to sieć uniwersytecka używająca IPv4: <tt>10.0.0.0/8</tt> składająca się z dużej ilości stacji
 studenckich, serwer WWW na <tt>10.0.0.1/32</tt> oraz serwer powłoki na <tt>10.0.0.2/32</tt>.
</p>

<p>
 Ze względów bezpieczeństwa, pracownicy uniwersytetu chcieliby oddzielić dwa segmenty i filtrować ruch
 pomiędzy nimi, oczywiście z minimalnymi zmianami dla topologii sieci.
</p>

<p>
 Wybrano serwer OpenBSD, z siecią studencką podpiętą do interfejsu <tt>xl0</tt> i siecią serwerów podpiętą
 do <tt>xl1</tt>.
</p>

<sect1> Dwa kierunki

<p>
 Pakiety przechodzące przez most przechodzą również dwukrotnie przez PF: najpierw wchodzą jednym
 interfejsem a potem wychodzą drugim. Nasz zestaw reguł musi zatem zezwolić na ruch wchodzący jak i
 wychodzący, co sprawia, że zaczniemy od następujących reguł:

<tscreen><verb>
pass in  on xl0 any
pass out on xl0 any
pass in  on xl1 any
pass out on xl1 any
</verb></tscreen>

 Zezwoli to na wpuszczanie ruchu z interfejsów <tt>xl0</tt> i <tt>xl1</tt>, oraz na wypuszczanie go do
 właściwego segmentu.
</p>

<sect1> Filtrowanie ze sprawdzaniem stanów

<p>
 Filtr Pakietów OpenBSD ma bardzo fajną właściwość, nazywaną sprawdzaniem stanów, opisaną szerzej w sekcji
 <ref id="23" name="Utrzymywanie stanów/śledzenie połączeń">. Użyjemy jej na naszym przykładzie by
 zwiększyć bezpieczeństwo segmentu serwerów sieciowych.
</p>

<p>
 Jest jednak jedna rzecz, o której musisz pamiętać w przypadku filtrowania ze sprawdzaniem stanów: pozycje
 w tabeli stanów indeksowane są według klucza składającego się z adresu źródłowego, docelowego oraz portów
 TCP, w których kolejność tych par jest bez znaczenia. Jeśli pakiet wychodzący z A do B tworzy pozycję w
 tabeli stanów, PF przepuści pakiety wychodzące z A do B, oraz pakiety przychodzące z B do A. Zablokuje
 jednak pakiety wychodzące z B do A, oraz przychodzące z A do B, co w przypadku braku mostowania jest
 przypadkiem jasnym i zrozumiałym.
</p>

<p>
 W przypadku mostu, pakiet przechodzi przez PF dwukrotnie; pakiet przychodzi jednym interfejsem i wychodzi 
 drugim.
</p>

<p>
 Są dwa rozwiązania. Pierwsze, to stworzenie dwóch wpisów w tabeli stanów dla każdego połączenia, przez
 użycie dwóch reguł z opcją `<tt>keep state</tt>'. Zwiększa to jednak obciążenie serwera mostującego i
 generalnie nie zaleca się robienia czegoś takiego, ponieważ jest inna opcja, dużo prostsza i elegancka.
</p>

<p>
 Z perspektywy PF, pakiety przechodzą przez most dwukrotnie. Jeśli patrzysz na jeden interfejs, widzisz
 dokładnie taki sam ruch jak na drugim, zmieniają się jedynie kierunki. Możesz więc pominąć filtrowanie
 ruchu na jednym z interfejsów i filtrować tylko po jednej stronie.
</p>

<p>
 Oczywiście chcemy śledzić połączenia zarówno do serwera WWW jak i serwera powłoki, a ponieważ najmniej
 ufamy sieci studentów, filtrować będziemy na interfejsie <tt>xl0</tt>, przepuszczając cały ruch na
 interfejsie <tt>xl1</tt>:

<tscreen><verb>
web="10.0.0.1/32"
shell="10.0.0.2/32"

pass  in  quick on xl1 all
pass  out quick on xl1 all

block in  on xl0 all
block out on xl0 all

pass  in  quick on xl0 proto tcp from any to $web \
                                port = 80 keep state
pass  in  quick on xl0 proto tcp from any to $shell \
                         port = { 22, 23 } keep state
</verb></tscreen>

<sect> Sztuczki z filtrowaniem pakietów

<p>
 By zwiększyć bezpieczeństwo maszyn które ma ochraniać, PF OpenBSD udostępnia pewne unikalne funkcje
 poprawiające błędy w implementacjach stosu TCP/IP. Funkcje te opisano poniżej.
</p>

<sect1> Modulowanie stanu ( ang. <em>state modulation</em> )

<p>
 Aby zapewnić poprawne dostarczanie pakietów przez TCP, protokół ten używa mechanizmu numerów
 sekwencyjnych, w którym na początku połączenia wybierany jest losowy, początkowy numer sekwencyjny i
 zwiększany po każdym przesłanym bajcie. Wiele implementacji TCP używa bardzo słabego generatora losowego
 by generować takie numery, co pociąga za sobą ryzyko, że ktoś będzie mógł przechwycić takie połączenia.
</p>

<p>
 Dlatego właśnie, programiści OpenBSD PF zdecydowali się na dodanie możliwości modulowania stanu
 ( ang. <em>state modulation</em> ). Polega ona na generowaniu bardziej losowego numeru sekwencyjnego
 dla połączeń pasujących do reguł i podmienianiu numerów sekwencyjnych pakietów przechodzących przez
 ścianę ogniową.
</p>

<p>
 Można to zrobić przez dodanie słowa kluczowego `<tt>modulate state</tt>', tak jak poniżej w regule
 chroniącej naszą sieć firmową z poprzedniego rozdziału:

<tscreen><verb>
pass  in quick on xl1 proto tcp from 260.250.1.0/24 to any \
                                   flags S/SA modulate state
</verb></tscreen>

 Dodanie opcji `<tt>modulate state</tt>' implikuje opcję `<tt>keep state</tt>' opisaną w
 sekcji <ref id="23" name="Utrzymywanie stanów/śledzenie połączeń">.</p>

<sect1> Normalizacja pakietów

<p>
 Ponieważ niektóre stosy IP niepoprawnie implementują defragmentację pakietów IP, PF z OpenBSD obsługuje
 również opcję <bf>normalizującą</bf> ( ang. <em>scrub</em> - jest to bardzo swobodne tłumaczenie ;) ).
 Jeśli pasuje ona do pakietu, część PF odpowiedzialna za normalizację zapewni, że z pakietu usunięte
 zostaną wszelkie nieprawidłowości zanim zostanie on dalej przesłany.
</p>

<p>
 Normalizacja całego ruchu przychodzącego, wymaga reguły podobnej do tej:

<tscreen><verb>
scrub in all
</verb></tscreen>

 Opcja ta zużywa pewną ilość zasobów systemu, więc powinna być używana tam, gdzie istnieje realna potrzeba
 ochrony faktycznie słabych implementacji stosu TCP/IP.
</p>

<p>
 Do opcji `<tt>scrub</tt>' można dołączyć dodatkowe:

<descrip>
<tag/no-df/wyczyść bit ( flagę ) fragmentu w pasującym pakiecie IP
<tag/min-ttl numer/wymuś minimalny czas życia ( ang. <em>time to live</em> ) na pasujących pakietach,
    odrzucając te, które nie spełniają tego warunku.
</descrip>

</p>

<sect> Migrowanie z IP Filter

<p>
 Model zestawu reguł w PF wzorowany na IPFilter. Są jednak pewne różnice, które ta sekcja stara się
 udokumentować.
</p>

<sect1> Nie ma już opcji <tt>head</tt> i <tt>group</tt>

<p>
 Słowa kluczowe `<tt>head</tt>' i `<tt>group</tt>', których używano w IPFilter do grupowania reguł,
 nie są już w PF potrzebne. Jeśli używałeś ich, będziesz musiał ręcznie uporządkować swój zestaw reguł
 by prawidłowo działał z OpenBSD PF.
</p>

<p>
 PF OpenBSD używa automatycznego mechanizmu optymalizującego zestaw reguł, zwanego <bf>pomijaniem</bf>.
 Zajrzyj do rozdziału <ref id="2.9" name="Optymalizacja zestawu reguł: pomijanie"> po więcej informacji.
</p>

<sect> Inna dokumentacja

<p>
 Dostępna jest pewna ilość informacji w Internecie dotyczących PF OpenBSD i ogólnie ścian ogniowych.
 Poniżej krótkie podsumowanie całego materiału, który może być interesujący:

<descrip>

<tag/<url url="http://www.benzedrine.cx/pf.html">/Oryginalna strona tego, co teraz jest PF OpenBSD
<tag/<url url="http://www.obfuscation.org/ipf/">/HOWTO IPFilter. Pomimo, że HOWTO które
właśnie czytasz stara się być na tyle kompletne na ile to możliwe jeśli chodzi o PF,
zajrzenie do tego dokumentu może być interesujące. W końcu są to korzenie PF OpenBSD.
<tag/<url url="http://www.linuxdoc.org/HOWTO/Firewall-HOWTO.html">/The Linux Firewall
and Proxy HOWTO, który opisuje konfigurację proxy działających w przestrzeni
użytkownika, takich jak Squid czy SOCKS. Napisane dla Linuksa, ale może również
być ciekawą lekturą.
<tag/<url url="http://www.openbsd.org/cgi-bin/man.cgi?query=pfctl&sektion=8&format=html">/
Strona podręcznikowa OpenBSD do programu <tt>pfctl</tt>
<tag/<url url="http://www.openbsd.org/cgi-bin/man.cgi?query=pf.conf&sektion=5&format=html">/
Strona podręcznikowa OpenBSD opisująca format reguł PF
<tag/<url url="http://www.openbsd.org/cgi-bin/man.cgi?query=pf&sektion=4&format=html">/
Strona podręcznikowa OpenBSD opisująca urządzenie <tt>pf</tt>. Raczej dla programistów.

</descrip>

<sect> Podziękowania

<p>
 Autor chciałby podziękować następującym osobom za pomoc w niektórych skomplikowanych tematach, za
 wyjaśnienie pewnych wewnętrznych procesów PF OpenBSD, za wypunktowanie błędów w poprzednich wersjach tego
 dokumentu, w końcu ogólnie za sugestie (w kolejności alfabetycznej):

<itemize>
<item>Mike Frantzen frantzen@w4g.org
<item>Markus Friedl markus@openbsd.org
<item>Artur Grabowski art@blahonga.org
<item>Daniel Hartmeier daniel@benzedrine.cx
<item>Erik Liden erik@ipunplugged.com
<item>Rod Whitworth listener@witworx.com
<item>Jim Zajkowski jim@jimz.net
</itemize>

Wouter Coene 2002-04-05</p>

<sect> Przypisy

<descrip>
<tag/260.250.1.31/kompletnie fikcyjny przykład
<tag/ISN/więcej informacji o generowaniu ISN, jak również informacje o nich w kontekście popularnych
     systemów operacyjnyc możesz znaleźć w dokumencie pod adresem
     <url url="http://razor.bindview.com/publish/papers/tcpseq.html"
         name="http://razor.bindview.com/publish/papers/tcpseq.html">
</descrip>

<sect>Uwagi od tłumacza

<p>
 Chciałbym podziękować następującym osobom za uwagi co do tłumaczenia i zasugerowanie poprawek:

<itemize>
 <tag>Mariusz Drozdziel nova (at) tucznik.net</tag>
 literówki
</itemize>

</p>

</article>
