# Bridge+Firewall

## Autor: Peter Breuer, ptb@it.uc3m.es
v1.1, 23 Grudnia 1996
Wersja polska: Bartosz Maruszewski B.Maruszewski@jtz.org.pl
v1.01, 26 Lipca 1997

W oryginalnym dokumencie na temat Bridge'a opisane są inne sposoby podejścia. Jest to Bridge mini-HOWTO napisane przez Chrisa Cole'a <chris@polymer.uakron.edu>. Wersja, na której bazowałem to 1.03 z 23 Sierpnia 1996. Oryginał tego dokumentu znajduje się na ftp.icm.edu.pl w katalogu `/pub/Linux/sunsite/docs/HOWTO/mini`. Dokument ten jest napisany w standardzie ISO-8859-2.

## 1. Co, jak i dlaczego ?

## 1.1 Co.

Bridge jest to inteligentne połączenie pomiędzy dwoma kartami sieciowymi. Firewall jest to inteligentny izolator.

## 1.2 Dlaczego.

Możesz chcieć bridge'a jeśli masz kilka komputerów:

- żeby zaoszczędzić pieniądze na hubie jeśli akurat masz dodatkową kartę ethernet-ową,
- żeby oszczędzić sobie nauki jak robić IP-forwarding i inne triki jeśli masz dwie karty w swoim komputerze,
- żeby oszczędzić sobie pracy jeśli coś się w przyszłości zmieni.

"Kilka komputerów" to może być np. trzy jeśli mają być rutowane, bridge'owane albo po prostu od czasu do czasu zmieniają swoje miejsce pobytu. Możesz także chcieć mieć bridge tylko dla zabawy, żeby się dowiedzieć co on robi - ja właśnie dlatego sobie go postawiłem.

Jeśli naprawdę chcesz go postawić z pierwszego powodu, to poczytaj lepiej NET-3-HOWTO albo Serial-HOWTO a znajdziesz tam lepsze obejścia.

Firewall jest ci potrzebny jeśli:

- chronisz swoją sieć przed dostępem z zewnątrz albo
- chcesz zabronić wyjścia poza twoją sieć z jej środka

Ja tu potrzebowałem tego drugiego. Przepisy na naszym uniwersytecie zabraniały nam grać rolę dostawcy Internet-u dla studentów.

## 1.3 Jak.

Zacząłem bridge'ować dwie karty sieciowe w maszynie z firewallem a skończyłem na firewall-owaniu wraz z bridge'owaniem bez usuwania jednej z funkcji. Wydaje się to działać znacznie bardziej wydajnie niż każda z konfiguracji osobno. Mogę na przykład wyłączyć firewall a bridge dalej działa albo odwrotnie jeśli chcę być bardziej bezpieczny.

Stawiałbym na to, że kod bridge'a jest tuż nad fizycznym poziomem urządzenia a kod firewalla jest o jeden poziom wyżej, tak że połaczenie bridge'a z firewallem działa tak jakby to była jedność a nie jakby działały równolegle.

      -> wej. bridge'a -> wej. firewalla -> jądro -> wyj. firewalla -> wyj. bridge'a

Nie ma innego sposobu na wytłumaczenie dlaczego maszyna może być "konduktorem" i izolatorem w tym samym czasie. W każdym razie wydaje się to działać razem bardzo dobrze. Oto co ja robię ...

## 2. Bridge.

## 2.1 Oprogramowanie.

Zdobądź konfigurator do bridge'a BRCFG.tgz.

## 2.2 Najpierw poczytaj.

Przeczytaj Multiple-Ethernet, żeby się dowiedzieć jak rozpoznać i skonfigurować więcej kart sieciowych.

Więcej szczegółów na temat magii startowania, które możesz potrzebować jest w BootPrompt-HOWTO.

Może obędzie się bez NET-3-HOWTO. Jest to dobry i długi dokument i będziesz musiał wybrać sobie to czego potrzebujesz.

