Trzecia część poradnika dotyczy routingu w systemach Linux. To temat, który na początku może wydawać się trochę abstrakcyjny, bo pojawiają się takie pojęcia jak tablica routingu, brama, interfejs sieciowy czy trasa statyczna. W praktyce jednak całość sprowadza się do bardzo prostego pytania: którędy system ma wysłać pakiet, aby dotarł on do właściwej sieci? Jeśli Linux zna drogę, komunikacja działa poprawnie. Jeśli nie zna, pakiet po prostu nie dotrze tam, gdzie powinien.
Routing to proces podejmowania decyzji o przekazywaniu pakietów pomiędzy interfejsami sieciowymi. Decyzje te opierają się na tablicy routingu, czyli zbiorze wpisów mówiących systemowi, jak dostać się do określonych sieci. Gdy host zna docelowy adres IP, porównuje go z trasami zapisanymi w tablicy i wybiera wpis, który najlepiej pasuje do danego celu. Jest to artykuł dotyczący konfiguracji routingu w Linuxie, dlatego nie wchodzę za dużo w szczegóły. Jeśli chcesz wiedzieć więcej na temat routingu to serdecznie zapraszam do artykułu na ten temat.
Ten artykuł domyka serie związaną z konfiguracją sieci w Linuxie. W pierwszej części przygotowaliśmy adresację i interfejsy sieciowe na wszystkich maszynach, w drugiej uporządkowaliśmy nazwy hostów i mechanizmy rozwiązywania nazw, a teraz dokładamy ostatni brakujący element, czyli trasy pomiędzy podsieciami. Dopiero po połączeniu tych trzech warstw całe laboratorium zaczyna działać jak spójna, większa sieć.
Jak sprawdzić tablicę routingu w Linuxie?
Tablicę routingu w Linuxie można sprawdzić na kilka sposobów. Najczęściej spotkasz dwa polecenia:
route
ip route
Starsze polecenie route nadal pojawia się w wielu poradnikach i materiałach szkoleniowych, dlatego warto je znać. Trzeba jednak pamiętać, że dziś zdecydowanie częściej używa się polecenia ip route, które jest nowocześniejsze i należy do pakietu iproute2. W praktyce oznacza to, że jeśli pracujesz na nowszym systemie, to właśnie ip route będzie zwykle lepszym wyborem.
Poniżej znajduje się przykładowy wynik polecenia route. Widzimy tam kilka wpisów opisujących trasy do różnych sieci. Każda linia mówi systemowi coś ważnego: dokąd prowadzi dana trasa, czy wymaga użycia bramy i przez jaki interfejs ma zostać wysłany ruch. Zanim przejdziemy do konfiguracji, warto najpierw spokojnie zrozumieć znaczenie poszczególnych kolumn.

Co oznaczają kolumny w tablicy routingu?
Kolumna Destination wskazuje sieć docelową, czyli adres sieci, do której prowadzi dana trasa. To właśnie na podstawie tej wartości system porównuje, czy dany pakiet powinien zostać wysłany tą drogą. Jeśli pakiet pasuje do tej sieci, Linux bierze pod uwagę pozostałe informacje z wiersza. To podstawowy punkt odniesienia dla całego procesu routingu.
Kolumna Gateway określa bramę, czyli urządzenie pośredniczące, przez które trzeba przejść, aby dotrzeć do danej sieci. Jeśli w tej kolumnie pojawia się adres IP, oznacza to, że pakiet nie trafi do celu bezpośrednio, tylko najpierw zostanie wysłany do innego hosta — zwykle routera. Jeżeli natomiast bramy nie ma, ruch trafia bezpośrednio przez wskazany interfejs. To bardzo ważna różnica, bo pokazuje, czy mówimy o sieci lokalnej, czy o sieci znajdującej się dalej.
Kolumna Genmask zawiera maskę sieci, która określa zakres adresów objętych daną trasą. Dzięki niej system wie, jak duża jest dana sieć i które adresy IP należą do tego wpisu. W kolumnie Flags możesz zobaczyć między innymi litery U oraz G. U oznacza, że trasa jest aktywna, natomiast G informuje, że do jej użycia potrzebna jest brama.
Na końcu znajduje się kolumna Iface, która wskazuje interfejs sieciowy używany do wysłania pakietów. To właśnie nim ruch opuści system w kierunku sieci docelowej. W praktyce oznacza to, że nawet jeśli system zna poprawną bramę, nadal musi wiedzieć, przez który fizyczny lub wirtualny interfejs ma się z nią komunikować.
Wpisy w tablicy można podzielić na wpisy sieci bezpośrednio połączonych, i wpisy sieci zdalnych. Sieci bezpośrednio połączone są automatycznie dodawane do tablicy routingu w momencie połączenia ze sobą dwóch komputerów. Wpisy sieci zdalnych musimy skonfigurować ręcznie. Są to wpisy kierujące do innych sieci, takich z którymi nie mamy kontaktu.
Konfiguracja routingu
Zanim przejdziesz dalej, upewnij się, że wcześniejsze elementy serii są już gotowe. Wszystkie hosty powinny mieć poprawnie ustawione adresy IP, maski i bramy, a jeśli testujesz komunikację po nazwach, również odpowiednio skonfigurowane hostname, hosts albo DNS. Routing nie naprawi błędnej adresacji ani źle ustawionych nazw – on tylko mówi systemowi, którędy wysłać pakiet do innej sieci.

