Wprowadzenie do planowania adresacji sieci

Zgodnie z wcześniejszą zapowiedzią, dziś publikuję kolejny artykuł poświęcony sprawom sieciowym i narzędziom wspomagającym administratora w zarządzaniu sieciami.netzwerkleitung-network-cable-luetze-980x200Tym razem chciałbym skupić się na czymś być może elementarnym, ale za to bardzo istotnym. Chodzi o planowanie adresacji IP dla dużych sieci. Istotność tego zagadnienia wynika wprost z powagi możliwych do popełnienia błędów i ich konsekwencji ujawniających się na ogół na późniejszych etapach zarządzania siecią czy funkcjonowania sieci, kiedy istotnym problemem mogą okazać się nieakceptowalne limity skalowalności, krytyczne ograniczenia  przy zmianach strategii routingu, niestabilność ścieżek routingu, niemożność należytej optymalizacji routingu czy choćby trudności z filtrowaniem ruchu w sieci przy pomocy list dostępowych (ACL) na routerach albo firewallach sieciowych.

Ale spróbujmy do tematu podejść w sposób systematyczny i przyglądnąć się po kolei poszczególnym zagadnieniom, zaczynając od podstaw.

Podstawy – Klasy adresowe

O przynależności adresu do określonej klasy adresowej decyduje wzorzec najstarszych bitów pierwszego oktetu adresu (reguła pierwszego oktetu).  Choć dla osób, które na co dzień nie przeliczają adresów i masek może to brzmieć nieco tajemniczo, to zasada jest niezwykle prosta. Wygląda to tak:

Możemy wyobrazić sobie 32-bitowy adres IP jako zbiór 4 oktetów (bajtów). Bity pierwszego oktetu ponumeruję zaczynając od najstarszego – od 0 do 7.

0 1 2 3 4 5 6 7
pierwszy oktet

Każdy bit może przyjmować wartość 0 (bit ‘zgaszony’) lub 1 (bit ‘zapalony’), co jest oczywiście prawidłowością w binarnym (dwójkowym) systemie liczbowym.

Wartości dwójkowe bitów w oktetach można przeliczyć na wartości dziesiętne oktetów, w przeciwnym razie bylibyśmy zmuszeni stosować niewygodny zapis dwójkowy zamiast wykorzystywanego powszechnie systemu dziesiętnego kropkowego (na przykład 11000000.10101000.00000001.00000001 zamiast 192.168.1.1). Każdy z bitów oktetu ma swoją wartość dziesiętną, a im bit jest starszy (im ma niższy numer czyli leży bardziej „na lewo” w naszym schemacie), tym jego wartość dziesiętna jest większa. Wartości dziesiętne poszczególnych pozycji bitowych wynoszą dla bitów oktetu odpowiednio:

128

(27)

64

(26)

32

(25)

16

(24)

8

(23)

4

(22)

2

(21)

1

(20)

Jak łatwo obliczyć, na przykład wartości dziesiętnej oktetu 192 odpowiada binarnie 11000000. Przeprowadzamy po prostu sumowanie wartości dziesiętnych poszczególnych pozycji bitowych otrzymując w efekcie dziesiętną wartość oktetu.

Ale wracając do reguły, która rządzi przynależnością adresu do określonej klasy adresowej, to jest ona bardzo prosta. Jak wcześniej wspomniałem decydujące znaczenie ma wzorzec najstarszych bitów pierwszego oktetu. Dla poszczególnych klas adresowych przedstawia się on następująco:

0    – Klasa A
10   – Klasa B
110  – Klasa C
1110 – Klasa D (multicast)
1111 – Klasa E (eksperymentalna)

Stosując przeliczenia wartości binarnych na dziesiętne, łatwo obliczyć zakresy adresów sieci należących do poszczególnych klas.

Wszystkie sieci klasy A muszą mieć ‘zgaszony’ najstarszy bit pierwszego oktetu, zatem dopuszczalny zakres adresów, wyrażony binarnie, to: 00000001-01111111.  Sumując wartości dziesiętne poszczególnych pozycji bitowych, otrzymujemy zakres 1-127, choć proszę pamiętać, że adresy zaczynające się od 127 są w świecie IP zarezerwowane na potrzeby tzw. pętli zwrotnej (loopback) czyli lokalnego hosta. Innymi słowy, każdy host może „zagadać” do samego siebie wysyłając po IP komunikat na adres pętli zwrotnej. Przyjęło się, że jest to adres 127.0.0.1, aczkolwiek równie dobrze może to być przykładowo 127.100.100.100. Liczy się tu jedynie wartość pierwszego oktetu, czyli 127 (binarnie: 01111111).  Zatem, ze względu na to, że adresy zaczynające się 127 są zarezerwowane (pętla zwrotna), zakres wartości pierwszego oktetu adresów sieci klasy A wynosi 1-126.

Adresy sieci klasy B zawierają się w przedziale: binarnie od 10000000 do 10111111 (proszę zwrócić uwagę na stały typowy dla tych adresów wzorzec najstarszych bitów: ‘10’). Dziesiętny ekwiwalent zakresu wartości pierwszego oktetu adresów klasy B, to: 128-191. Klasę C tworzą adresy z zakresu wartości pierwszego oktetu: binarnie od 11000000 do 11011111 czyli 192-223. Klasa D (multicast) to binarnie: 11100000-11101111 (224-239), wreszcie klasa eksperymentalna to binarnie: 11110000-11111111 (240-255).

By zakończyć temat podziału przestrzeni adresowej na klasy, należy jedynie wspomnieć, że sieci klasy A mają maskę (prefiks czyli część sieciową adresu) 8-bitową (255.0.0.0), klasy B – 16-bitową (255.255.0.0), natomiast klasy C – 24-bitową (255.255.255.0).

Podstawy – Adresacja prywatna versus publiczna oraz translacja adresów