## 2.3 Konfiguracja startu systemu.

Po przeczytaniu powyższego dowiesz się, że musisz skompilować jądro, żeby rozpoznało drugie urządzenie ethernet-owe podczas startu oraz, że musisz dodać linię do pliku `/etc/lilo.conf` i uruchomić lilo:

            append = "ether=0,0,eth1"

Zauważ, że jest tu eth1. eth0 jest pierwszą kartą a eth1 jest drugą kartą. Zawsze możesz podać parametry podczas startu kiedy lilo ich oczekuje. Oto przykład dla trzech kart:

            linux ether=0,0,eth1 ether=0,0,eth2

Ja używam loadlin.exe, aby uruchomić Linux-a:

            loadlin.exe c:\vmlinuz root=/dev/hda3 ro ether=0,0,eth1 ether=0,0,eth2

Zauważ, że to zmusza jądro do szukania podczas startu. Nie będzie to miało miejsca jeśli załadujesz sterowniki ethernet-owe jako moduły (ze względów bezpieczeństwa ponieważ kolejność szukania nie może być określona). Więc jeśli używasz modułów, to będziesz musiał dodać parametry określające IRQ i port w pliku `/etc/conf.modules` - to jest mój przykład:

                 alias eth0 3c509
                 alias eth1 de620
                 options 3c509 irq=5 io=0x210
                 options de620 irq=7 bnc=1

Możesz sprawdzić czy używasz modułów przez ps -aux i zobaczenie czy jest proces kerneld i czy w katalogu `/lib/modules/`uname -r`` są pliki *.o. (w miejsce uname -r wstaw wynik tego polecenia). Jeśli masz proces kerneld albo w podanym katalogu są pliki *.o, to wyedytuj plik `/etc/conf.modules` i przeczytaj uważnie stronę podręcznika systemowego na temat depmod.

Zauważ też, że do niedawna (2.0.25) sterownik 3c509 nie mógł być użyty jako moduł dla więcej niż jednej karty. Widziałem gdzieś łatę, która naprawia tę niedogodność. Może on być w jądrze kiedy to czytasz.

## 2.4 Konfiguracja jądra.

Skompiluj jądro z włączoną opcją bridge.

     CONFIG_BRIDGE=y

Ja skompilowałem także z włączonymi opcjami firewalling, IP-forwarding, IP-masquerading i resztą. Ale tylko jeśli chcesz mieć także firewall.

    CONFIG_FIREWALL=y
    CONFIG_NET_ALIAS=y
    CONFIG_INET=y
    CONFIG_IP_FORWARD=y
    CONFIG_IP_MULTICAST=y
    CONFIG_IP_FIREWALL=y
    CONFIG_IP_FIREWALL_VERBOSE=y
    CONFIG_IP_MASQUERADE=y

Nie potrzebujesz tego wszystkiego. To czego potrzebujesz, to standardowa konfiguracja sieci:

    CONFIG_NET=y

i nie sądzę, żebyś się musiał przejmować innymi opcjami związanymi z siecią. Wszystkie opcje, których właściwie nie wkompilowałem w jądro mam dostępne jako moduły i mogę je dodać później.

Zainstaluj nowe jądro, uruchom lilo i zresetuj z nowym jądrem. W tym momencie nic się nie powinno zmienić.

## 2.5 Adresy sieciowe.

Chris twierdzi, że bridge nie powinien mieć adresu IP, ale to nie jest to ustawienie opisane tutaj.

Będziesz chciał używać tej maszyny do łączenia się z siecią więc potrzebujesz adresu i musisz się upewnić, że masz skonfigurowane poprawnie urządzenie "loopback", tak żeby twoje oprogramowanie mogło komunikować się z miejscami, z którymi spodziewa się, że będzie się mogło porozumieć. Jeśli nie będzie tego urządzenia, to serwis nazw albo inny serwis sieciowy może nie działać. Przeczytaj NET-3-HOWTO, ale twoja standardowa konfiguracja powinna już to za ciebie zrobić:

       ifconfig lo 127.0.0.1
       route add -net 127.0.0.0