Routing należy skonfigurować na tych hostach, które pełnią rolę routerów brzegowych pomiędzy różnymi sieciami. W tym przykładzie będą to Debian oraz CentOS. To właśnie one mają więcej niż jeden interfejs i mogą przekazywać ruch pomiędzy segmentami sieci. Dodatkowo pokażę też, jak podobną konfigurację można wykonać na Ubuntu.
Włączanie routingu w Linuxie
Zanim Linux zacznie pełnić rolę routera, trzeba włączyć w nim przekazywanie pakietów IPv4. Domyślnie większość systemów działa jak zwykły host, czyli odbiera ruch skierowany do siebie, ale nie przekazuje go dalej pomiędzy interfejsami. Jeśli więc komputer ma routować pakiety między dwiema sieciami, ten mechanizm trzeba aktywować. Bez tego nawet poprawnie dodane trasy niewiele pomogą.
Status przekazywania pakietów możesz sprawdzić poleceniem:
sysctl net.ipv4.ip_forward
Jeśli zobaczysz wartość 0, oznacza to, że routing jest wyłączony. Wartość 1 oznacza, że system może już przekazywać pakiety między interfejsami. To bardzo ważny parametr, bo od niego zależy, czy Linux będzie zachowywał się jak host, czy jak router.
Aby włączyć routing tymczasowo, możesz użyć polecenia:
sysctl -w net.ipv4.ip_forward=1
Jeżeli chcesz, aby ustawienie przetrwało restart systemu, najlepiej dopisać odpowiedni wpis do konfiguracji sysctl, na przykład w pliku /etc/sysctl.conf. Następnie należy przeładować konfigurację.
echo net.ipv4.ip_forward=1 > /etc/sysctl.conf
sysctl -p
Ten krok wykonujemy na Debianie i CentOS-ie, bo to one w naszej topologii pełnią rolę hostów pośredniczących pomiędzy sieciami. Same hosty końcowe, takie jak Ubuntu, Windows CL1 i Windows CL2, nie muszą mieć włączonego przekazywania pakietów – one mają przede wszystkim wiedzieć, do jakiej bramy domyślnej wysłać ruch poza swoją lokalną podsieć. I właśnie dlatego tak ważna była poprawna konfiguracja z pierwszego artykułu.
Dodawanie tras w Debianie
Spójrzmy teraz na praktyczny przykład. Załóżmy, że system Debian ma komunikować się z siecią 172.16.20.0/24, która znajduje się za systemem CentOS. W tej chwili Debian nie zna tej sieci, więc nie wie, gdzie powinien wysyłać pakiety do tego segmentu. Musimy więc dodać trasę statyczną, która nauczy go, że droga do tej sieci prowadzi przez odpowiednią bramę. To właśnie jest sedno routingu statycznego: system nie zgaduje, tylko korzysta z wpisu, który mu dodamy.
W Debianie jedną z klasycznych metod trwałego dodawania tras jest wykorzystanie pliku /etc/network/interfaces. W odpowiedniej sekcji interfejsu można umieścić polecenie wykonywane po jego uruchomieniu.
Przykładowy wpis może wyglądać tak:
up ip route add 172.16.20.0/24 via 192.16.0.20
Taki zapis mówi systemowi: aby dostać się do sieci 172.16.20.0/24, wyślij pakiety do hosta 192.16.0.20, który zna dalszą drogę. Oczywiście adres tej bramy musi należeć do urządzenia, z którym Debian jest bezpośrednio połączony. Po zapisaniu zmian należy przeładować konfigurację sieci, na przykład poleceniem:
systemctl restart networking
Po wszystkim warto sprawdzić wynik:
ip route
Dzięki temu od razu zobaczysz, czy nowa trasa została poprawnie dodana do tablicy routingu.