Gdyby wszystkie aktualnie podłączone do Internetu komputery miały mieć publiczne adresy IP, już dawno doszłoby do wyczerpania całej dostępnej ich puli. Mówimy tu oczywiście o protokole IP w wersji czwartej, ponieważ specyfikacja wersji szóstej radzi sobie doskonale z problemem dostępności adresów (przynajmniej na miarę aktualnych potrzeb), oferując 128 bitową przestrzeń adresową. Sprytne rozwiązanie które na wiele lat uratowało protokół IP w wersji czwartej od wróżonej mu rychłej śmierci, polegało zastosowaniu prywatnych adresów IP w sieciach poszczególnych organizacji czy dostawców usług dostępowych do Internetu klientom indywidualnym, przy zastosowaniu translacji tych właśnie prywatnych adresów IP na styku ich sieci i Internetu (na tzw. bramkach translacji). Translacja polegała na „tłumaczeniu” prywatnych adresów organizacji na jeden lub kilka adresów publicznych w sytuacji zaspokojenia potrzeby komunikowania się ze światem zewnętrznym w globalnej sieci Internet. Pule adresów sieci niepropagowanych w Internecie, z których możemy czerpać na potrzeby adresowania sieci prywatnych zostały wyszczególnione w dokumencie IETF RFC 1918. Dla przypomnienia podam, że chodzi o następujące zakresy adresów:

10.0.0.0 – 10.255.255.255 (1 sieć klasy A)
172.16.0.0 – 172.31.255.255 (15 sieci klasy B)
192.168.0.0 – 192.168.255.255 (255 sieci klasy C)

Idea stosowania adresacji prywatnej polega na tym, że hosty (komputery i inne urządzenia końcowe oraz serwery), a także urządzenia infrastruktury sieciowej, będące własnością lub zarządzane przez określoną organizację, komunikują się pomiędzy sobą, w obrębie domeny przedsiębiorstwa, czyli w obrębie sieci prywatnej, stosując właśnie adresy prywatne. Jeśli jednak trzeba zapewnić im komunikację ze światem zewnętrznym, z globalną siecią Internet, to rzecz jasna, należy w tym celu przeprowadzić translację ich adresów prywatnych na publiczne, routowalne w Internecie. W przeciwnym razie ruch z komputerów z naszej sieci mógłby co prawda wyjść poza lokalną bramkę sieciową (router czy firewall) przedsiębiorstwa, ale ruch zwrotny w ramach nawiązanych połączeń nie miałaby szans, z powodów oczywistych, dotrzeć do źródła (sieci prywatne nie są routowalne w Internecie i nie podlegają centralizacji zarządzania, jak sieci publiczne). Przeciwdziałaniu tego typu problemom służy translacja adresów prywatnych na publiczne z wykorzystaniem protokołu NAT (Network Address Translation) – translacja jeden-do-jednego: jeden adres prywatny na jeden adres publiczny (stosowana przeważnie dla publicznie dostępnych serwerów przedsiębiorstwa, na przykład głównej witryny WWW oraz serwerów strefy e-commerce), a najczęściej PAT (Port Address Translation) – translacja wiele-do-jednego: wiele prywatnych adresów korzysta przy komunikowaniu się z siecią Internet z jednego publicznego adresu IP, a jednoznaczność takiego mapowania jest zapewniona przez mapowania portów protokołu TCP czy UDP. Translacja, o której mowa, zapewniana jest przeważnie statycznie dla serwerów i na ogół dynamicznie dla komputerów użytkowników końcowych. Dla potrzeb translacji adresów serwerów stosowany jest statyczny NAT, zaś dla potrzeb komputerów i urządzeń użytkowników końcowych – PAT, pozwalający wykorzystać jeden lub zaledwie kilka adresów publicznych, jakimi dysponuje przedsiębiorstwo, do zapewnienia komunikacji wszystkim swoim użytkownikom z zasobami Internetu.

Skalowalność adresacji

Planując adresację IP należy robić to w ten sposób, aby alokować ciągłe bloki adresów na potrzeby poszczególnych segmentów sieci, z uwzględnieniem liczby hostów w poszczególnych segmentach. Problem na ogół polega na tym, aby projektowanym planem adresowym zaspokoić nie tylko bieżące potrzeby, ale także dające się przewidzieć potrzeby przyszłe, jeśli chodzi o dostępność adresów IP. Chodzi mianowicie o to, by za kilka lat nie trzeba było na nowo reorganizować adresacji, a przez to również strategii routingu z powodu braków adresów w wydzielonych pulach, przeznaczonych na zaadresowanie poszczególnych segmentów sieci. Planowanie adresacji z uwzględnieniem kryterium skalowalności polega na założeniu pewnego marginesu puli adresów właśnie na zaspokojenie przyszłych potrzeb. Przykładowo: zastosowanie podziału sieci klasy C na podsieci z maską (prefiksem) 27-bitowym pozwoli na wykreowanie 8 podsieci (włączając w to czasem problematyczną podsieć zerową), w obrębie których będzie możliwe zaadresowanie po 30 hostów (urządzeń końcowych), bo pierwszy adres z puli jest  zawsze adresem samego subnetu (podsieci), a ostatni zawsze adresem rozgłoszeniowym (broadcast) i jako takie nie mogą zostać przyznane hostom końcowym.

Adresacja ‘primary’ i ‘secondary

Oczywiście, kiedy braknie nam adresów dla hostów w określonym segmencie sieci, nie od razu trzeba wywracać do góry nogami cały plan adresacji. Zamiast podejmować tak drastyczne kroki, można zastosować którąś z dostępnych „protez”, na przykład: adresację secondary lub adresowane podinterfejsy na routerze. Pierwsze ze wspomnianych rozwiązań polega na tym, że przypisujemy określonemu segmentowi sieci LAN kolejny adres IP, następnie dostępnymi adresami z nowej puli adresowej adresujemy hosty podłączone do wspomnianego segmentu. Zaś w celu zapewnienia możliwości komunikowania się naszej nowej podsieci ze światem, routerowi nadajemy dodatkowy adres IP (adres ‘secondary’) na jego interfejsie LAN do tego segmentu.

Wygląda to tak, jak w poniższym przykładzie:

Router(config-if)# ip address 10.1.1.1 255.255.255.0
Router(config-if)# ip address 10.1.2.1 255.255.255.0 secondary