Będziesz musiał nadać adres obojgu kartom. Ja dopasowałem swój `/etc/rc.d/rc.inet1` w Slackware 3.x, aby ustawić moje dwie karty. A ty powinieneś także poszukać gdzie jest konfiguracja sieci u ciebie i podwoić instrukcje. Załóżmy, że masz już adres: 192.168.2.100 (jest to prywatny zarezerwowany adres sieciowy, ale nieważne - nikomu nie zaszkodzi jeśli użyjesz tego adresu przez pomyłkę) wtedy masz już pewnie linię:

      ifconfig eth0 192.168.2.100 netmask 255.255.255.0 metric 1

w swojej konfiguracji. Pierwsze co pewnie będziesz chciał zrobić to podzielić przestrzeń adresową na pół, tak że możesz potem te dwie połowy bridge'ować. Więc dodaj linię. która zredukuje maskę tak, że będzie ona adresować mniejszą ilość maszyn:

      ifconfig eth0 netmask 255.255.255.128

Spróbuj tego też. Powoduje to obcięcie przestrzeni adresowej do zakresu od .0 do .127.

Teraz możesz ustawić swoją drugą kartę w drugiej połowie adresów. Upewnij się, że nikt jeszcze takiego adresu nie ma. Dla symetrii ja ustawiłem ją na 228 (128+100=228). Każdy adres będzie się tak zachowywał dopóki nie znajdzie się w masce tej pierwszej karty - a nawet wtedy, no może. Unikaj adresów specjalnych takich jak .0, .1, .128 o ile naprawdę wiesz co robisz.

      ifconfig eth1 192.168.2.228 netmask 255.255.255.128 metric 1

To powoduje zmniejszenie zakresu adresów drugiej karty do .128 do .255.

## 2.6 Ruting sieci.

Powyższe może być wystarczającą konfiguracją dla działającego bridge'a, ale ja będę miał także firewall i chcę kontrolować fizyczne przeznaczenie niektórych pakietów. Nawet wtedy trzeba się pilnować przed spoofingiem.

Mam małą sieć maszyn dołączonych do hub-a na eth0, więc konfiguruję tam sieć:

      route add -net 192.168.2.128 netmask 255.255.255.128 dev eth0

128 byłoby 0 gdybym miał pełną klasę C. "dev eth0" nie jest tu potrzebne ponieważ adres karty zalicza się do tej sieci, ale może być potrzebne dla ciebie.

Na drugiej karcie mam linię idącą prosto do dużego rutera, któremu ufam.

                                                client 129
             __                                        |     __
    client 1   \    .0                    .128         |   /   net 1
    client 2 --- Hub - eth0 - Kernel - eth1 - Hub - Router --- net 2
    client 3 __/       .100            .228         .2 |   \__ net 3
                                                       |
                                                client 254

Dołączam adres tego rutera do tej karty jako statyczny ponieważ inaczej zaliczałby się on do maski tej pierwszej karty i jądro źle kierowałoby pakiety do tego dużego rutera.

      route add 192.168.2.2 dev eth1

Ja go nie potrzebuję ponieważ nie mam więcej maszyn w tej połówce przestrzeni adresowej, ale deklaruję sieć także na tej drugiej karcie

      route add -net 192.168.2.128 netmask 255.255.255.128 dev eth1

Muszę także wysłać wszystkie nie lokalne pakiety w świat, więc informuję jądro, żeby wysyłało je do dużego rutera:

      route add default gw 192.168.2.2

## 2.7 Konfiguracja karty.

To tyle odnośnie standardowego ustawiania sieci, ale my mamy bridge więc musimy na obydwu (?) kartach słuchać pakietów, które nie są przeznaczone dla nas. Następujące dwie linie powinny się znaleźć w pliku konfigurującym sieć:

      ifconfig promisc eth0
      ifconfig promisc eth1