Dodawanie tras statycznych w CentOS
Sama konfiguracja trasy po stronie Debiana nie wystarczy, jeśli komunikacja ma działać w obie strony. Jeżeli Debian nauczy się drogi do sieci znajdującej się za CentOS-em, ale CentOS nie będzie znał trasy powrotnej do sieci za Debianem, odpowiedzi nie wrócą poprawnie. To bardzo częsty błąd u początkujących. Z jednej strony wszystko wygląda sensownie, ale połączenie nadal nie działa, bo druga strona nie wie, gdzie odesłać pakiety.
W systemach takich jak CentOS czy Fedora bardzo wygodnym narzędziem do konfiguracji sieci jest nmcli. Pozwala ono dodać trasę statyczną do konkretnego połączenia sieciowego bez ręcznego edytowania plików konfiguracyjnych. To rozwiązanie jest czytelne i dobrze wpisuje się w środowiska korzystające z NetworkManagera. Dzięki temu konfiguracja jest stosunkowo prosta i łatwa do późniejszego sprawdzenia.
Przykładowe polecenie może wyglądać tak:
nmcli connection modify enp0s8 +ipv4.routes "172.16.10.0/24 192.16.0.10"
nmcli connection up enp0s8
nmcli connection reload
W tym przypadku uczymy system, że aby dostać się do sieci 172.16.10.0/24, trzeba wysłać ruch do bramy 192.16.0.10. Jest to adres routera, który zna dalszą drogę do tej sieci. Tak jak wcześniej, po aktywowaniu połączenia warto sprawdzić wynik poleceniem ip route.

Dodawanie tras w Ubuntu
W nowszych wersjach Ubuntu konfiguracja sieci najczęściej opiera się na Netplanie. Oznacza to, że zamiast ręcznie dopisywać polecenia do skryptów startowych, możesz dodać trasy bezpośrednio w pliku YAML. To rozwiązanie jest całkiem czytelne i logiczne, choć trzeba uważać na wcięcia.
Załóżmy, że z systemu Ubuntu chcemy skomunikować się z siecią znajdującą się za Debianem. Jeśli Ubuntu nie zna tej sieci bezpośrednio, trzeba wskazać mu właściwą bramę. W naszym przykładzie ruchem do sieci 172.16.10.0/24 ma zarządzać Centos, który pełni rolę bramy domyślnej w Ubuntu. To właśnie jego adres IP musi zostać użyty jako kolejny krok na drodze do sieci docelowej. Bez tego Ubuntu nie będzie wiedziało, w którą stronę wysłać ruch. Ubuntu również musi znać drogę do sieci 192.16.0.0 ponieważ to kolejna sieć, która stoi na drodze do Windowsa. Należy dodać dwie trasy, które umieszczam na screenie poniżej.
Zauważyłem, że dodatkowo warto wyłączyć bramę domyślną przypisywaną z DHCP na interfejsie enp0s3. W przeciwnym wypadku psuje ona tablice routingu i pakiety wędrują nie tam gdzie trzeba.
Poniżej umieszczam działającą konfiguracje w Ubuntu.

W tym zapisie sekcja “to” określa sieć docelową, a via wskazuje bramę, przez którą należy przesłać ruch. Po zapisaniu pliku trzeba zastosować konfigurację poleceniem:
netplan apply
Tak jak wcześniej, po aktywowaniu połączenia warto sprawdzić wynik poleceniem ip route.

Jak sprawdzić, czy routing działa?
Przy testowaniu routingu bardzo łatwo skupić się tylko na routerach, a pominąć hosty końcowe. Tymczasem poprawna komunikacja w naszym laboratorium wymaga, żeby każda maszyna miała właściwą konfigurację dla swojej roli: Debian i CentOS muszą przekazywać pakiety i znać trasy do zdalnych sieci, a Ubuntu oraz hosty Windows muszą mieć poprawnie ustawione bramy domyślne. Jeśli dodatkowo testujesz po nazwach, to dochodzi jeszcze konfiguracja z poprzedniego artykułu, czyli hosts, DNS i hostname. Jeśli testy ping pomiędzy wszystkimi maszynami wychodzą pomyślnie, to znak, że cała seria została złożona w jedną działającą całość. U mnie komunikacja z Ubuntu do Debiana i Windowsa CL1 przebiega od tej pory pomyślnie.