Tym sposobem interfejs routera ma dwa adresy – adres podstawowy (primary) i dodatkowy. W rzeczywistości adresów dodatkowych może mieć więcej, a konfiguracja kolejnych polega po prostu na użyciu w trybie konfiguracyjnym kolejnych poleceń ‘ip address’ ze słówkiem ‘secondary’ na końcu. Rzecz jasna, taka konfiguracja ma swoje ograniczenia, które potrafią dać o sobie znać przy wystąpieniu problemów i przy diagnostyce sieci. Miejmy też na uwadze to, że segment sieci, w której działa adresacja ‘secondary’ będzie musiał podołać zwiększonym wymaganiom na pasmo transmisji. Łatwiej też będzie go można zdestabilizować eskalacją ruchu broadcastowego, zwłaszcza z wykorzystaniem broadcastów w postaci 255.255.255.255 (flooded broadcasts).

Kolejna ze wspomnianych protez polega na wykreowaniu podinterfejsów na interfejsach LAN routera (jeśli to możliwe, a to będzie zależało od rodzaju interfejsu i typu enkapsulacji na interfejsie) i nadaniu im adresów IP z poszczególnych, różnych subnetów, jak w poniższym przykładzie:

Router(config)# interface fast 0/0.1
Router(config-subif)# ip address 10.1.1.1 255.255.255.0

Router(config)# interface fast 0/0.2
Router(config-subif)# ip address 10.1.2.1 255.255.255.0

Nieadresowane łącza point-to-point (IP unnumbered)

Tego typu „oszczędność” można zastosować dla łączy point-to-point (na przykład dla linii dzierżawionych, czy dla PVC Frame Relay w konfiguracji point-to-point, etc.). Konfiguracja ‘IP unnumbered’ pozwala na zapewnienie komunikacji poprzez tego rodzaju łącza pomimo faktu, że ich interfejsy na routerach nie posiadają własnych adresów IP.  Możliwe jest to dzięki temu, że na potrzeby transmisji IP przez wspomniane łącza, zapożyczany jest adres IP interfejsu wskazanego jako parametr użyty przy konfiguracji funkcjonalności „IP unnumbered” na nienumerowanym interfejsie. Jest nim na ogół interfejs sieci LAN (na przykład Ethernet lub FastEthernet) albo logiczny interfejs pętli zwrotnej (loopback), oczywiście poprawnie zaadresowany adresem routowanym w sieci przedsiębiorstwa.

Router(config-if)# ip unnumbered loopback 0

W alternatywnej wersji konfiguracji, gdybyśmy jednak zdecydowali się na zastosowanie numerowanego łącza, to znaczy przypisali adresy IP interfejsom routerów po obu stronach połączenia point-to-point, zużylibyśmy w tym celu minimum 4 adresy IP. Wynika to z zastosowania adresu podsieci z prefiksem (maską podsieci) na 30 bitach (255.255.255.252). Oczywiście, w takim przypadku zastosowana w sieci strategia routingu musiałaby nam na to najzwyczajniej pozwolić, co w praktyce sprowadza się do wykorzystania w naszej sieci bezklasowego protokołu routingu dynamicznego lub oparcie konfiguracji routingu wyłącznie w o routing statyczny. Zastosowanie bezklasowego protokołu routingu dynamicznego, czyli takiego, w którym propagowane są pomiędzy routerami, w komunikatach o sieciach, długość ich prefiksu (maski podsieci), jest w tym przypadku wymogiem. Zakładam bowiem, że w sieci będzie stosowana adresacja z wykorzystaniem zmiennej długości masek (VLSM – Variable-Length Sumbet Mask). Klasowe protokoły nie tolerują zróżnicowania długości masek podsieci z uwagi na automatyczna klasową sumaryzację, o czym napiszę w dalszej części artykułu.

Adresacja VLSM

Adresacja z wykorzystaniem zmiennych długości masek podsieci służy oszczędnej alokacji adresów.  Najlepszym przykładem ilustrującym, jakiego marnotrawstwa możemy się dopuścić stosując adresację opartą o jej alternatywę, czyli podział sieci na subnety ze stałą długością maski, jest porównanie dwóch planów adresacji sieci o identycznej topologii. W pierwszym przypadku stosujemy adresację opartą o stałą długość maski, w drugim natomiast korzystamy z dobrodziejstw VLSM-a. W tym pierwszym przypadku, mając do zaadresowania 10 sieci (6 segmentów LAN i 4 łącza point-to-point) musielibyśmy dostępną przestrzeń adresową podzielić na N równych „kawałków”, gdzie N jest potęgą dwójki, nie mniejszą niż 10, czyli N=24=16. Taki podział dałby nam do dyspozycji podsieci o adresach zmieniających się o wartość 16 na pozycji ostatniego oktetu:

.0 --> odrzucamy ze względu na to, że adres stanowi tzw. subnet-zero (choć oczywiście można go wykorzystać pod pewnymi warunkami)
.16/28 (.16 – sieć, .31 – broadcast, zakres adresów hostów: .17-.30)
.32/28 (.32 – sieć, .47 – broadcast, zakres adresów hostów: .33-.46)
.48/28 (.48 – sieć, .63 – broadcast, zakres adresów hostów: .49-.62)
.64/28 (.16 – sieć, .31 – broadcast, zakres adresów hostów: .17-.30)

…itd.

Przykładową topologię sieci wraz z planem adresacji opartym o VLSM pokazuje następujący rysunek:

Przykładowy plan adresacji oparty o VLSM

Nawet z pobieżnej oceny wynika ewidentna korzyść planu adresacji opartego o zmienną długość maski podsieci. Chodzi głównie o to, żeby na adresowanie łączy point-to-point nie tracić adresów. Tam jedynie słuszną długością maski jest 30 bitów (255.255.255.252), co daje możliwość zaadresowania dwóch hostów w segmencie czyli w sam raz zaspokaja potrzeby interfejsów routerów po obu stronach łącza. Krótsza niż licząca 30 bitów maska oznacza marnotrawstwo adresów, bo na łączach  point-to-point zawsze użyteczne będą jedynie cztery adresy – adres sieci, broadcast i dwa adresy hostowe, do przypisania routerom po obu stronach.