Na stronie podręcznika systemowego napisane jest, że allmulti=promisc, ale u mnie to nie działało.

## 2.8 Dodatkowy ruting.

Jedno co zauważyłem, to to, że musiałem przynajmniej drugą kartę ustawić w tryb, w którym odpowiadałaby ona dużemu ruterowi jakie maszyny chowam w swojej sieci.

      ifconfig arp eth1

Na wszelki wypadek zrobiłem to samo dla pierwszej karty.

      ifconfig arp eth0.

## 2.9 Konfiguracja Bridge'a.

Umieść włączanie bridge'owania w swoim pliku konfiguracyjnym:

        brcfg -enable

Powinieneś to próbować w czasie rzeczywistym cały czas oczywiście! Konfigurator bridge'a poda parę liczb. Możesz poeksperymentować włączając i wyłączając porty - jeden za każdym razem.

       brcfg -port 0 -disable/-enable
       brcfg -port 1 -disable/-enable

Polecenie brcfg pokaże ci raport w każdej chwili. Zobaczysz, że bridge słucha, dowiaduje się i potem przekazuje pakiety. (Nie rozumiem dlaczego kod powtarza te same adresy sprzętowe dla obu moich kart, ale nieważne ... HOWTO Chrisa mówi, że to dobrze)

## 2.10 Wypróbuj.

Jeśli cały czas wszystko u ciebie działa, to wypróbuj swoją konfigurację w rzeczywistości - wyłącz obie karty i uruchom swój plik konfiguracyjny:

        ifconfig eth0 down
        ifconfig eth1 down
        /etc/rc.d/rc.inet1

Jeśli masz szczęście, to różne podsystemy (nfs, ypbind, itp) nie zauważą tej zmiany. Nie próbuj tego o ile nie siedzisz przy klawiaturze.

Jeśli chcesz być bardziej ostrożny niż teraz, powinieneś wyłączyć tyle demonów ile się da i odmontować katalogi nfs. Najgorszym co może się stać, to to, że będziesz musiał zrestartować komputer w trybie jednego użytkownika (parametr "single" dla lilo lub loadlin) i zmienić wszystko na stan taki jaki był przed zmianą konfiguracji.

## 2.11 Sprawdzenia.

Sprawdź czy na każdym interfejsie jest inny ruch:

            tcpdump -i eth0    (w jednym oknie)
            tcpdump -i eth1    (w drugim oknie)

Powinieneś się przyzwyczaić do używania tcpdump do szukania przyczyn niektórych zdarzeń, które nie powinny mieć miejsca a mają.

Na przykład szukanie pakietów, które przeszły przez bridge do drugiej karty z wewnętrznej sieci. W tym przykładzie szukam pakietów z maszyny o adresie .22:

           tcpdump -i eth1 -e host 192.168.2.22

Potem wyślij ping-a z maszyny .22 do rutera. Powinieneś zobaczyć raport o tym pakiecie.

W tym momencie powinieneś mieć w pełni działający bridge z dwoma adresami. Sprawdź czy możesz je pingować z zewnątrz i z wewnątrz sieci oraz, że możesz się łączyć z jednej sieci do drugiej i z zewnątrz.

## 3. Firewall.

## 3.1 Oprogramowanie i czytanie.

Powinieneś przeczytać Firewall-HOWTO.

Dowiesz się stamtąd skąd wziąć ipfwadm jeśli jeszcze go nie masz. Są jeszcze inne narzędzia, które możesz ściągnąć, ale ja nie zrobiłem nic dalej bez ipfwadm. Jest on dość przyjazny i niskopoziomowy ! Widzisz dokładnie co się dzieje.

## 3.2 Sprawdzenie wstępne.

Wkompilowałeś IP-forwarding i -masquerading w jądro, więc możesz sprawdzić czy firewall jest w swoim domyślnym (akceptującym) stanie poleceniami:

           ipfwadm -I -l
           ipfwadm -O -l
           ipfwadm -F -l