Kontynuując temat, już niekoniecznie w kontekście zaprezentowanego schematu topologii sieci,  może się też zdarzyć tak, że na serwerowy segment sieci będziemy chcieli przeznaczyć mniejszą pulę adresów niż na segmenty, w których działają stacje użytkowników końcowych. Jeśli dla przykładu w VLAN-ie serwerowym nigdy nie będziemy mieć potrzeby zaadresowania więcej niż 30 hostów, to marnotrawstwem byłoby stosowanie adresów podsieci z prefiksem krótszym niż 27 bitów (255.255.255.224). Załóżmy, że w naszej sieci znajdują się również VLAN-y użytkowników końcowych, w których zapotrzebowanie na adresy jest większe, powiedzmy potrzeba tam maksymalnie 62 adresów IP. Najbardziej odpowiednia maska liczy będzie wówczas 26 bitów (255.255.255.192).

Co się tyczy metodyki planowania VLSM-a, nie muszę dodawać, że planując takową adresację, należy zapewnić rozdzielność zakresów adresów dla poszczególnych podsieci. Innymi słowy, zakresy adresów podsieci bezwzględnie nie mogą się na siebie nakładać. W praktyce efekt rozłączności zbiorów adresów VLSM osiąga się przez zastosowanie zasady „subnetowania subnetów”. Co oznacza to tajemniczo brzmiące określenie? Oznacza mianowicie pewien skrót myślowy, opisujący podejście przy dzieleniu dostępnej przestrzeni adresowej. Najlepiej wyjaśnić to na przykładzie. Załóżmy, że mamy do wykonania zadanie polegające na optymalnym podziale sieci 192.168.3.0/24 na podsieci. Do zaadresowania mamy – załóżmy – cztery łącza point-to-point, dwa serwerowe VLAN-y liczące nie więcej niż 30 hostów i dwa VLAN-y dla użytkowników końcowych, w których – jak szacujemy – liczba hostów nie przekroczy 62. Podejście zgodne z „subnetowaniem subnetów” jest takie: podziel adres sieci na duże „kawałki”, a potem w razie potrzeby dziel te duże kawałki na mniejsze przez przesuwanie granicy prefiksu „na prawo” – w kierunku sufiksu (zwiększanie długości maski).  Oczywiście tego typu dalszemu podziałowi mogą podlegać wyłącznie „kawałki” niewykorzystane, to znaczy takie, z których dotąd jeszcze nie przydzielono (nie „wykrojono”) żadnego adresu dla sieci czy hostów.

Plan adresacji mógłby wyglądać tak:

Największe kawałki na jakie należy podzielić sieć 192.168.3.0/24 muszą „pomieścić” maksymalnie 62 adresy, zatem w pierwszej turze podziału dzielimy sieć na bloki po 64 adresy, co jak łatwo się zorientować oznacza przesunięcie granicy prefiksu o dwa bity „na prawo” w stosunku go granicy wynikającej z przynależności adresu do klasy adresowej (klasa C – prefiks 24-bitowy). Otrzymujemy następujące bloki do finalnego wykorzystania lub dalszego podziału:

192.168.3.0/26
192.168.3.64/26
192.168.3.128/26
192.168.3.192/26

Przydzielmy adresy .64/26 (.64 – sieć, .127 – broadcast, zakres adresów dla hostów: .65-.126) i .128/26 (.128 – sieć, .191 – broadcast, zakres adresów dla hostów: .129-.190) na VLAN-y, w których będą działały maksymalnie po 62 hosty.

Teraz weźmy ostatni blok i podzielmy go na dwa kawałki, by wygospodarować z dostępnej przestrzeni adresowej adresy dla VLAN-ów serwerowych. Przesunięcie granicy prefiksu (długości maski) o jeszcze jeden bit „w prawo” w ostatnim bloku da nam dwa 32 adresowe podbloki (podsieci) o następujących adresach:

192.168.3.192/27 (.192 – sieć, .223 – broadcast, zakres adresów dla hostów: .193-.222)
192.168.3.224/27 (.224 – sieć, .255 – broadcast, zakres adresów dla hostów: .223-.254)

Na koniec trzeba „wykroić” adresy na łącza point-to-point. Dla tego typu łączy jedynie słuszne jest zastosowanie maski 30 bitowej. Wykorzystajmy w tym celu pierwszy blok adresowy, „odłożony na bok” w pierwszej turze podziału przestrzeni adresowej, czyli blok: 192.168.3.0/26. Ponieważ mamy potrzebę zaadresowania czterech łączy point-to-point, to 64 adresowy blok podzielmy na dwa podbloki po 32 adresy:

192.168.3.0/27
192.168.3.32/27

a potem jeden z tych podbloków podzielmy na podbloki po cztery adresy, a drugi zachowamy w rezerwie:

192.168.3.0/30  (.0  – sieć, .3 –  broadcast, zakres adresów dla hostów: .1-.2)
192.168.3.4/30  (.4  – sieć, .7 –  broadcast, zakres adresów dla hostów: .5-.6)
192.168.3.8/30  (.8  – sieć, .11 – broadcast, zakres adresów dla hostów: .9-.10)
192.168.3.12/30 (.12 – sieć, .15 – broadcast, zakres adresów dla hostów: .13-.14)
192.168.3.16/30 (.16 – sieć, .19 – broadcast, zakres adresów dla hostów: .17-.18)
192.168.3.20/30 (.20 – sieć, .23 – broadcast, zakres adresów dla hostów: .21-.22)
192.168.3.24/30 (.24 – sieć, .27 – broadcast, zakres adresów dla hostów: .25-.26)
192.168.3.28/30 (.28 – sieć, .31 – broadcast, zakres adresów dla hostów: .29-.30)

Na zaadresowanie czterech łączy point-to-point wykorzystajmy adresy .4/30, .8/30, .12/30, .16/30 resztę trzymając w rezerwie. Przypomnę jedynie, że w rezerwie mamy tez blok 192.168.3.32/27, także do wykorzystania w razie potrzeby.
Na koniec rozdziału o VLSM-ie wspomnę jedynie, że zastosowanie zmiennej długości masek podsieci jest możliwe wyłącznie w takich sieciach, w których strategia routingu oparta jest o bezklasowy protokół routingu dynamicznego (taki który wraz z adresami podsieci rozgłasza także długości masek podsieci) lub o wyłącznie o routing statyczny.  Klasowo działające protokoły, ze względu na to, że nie rozgłaszają długości prefiksów dla propagowanych sieci,  nie radzą sobie z adresacja VLSM.

Routing dynamiczny klasowy versus bezklasowy