I tak odpowiednio wyświetlane są zasady dotyczące wchodzących, wychodzących i przekazywanych (masquerading) pakietów. -l oznacza "list".

Możliwe, że wkompilowałeś także zliczanie (accounting):

           ipfwadm -A -l

Powinieneś zobaczyć, że nie ma zdefiniowanych żadnych zasad i że domyślnym stanem jest akceptacja wszystkich pakietów. Możesz wrócić do tego stanu w każdej chwili pisząc:

           ipfwadm -I -f
           ipfwadm -O -f
           ipfwadm -F -f

-f oznacza "flush". Możliwe, że musisz tego użyć.

## 3.3 Zasady domyślne.

Chcę po prostu odciąć resztę świata od swojej sieci wewnętrznej i nic więcej, tak więc ostatnią (domyślną) zasadą będzie ignorowanie wszelkich pakietów pochodzących z wnętrza sieci i zaadresowanych na zewnątrz. Umieściłem wszystkie te zasady (w takiej kolejności) w `/etc/rc.d/rc.firewall` i wykonuję ten skrypt z `rc.local` podczas startu.

      ipfwadm -I -a reject -S 192.168.2.0/255.255.255.128 -D 0.0.0.0/0.0.0.0

-S oznacza źródłowy (source) adres/maskę. -D to adres/maska przeznaczenia (destination).

Ten format dla ipfwadm-a jest trochę długi. Program ten jest inteligentny jeśli chodzi o nazwy sieciowe i niektóre popularne skróty. Zajrzyj do podręcznika systemowego.

Przypuszczalnie bardziej wygodnie jest określać niektóre lub wszystkie zasady dla wychodzącej połowy firewall-a używając opcji -O zamiast -I, ale ja określę je dla części wchodzącej.

## 3.4 Dziury na adres.

Przed zasadami domyślnymi muszę umieścić kilka zasad, które służą jako wyjątek od ogólnego zabronienia dostępu do serwisów zewnętrznych dla klientów wewnętrznych.

Chcę traktować adres firewall-a w sieci wewnętrznej specjalnie. Zabronię logowania się na tę maszynę o ile ktoś nie ma specjalnego pozwolenia, ale jak już się tam zalogują, to powinni mieć możliwość kontaktu ze światem.

      ipfwadm -I -i accept -S 192.168.2.100/255.255.255.255 \
                           -D 0.0.0.0/0.0.0.0

Chcę także, aby klienci wewnątrz sieci mogli się komunikować z firewall-em. Może mogą go zmusić, aby wypuścił ich na zewnątrz !

      ipfwadm -I -i accept -S 192.168.2.0/255.255.255.128 \
                           -D 192.168.2.100/255.255.255.255

W tym momencie sprawdź czy możesz się dostać do klientów wewnątrz sieci z zewnątrz poprzez telnet i nie możesz się wydostać. Oznacza to, że możesz się kontaktować, ale klienci nie mogą ci odpowiedzieć. Powinieneś móc się dostać wszystkimi drogami jeśli używasz firewall-a jako maszyny przejściowej. Spróbuj także rlogin i ping z uruchomionym tcpdump na jednej z kart. Powinieneś umieć odpowiednio wykorzystać to co robisz.

## 3.5 Dziury na protokół.

W następnym kroku poluźniłem trochę zasady protokół po protokole. Chcę, na przykład, wpuszczać ping-i, żeby dostać odpowiedź.

      ipfwadm -I -i accept -P icmp -S 192.168.2.0/255.255.255.128 \
                                   -D 0.0.0.0/0.0.0.0

-P icmp to magiczne zaklęcie dla konkretnego protokołu.

Dopóki trzymam ftp-proxy pozwalam także na odwołania ftp na zewnątrz przez konkretne porty. Te docelowe porty na odległej maszynie to: `20, 21, 115`

      ipfwadm -I -i accept -P tcp -S 192.168.2.0/255.255.255.128 \
                                   -D 0.0.0.0/0.0.0.0 20 21 115

Bez działającego serwera nazw nie mógłbym mieć działającego sendmail-a. Zamiast ustawić serwer nazw na firewall-u, pozwoliłem mu przepuszczać zapytania skierowane do najbliższego serwera nazw i umieściłem jego adres w plikach `/etc/resolv.conf` u klientów - nameserver 123.456.789.31 - w osobnej linijce.

      ipfwadm -I -i accept -P tcp -S 192.168.2.0/255.255.255.128 \
                                   -D 123.456.789.31/255.255.255.255 54

To, którego portu używa dany serwis możesz dowiedzieć się z programu tcpdump. Po prostu uruchom dany serwis przez ftp, albo telnet na danym kliencie i szukaj go na portach wejściowych albo wyjściowych na danym kliencie:

      tcpdump -i eth1 -e host client04

Plik `/etc/services` jest drugim ważnym źródłem.

Aby pozwolić na dostęp poprzez telnet do firewall-a z zewnątrz, musisz pozwolić klientom na wołanie na konkretnym porcie. Rozumiem dlaczego jest to potrzebne dla ftp - z powodu serwera, który ustawia strumień danych na końcu - ale nie jestem pewien dlaczego telnet także tego potrzebuje.

      ipfwadm -I -i accept -P tcp -S 192.168.2.0/255.255.255.128 ftp telnet \
                                   -D 0.0.0.0/0.0.0.0

Są problemy z pewnymi demonami, które sprawdzają nazwę firewall-a, żeby zdecydować jaki jest ich adres sieciowy. rpc.yppasswdd to jeden, z którym miałem problemy. Nalegał na rozsyłanie informacji, że jest on poza firewall-em (na drugiej karcie). To znaczy, że klient wewnątrz nie może się z nim porozumieć.

Zamiast uruchamiania IP-aliasing-u, albo zmiany kodu demona, odwzorowałem nazwę dla karty wewnętrznej u klientów w ich plikach `/etc/hosts`.

## 3.6 Sprawdzenia.

Teraz chcesz sprawdzić czy wciąż możesz połączyć się telnet-em, rlogin-em lub ping-ować z zewnątrz. Z wewnątrz powinieneś móc ping-ować na zewnątrz. Powinieneś móc także połączyć się telnet-em z firewall-em z wewnątrz a później móc robić wszystko.

To tyle. W tym momencie możesz się pouczyć o rpc/Yellow Pages i interakcji z plikiem haseł. Sieć chroniona firewall-em powinna działać tak, aby nie pozwalać nieuprzywilejowanym użytkownikom na logowanie się na firewall-u i przez to na wychodzenie na zewnątrz.. A to już historia na inne HOWTO.

## 4. Od tłumacza.

Tłumaczenie to jest chronione prawami autorskimi © Bartosza Maruszewskiego. Dozwolone jest rozprowadzanie i dystrybucja na prawach takich samych jak dokument oryginalny.

Jeśli znalazłeś jakieś rażące błędy ortograficzne, gramatyczne, składniowe, techniczne to pisz do mnie:

B.Maruszewski@jtz.org.pl

Oficjalną stroną tłumaczeń HOWTO jest http://www.jtz.org.pl/

Aktualne wersje przetłumaczonych dokumentów znajdują się na tejże stronie. Dostępne są także poprzez anonimowe ftp pod adresem ftp.jtz.org.pl w katalogu `/HOWTO`.

Przetłumaczone przeze mnie dokumenty znajdują się także na mojej stronie WWW. Są tam też odwołania do Polskiej Strony Tłumaczeniowej.

Kontakt z naszą grupą, grupą tłumaczy możesz uzyskać poprzez listę dyskusyjną jtz@ippt.gov.pl. Jeśli chcesz się na nią zapisać, to wyślij list o treści `subscribe jtz Imię Nazwisko` na adres `majordomo@ippt.gov.pl`