Klasowy routing dynamiczny opiera swoje działanie o protokoły, które w komunikatach rozgłoszeniowych nie wysyłają informacji o masce podsieci. Router, konstruując na ich podstawie tablicę routingu, stosuje dla rozgłaszanych sieci maskę zgodną z lokalna konfiguracją czyli z wiedzą o masce na podstawie konfiguracji własnych interfejsów, poprzez które odbierane są rozgłoszenia lub z braku takiej wiedzy, stosuje maskę wynikająca dla danego adresu z jego przynależności do określonej klasy adresowej. Na przykład, jeżeli router otrzymuje informację o podsieci 192.168.1.64 przez interfejs, który ma przypisany adres 192.168.1.129 z 26-bitową maską (255.255.255.192), to z uwagi na fakt, że obie podsieci: 192.168.1.128/26 i 192.168.1.64/26 należą do C-klasowej sieci 192.168.1.0/24, podsieć 192.168.1.64 trafi do tablicy routingu tego routera z maską zgodną z zastosowaną dla tzw. sieci bezpośrednio dołączonej (directly connected), czyli skonfigurowanej na lokalnym interfejsie routera, poprzez który od sąsiada przyjęte zostało rozgłoszenie danej podsieci. Jeśli natomiast router otrzyma od sąsiada informację o podsieci 192.168.1.64 przez interfejs, który będzie posiadał adres z innej sieci klasowej na przykład 192.168.3.1/24 (też C-klasowa sieć, ale zupełnie inna niż 192.168.1.0/24) lub 172.16.3.1/24, to dla adresu 192.168.1.64 zostanie zastosowana maska klasowa, a do tablicy routingu trafi adres 192.168.1.0/24 (z maską 255.255.255.0, nie zaś 255.255.255.192). Mówimy tu o zjawisku klasowej sumaryzacji sieci, typowej dla protokołów klasowych (classful), takich, jak choćby RIP ver.1 czy IGRP. Tak też mogą zachowywać się protokoły co prawda bezklasowe, takie jak RIP ver. 2, EIGRP, a nawet BGP, do momentu, kiedy jawnie w ich ustawieniach na routerze nie wyłączymy automatyki klasowej sumaryzacji. Jednak w przypadku tych drugich mamy taki wybór, podczas gdy protokoły klasowe sumaryzują sieci w opisanych okolicznościach zawsze.

Bezklasowe protokoły routingu propagują informacje o długości prefiksów dla rozgłaszanych sieci, zatem wiedza routera o masce jest pełna i nie musi ograniczać się do konfrontowania adresu sieci, o której router „słyszy” w rozgłoszeniu od sąsiada, z adresem własnych sieci dołączonych albo przyjmować dla nich maski klasowe. Routery „rozmawiające” z sobą przy pomocy protokołów bezklasowych radzą sobie świetnie z nieciągłymi subnetami IP i z adresacją opartą o zmienną długość maski (VLSM). Doskonale też radzą sobie z optymalizacją routingu poprzez sumaryzację sieci i to taką sumaryzację, która może być przeprowadzana na granicy dowolnego bitu adresu, niekoniecznie na granicy prefiks/sufiks wynikającej z przynależności adresu do określonej klasy adresowej (bezklasowa sumaryzacja, supernetting).

Sumaryzacja routingu i CIDR

Sumaryzacja routingu polega na reprezentowaniu jedną pozycją w tablicy routingu większego zbioru podsieci czy sieci. Czemu to służy? Rzecz jasna, służy to zmniejszeniu rozmiarów tablic routingu czyli de facto przyspieszeniu decyzji, jakie router musi podejmować o kierunkach propagacji przepływającego przezeń ruchu sieciowego. Im mniejsza tablica routingu, tym mniejsza moc obliczeniowa jest potrzebna, by takową decyzję podejmować. Inna korzyść jest taka, że sumaryzacja routingu w sieciach o dobrze zaprojektowanej topologii hierarchicznej i dopasowanym do niej zhierarchizowanym planie adresowym stabilizuje routing. Router, który nie wie o poszczególnych, detalicznych podsieciach wchodzących w zakres sumaryzacji, mający w swojej tablicy routingu jedynie routing sumaryczny reprezentujący zbiór tych sieci, nie musi przebudowywać swojej tablicy routingu za każdym razem kiedy jakaś niestabilna podsieć zmieni swój stan (stanie się niedostępna lub ponownie dostępna po okresie niedostępności). Bowiem tak długo dopóki działa choć jedna podsieć wchodząca w zakres sumaryzacji, routing sumaryczny pozostaje stabilny i aktywny. Dopiero kiedy „padnie” ostatnia sieć spośród znajdujących się w zakresie sumaryzacji, routing sumaryczny, jako nieaktywny zostaje usunięty z tablicy routingu routera.

Wcześniej wspomniałem już o sumaryzacji klasowej dokonywanej automatycznie przez tzw. klasowe protokoły routingu dynamicznego. W przypadki protokołów bezklasowych możliwe jest po pierwsze pełne zarządzanie sumaryzacją, poprzez jej odpowiednią konfigurację, a po drugie, efektem sumaryzacji niekoniecznie muszą być sieci klasowe – siecią sumaryczną może być zbiór subnetów albo supernet (nadsieć).

Sumaryzacja routingu

Nie będziemy zagłębiać się w sposoby sterowania sumaryzacją w poszczególnych protokołach routingu dynamicznego. Ten temat nadaje się na oddzielny artykuł, który – rzecz jasna – mogę napisać, jeśli taka będzie wola moich czytelników. Dość wspomnieć jedynie, że w protokole EIGRP sumaryzację przeprowadza się na routerze w kierunku określonego łącza (tym łączem do sąsiada będzie propagowany routing sumaryczny). Miejscem sumaryzacji w protokole OSPF są routery brzegowe międzyobszarowe (Area Border Router – ABR) oraz routery brzegowe systemu autonomicznego (Autonomous System Boundary router – ASBR). Jeszcze inaczej wygląda sumaryzacja w protokole BGP i w tym miejscu dotykamy zagadnienia CIDR – Classless Interdomain Routing czyli między innymi sumaryzacji supernetowej routingu międzydomenowego w globalnej sieci Internet.

CIDR wprowadzono w odpowiedzi na ograniczenia klasowego podział przestrzeni adresowej i wynikającego z niej arbitralnego operowania blokami adresów z zakresów wynikających z  przynależności adresów sieci do klas adresowych. Jeśli niegdyś duża organizacja lub operator ISP potrzebowały więcej niż jednej sieci klasy C, to otrzymywały adres klasy B, co w większości przypadków prowadziło do czystego marnotrawstwa. Jeśli bowiem organizacja potrzebowała załóżmy 32 adresów sieci klasy C, to otrzymując zamiast tego jeden adres klasy B dysponowała znacznym nadmiarem adresów.

Przeliczny to:

32 sieci klasy C oferują dla potrzeb adresowania hostów pulę liczącą 32 x (28 – 2) = 8128 adresów. Zaś jedna sieć klasy B oferuje 216 – 2 = 65534 adresy czyli ponad 8 razy więcej niż wynosi rzeczywista potrzeba organizacji lub operatora ISP z analizowanego przykładu.

Podejście oparte o CIDR pozwala też na eleganckie optymalizowanie routingu międzydomenowego. Polega ono na tym, aby nie rozgłaszać w protokole BGP poszczególnych sieci klasowych, tylko efekty sumaryzacji całych ich bloków. Jak już wspomniałem, znacznie zmniejsza to rozmiary i tak nieraz monstrualnie wielkich tablic routingu na routerach operatorów ISP, a na dodatek stabilizuje routing. Jest bowiem tak, że dopóki działa co najmniej jedna sieć wchodząca w zakres sumaryzacji, to z punktu widzenia routera przechowującego w swojej tablicy routingu sieci zsumaryzowane, routing do tych sieci jest stabilny. Należy to rozumieć w ten sposób, że zmiana stanu pojedynczej sieci wchodzącej w zakres sumaryzacji nie jest dla takiego routera sygnałem o zmianie topologii sieci, zmuszającym go do przebudowania tablicy routingu. Korzyść, o której tutaj mówimy, widać tym wyraźniej im bardziej uświadomimy sobie ogromną skalę informacji o sieciach przetwarzanych na routerach BGP i związane z tym duże zapotrzebowania na moc obliczeniową procesora niezbędną do przetwarzaniem dużych struktur danych mających związek z routingiem (bazy topologii, bazy sąsiedztwa, protokołowe tablicy routingu, główna tablica routingu itp.). Z drugiej strony, proszę pamiętać, że w podejściu zgodnym z CIDR wiele organizacji czy też operatorów ISM może otrzymać bloki adresów „wykrojone” na przykład z jednego adresu klasy A. Weźmy taki przykład: różne organizacje otrzymują na własne potrzeby bloki adresowe – załóżmy – sieci 90.0.0.0/8, pozostałe przez przesunięcie granicy prefiksu o jeden oktet „na prawo” – w stroną sufiksu. Kolejne wygospodarowane tym sposobem adresy to; 90.0.0.0/16, 90.1.0.0/16, 90.2.0.0/16 itd. Zmienia się w nich wartość drugiego oktetu. W tej sytuacji może zdarzyć się tak, że routery BGP określonego operatora będą „słyszały” nie o całej sieci klasowej 90.0.0.0/8 z jednego źródła, a o poszczególnych blokach adresowych z różnych źródeł pochodzących z różnych systemów autonomicznych. Warto mieć na względzie to, że CIDR, jeśli chodzi o szczegółowość routingu, ma dwa oblicza i nie zawsze oznacza on sumaryzację supernetową czyli taką, z jaką mamy do czynienie przez przesuwanie prefiksu „na lewo” w stosunku do granicy wynikającej z przynależności adresu do określonej klasy adresowej.

Typowe problemy i błędy związane z adresacją

Brak spójnego planu adresowego jest największym błędem projektanta sieci, ponieważ rodzi bałagan, którego fatalne skutki mogą pojawiać się z opóźnieniem i przejawiać się bardzo różnie, mniej lub bardziej boleśnie dla administratorów i użytkowników sieci. Mogą, w swym najlżejszym wydaniu, przyjmować postać na przykład problemów z szybkim zdiagnozowaniem przyczyn awarii. Gorszymi następstwami mogą być istotne problemy z routingiem, takie jak na przykład zapętlenia ścieżek (zwłaszcza gdy bałagan z adresami przeniesiemy z domeny jednego protokołu do innego w drodze redystrybucji sieci pomiędzy protokołami), niestabilny routing, problemy z szybkim osiągnięciem stanu zbieżności po awarii albo zmianie topologii, czy nieoptymalne ścieżki doboru tras. Problemem może też być przeciążenie routerów, a w pewnych skrajnych okolicznościach także brak ciągłości działania sieci. Wspomnę też, że w sieciach z bałaganiarską adresacją trudne, a czasem wręcz niemożliwe jest panowanie nad bezpieczeństwem przy pomocy rozwiązań typu firewall czy list dostępowych.

Kolejnym problemem, w pewnym sensie należącym do tej samej kategorii, co poprzednio zasygnalizowane, to nieciągłość subnetów IP w sieciach, w których albo ma działać klasowy protokół routingu, albo nawet bezklasowy, ale z domyślnie włączoną funkcją sumaryzacji klasowej. Jeśli skutkiem takiej sumaryzacji okaże się, że routing do dwóch topologicznie odseparowanych od siebie części intersieci w których zastosowano nieciągłe subnety IP prowadzi dwiema niezależnymi trasami, to może to prowadzić do nieosiągalności jednego z tych obszarów z poziomu innych części intersieci. Którego z nich? To oczywiście zależy od tego, która z dwóch ścieżek jest bardziej wiarygodna w sensie dystansu administracyjnego, a gdy ten jest identyczny, to która jest korzystniejsza w sensie metryki. Na poziomie diagnostyki widać to na przykład, kiedy wysyłamy pakiety ICMP-ECHO przy pomocy ping-a do któregoś z hostów problematycznych sieci i otrzymujemy odpowiedź na co drugi pakiet, albo część sesji protokołów połączeniowo-zorientowanych jest poprawnie nawiązywana i obsługiwana, a część nie.

Błędem projektanta jest też zastosowanie planu adresacji, który nie jest dopasowany do hierarchicznej topologii sieci. Każdy element jej struktury, czy to będzie obszar sieci (jak w protokole OSPF albo IS-IS) czy topologicznie wyodrębniona struktura typu węzeł dostępowy, węzeł dystrybucyjny albo rdzeń sieci, powinien mieć swój własny, ciągły zakres bloków adresów. Takie podejście daje luksus efektywniejszego zarządzania siecią, ułatwia diagnostykę problemów, warunkuje możliwość zastosowania sumaryzacji sieci, otwiera także więcej możliwości na zastosowanie inteligentnych sposobów zwiększania niezawodności sieci (redundantne ścieżki routingu, failover, load-balancing, szybka zbieżność routingu po zmianach topologii logicznej czy też wynikających z awarii i dysfunkcji sieci).

Wreszcie ostatnią kategorią problemów z adresacją IP jest jej niedostosowanie do wymagań protokołów routingu dynamicznego. To jest jednak temat na oddzielny artykuł, który wymaga wprowadzenia do teorii protokołów w celu dobrego rozumienia prawideł projektowania sieci z ich wykorzystaniem oraz mechanizmów ich funkcjonowania w sieciach.

Konkluzje

Choć adresacja IP jest rodzajem elementarza projektanta i ktoś mógłby powiedzieć: „po co sobie takimi podstawami zaprzątać głowę?”, to z uwagi na choćby poważne konsekwencje błędów, jakie – projektując sieć – można popełnić na etapie opracowywania koncepcji planu adresowego, warto przypomnieć sobie podstawy. Taki też był cel tego artykułu.  Najważniejsze idee, które – mam nadzieję – udało mi się jakoś w nim uwypuklić, to:

  • Dobry plan adresacji, to skalowalny plan;
  • Plan adresacji musi być dostosowany do hierarchii topologii sieci;
  • Projektując plan adresacji, konieczne jest wzięcie pod uwagę specyficznych wymagań protokołów routingu dynamicznego, a szerzej rzecz ujmując, planowanej, docelowej strategii routingu w sieci (routing statyczny versus dynamiczny, routing domyślny, wiarygodność źródeł informacji o routingu czyli dystans administracyjny, metryki ścieżek i ich kształtowanie, routing domyślny, redystrybucje oraz filtracja redystrybucji, policy-based routing, rozwiązania podwyższonej niezawodności na poziomie routingu etc.);
  • Plan adresacji musi być zgodny z wymaganiami związanymi z bezpieczeństwem i zarządzaniem siecią (gdzie ma być firewall?, gdzie i w jakim kierunku mają działać ACL-e?, gdzie mają być zlokalizowane bramki translacji adresów? itp.).

Jeśli coś można zrobić dobrze, to należy dążyć do wykonania tego idealnie. Takie podejście nigdy jeszcze nie zaszkodziło ani projektantowi, ani organizacji, na rzecz której projekt został wykonany. I tego się trzymajmy.

Skrypt wspomagający planowanie adresacji

Częścią tego artykułu jest narzędzie w formie skryptu, które napisałem w tym celu, by ułatwić planowanie adresacji IP i umożliwić rozwiązywanie problemów z tym związanych. Skrypt został napisany w języku Ruby. Można go zatem uruchamiać w praktycznie dowolnym systemie operacyjnym, gdzie tylko dysponujemy interpreterem tego zacnego języka, bez potrzeby modyfikacji jego kodu.

Nie zapomnijcie proszę o instalacji biblioteki ‚ipaddress’ poleceniem CLI:

gem install ipaddress

Tak wygląda jego graficzny interfejs użytkownika skryptu:

Planowanie adresacji IP - GUI skryptu

Na załączonym obrazku widać jakie możliwości ma program. Mianowicie, ułatwia przeliczanie reprezentacji adresu z dziesiętnej kropkowej na binarną czy heksadecymalną, wizualizuje część prefiksową i część sufiksową adresu dla danej arbitralnie przyjętej maski (zgodnie z podejściem CIDR), oblicza liczbę i zakresy adresów hostów, a nawet konwertuje adresy IP ver. 4 na adresy w IP ver. 6.

Zachęcam rzecz jasna do zabawy z kodem skryptu i jego dalszą modyfikacją.

Oto jego kod:

require 'tk'
require 'ipaddress'

def mask_border(prefix)
	border_string=''
	if prefix32
		prefix=32
	end
	(1..32).each do |licznik|
		if licznik==prefix
			border_string.concat('|')
		elsif licznik%8==1 and licznik>1
			border_string.concat('.-')
		else
			border_string.concat('-')
		end
	end
	return border_string
end

def adr_to_bin(str_adr)
	result=""
	begin
		oktety=str_adr.split('.')
		oktety.each do |oktet|
			result.concat(sprintf("%08b.", oktet))
		end	
	rescue => e
		p e.message
		p e.backtrace
	end
	return result.chop
end

def adr_to_hex(str_adr)
	result=""
	begin
		oktety=str_adr.split('.')
		oktety.each do |oktet|
			result.concat(sprintf("0x%02X.", oktet))
		end	
	rescue => e
		p e.message
		p e.backtrace
	end
	return result.chop
end

def calculate_address(adres, prefix)
	begin
		result = ""
		# result.concat('-' * 60)
		ip = IPAddress("#{adres}/#{prefix}")
		network = ip.network
		subnet = ip.netmask
		broadcast = ip.broadcast
		result.concat("\nAddress IP:\t#{ip} \nSubnet mask:\t#{subnet} \nNetwork address:\t#{network} \nBroadcast address:\t#{broadcast}\n")
		network_size = ip.size # Liczba hostow w sieci
		ipv6 = ip.to_ipv6
		first_host = ip.first.to_s
		last_host = ip.last.to_s
		if ip.a?
			klasa = 'A'
		elsif ip.b?
			klasa = 'B'
		else
			klasa = 'C'
		end
		result.concat("IPv6 address: #{ipv6}\n")
		result.concat("Class: #{klasa} subnet,\tNumber of hosts in this subnet: #{network_size}\n")
		result.concat("First host address: #{first_host}\nLast host address: #{last_host}\n")
		result.concat('-' * 60)
		# ----
		# result.concat("\nAddress IP:\t0x#{ip.to_i.to_s(16)}\nSubnet mask:\t0x#{subnet.to_i.to_s(16)}\nNetwork address:\t0x#{network.to_i.to_s(16)}\nBroadcast address:\t0x#{broadcast.to_i.to_s(16)}\n")
		result.concat("\n#{adr_to_hex(ip.to_s)} ---> Address IP\n#{adr_to_hex(subnet.to_s)} ---> Subnet mask\n#{adr_to_hex(network.to_s)} ---> Network address\n#{adr_to_hex(broadcast.to_s)} ---> Broadcast address\n")
		result.concat('-' * 60)
		# ----
		result.concat("\n#{adr_to_bin(ip.to_s)} ---> Address IP\n#{mask_border(prefix)} ---> Border of subnet bits\n#{adr_to_bin(subnet.to_s)} ---> Subnet mask\n#{adr_to_bin(network.to_s)} ---> Network address\n#{adr_to_bin(broadcast.to_s)} ---> Broadcast address\n")			 
		result.concat('-' * 60 + "\n")
	rescue => e
		p e.message
		p e.backtrace
	end
	return result
end	

root = TkRoot.new {title "IP Addressing -- Janusz Nawrat, 2013"}

frame = TkFrame.new(root).grid('column'=>0, 'row'=>2, 'columnspan'=>3, 'rowspan'=>2)

input_frame = TkFrame.new(root) do
	relief 'sunken'
	borderwidth 3
	padx 15
	pady 10
	grid('column'=>0, 'row'=>0, 'columnspan'=>5, 'rowspan'=>2, 'sticky'=>'ew')
end

$adr = TkVariable.new
$prf = TkVariable.new

$octet1 = TkVariable.new; $octet2 = TkVariable.new; $octet3 = TkVariable.new; $octet4 = TkVariable.new

$prf.value = 1

$octet1.value = 1; $octet2.value = 1; $octet3.value = 1; $octet4.value = 1

TkLabel.new(input_frame) do
	text "IP Address: "
	grid('column'=>0, 'row'=>0, 'sticky'=>'e')
end

octet1_spin = TkSpinbox.new(input_frame) do
  to 255
  from 0
  increment 1
  width 10
  textvariable $octet1
  grid('column'=>1, 'row'=>0, 'sticky'=>'ew', 'pady'=>1, 'padx'=>2)
end

octet2_spin = TkSpinbox.new(input_frame) do
  to 255
  from 0
  increment 1
  width 10
  textvariable $octet2
  grid('column'=>2, 'row'=>0, 'sticky'=>'ew', 'pady'=>1, 'padx'=>2)
end

octet3_spin = TkSpinbox.new(input_frame) do
  to 255
  from 0
  increment 1
  width 10
  textvariable $octet3
  grid('column'=>3, 'row'=>0, 'sticky'=>'ew', 'pady'=>1, 'padx'=>2)
end

octet4_spin = TkSpinbox.new(input_frame) do
  to 255
  from 0
  increment 1
  width 10
  textvariable $octet4
  grid('column'=>4, 'row'=>0, 'sticky'=>'ew', 'pady'=>1, 'padx'=>2)
end

TkLabel.new(input_frame) do
	text "Prefix length: "
	grid('column'=>0, 'row'=>1, 'sticky'=>'e')
end

$prefix_scale = TkScale.new(input_frame) do
	orient 'horizontal'
	length 100
	from 0
	to 32
	# command (proc {printheight})
	tickinterval 8
	variable $prf
	grid('column'=>1, 'row'=>1, 'columnspan'=>4, 'sticky'=>'ew') 
end

$output_text = TkText.new(frame) do
	grid('column'=>0, 'row'=>2, 'columnspan'=>3, 'sticky'=>'ew')
end

action_button = TkButton.new(frame) do
	text "Action"
	command "$adr=$octet1.to_s+'.'+$octet2.to_s+'.'+$octet3.to_s+'.'+$octet4.to_s; \
			$output_text.delete 0.1, 'end';
	        $output_text.insert 'end', calculate_address($adr, $prf)"
	grid('column'=>0, 'row'=>3, 'sticky'=>'ew', 'padx'=>2, 'pady'=>5)
end

clear_button = TkButton.new(frame) do
	text "Clear"
	command "$output_text.delete 0.1, 'end'"
	grid('column'=>1, 'row'=>3, 'sticky'=>'ew', 'padx'=>2, 'pady'=>5)
end

exit_button = TkButton.new(frame) do
	text "Exit"
	command "exit"
	grid('column'=>2, 'row'=>3, 'sticky'=>'ew', 'padx'=>2, 'pady'=>5)
end

TkGrid.columnconfigure( root, 0, :weight => 1 )
TkGrid.columnconfigure( root, 1, :weight => 1 )
TkGrid.columnconfigure( root, 2, :weight => 1 )

TkGrid.columnconfigure( frame, 0, :weight => 1 )
TkGrid.columnconfigure( frame, 1, :weight => 1 )
TkGrid.columnconfigure( frame, 2, :weight => 1 )

TkGrid.columnconfigure( input_frame, 0, :weight => 1 ); TkGrid.columnconfigure( input_frame, 1, :weight => 1 );
TkGrid.columnconfigure( input_frame, 2, :weight => 1 ); TkGrid.columnconfigure( input_frame, 3, :weight => 1 );
TkGrid.columnconfigure( input_frame, 4, :weight => 1 );

Tk.mainloop

Informacje Janusz Nawrat
Just ordinary man who likes thinking...

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

TOMASZ WEŁNA

artysta grafik | wykładowca

PRACOWNIA OKO

Szkoła Rysunku Malarstwa i Grafiki DR TOMASZA WEŁNY | KRAKÓW | Plac Matejki 10 | tel 691 81 75 74

Piękno neurobiologii

Blog Jerzego Vetulaniego

Teoria muzyki, zasady muzyki, podstawy muzyki

Teoria muzyki, zasady muzyki, podstawy muzyki - czyli to co każdy amator muzyki wiedzieć powinien :)

Personal Development & Inspirations

Przemyślenia i refleksje, którymi warto się podzielić (blog by Janusz Nawrat)

Business IT Cooperation Platform

Biznes i IT - dwa światy, które muszą współdziałać

%d bloggers like this: