Dummynet
Data: 12-09-2003 o godz. 22:18:59
Temat: Konfiguracje usług w systemie FreeBSD


Dummynet to wspaniałe narzedzie pozwalajace nam, na kształtowanie ruchu w systemie FreeBSD. Jesli zajmujesz się badaniami w dziedzinie sieci komputerowych, na pewno ten pakiet przypadnie ci do gustu. Równiez, jesli posiadasz nieduzą sieć i chcesz aby kazdy zuzywał tyle samo pasma, na pewno też ten pakiet bedzie pomocny.



0.1 Instalacja

Aby zainstalować dummynet nalezy stosownie skonfigurować jadro. Zazwyczaj w pliku konfiguracyjnym jadra wystarczy dodać te trzy opcje:

options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
options DUMMYNET

Druga opcja nie jest konieczna, ale gdy posiadamy inny pakiet, który odpowiada za firewall (na przykład ipfilter ), to opcja ta jest pomocna, ponieważ domyslnie nie blokuje nam zadnych pakietów. Nic nie stoi na przeszkodzie, aby blokowaniem pakietów zajmował się ipfilter, a profilowaniem ruchu, ipfw/dummynet. Aby system po starcie automatycznie ładował regułki, nalezy dodać ponizszą linijkę do /etc/rc.conf. Nalezy pamietac, ze plik /etc/ipfw.rules rózni się nieco składnia, od składni poleceń uzytych w tym dokumencie, mianowicie, nie posiada polecenia ipfw na poczatku kazdej linijki.

firewall_enable="YES"
firewall_rules="/etc/ipfw.rules"

0.2 Elementy sterujace ruchem

Na elementy sterujace ruchem składają się tzw. rury i kolejki, lub jesli ktoś woli, potoki. Kazdy z tych elementów składowych moze być skonfigurowany tak, aby automatycznie wrzucał do takiej kolejki lub rury ruch, który zostanie mu przydzielony. Ponadto, mozna wprowadzić dodatkowy element losowego wyboru danej rury/kolejki. Aby zaczać profilować ruch, nalezy najpierw dodać kolejkę lub rure, a potem ją skonfigurowac. Wszystkiego dokonujemy komendą ipfw.

0.3 Rury


Rura, to kanał wydzielonego ruchu, który ma z góry zadaną przepustowosć (bw), długosć kolejki (queue), opóznienie (delay) oraz losową utratę pakietów (plr). Ograniczanie ruchu jest realizowane poprzez kolejkowanie pakietów, i odkolejkowywanie ich z okresloną szerokoscią pasma. Gdy kolejka przepełnia sie, pakiety zostają odrzucone. Aby dodać i skonfigurować przykładową rure, wydajemy polecenie:

ipfw add pipe 1 ip from any to any
ipfw pipe 1 config bw 1Mbit/s plr 0.9 delay 100ms


Rura, którą skonfigurowalismy, ma szerokosć 1 megabita, losową utratę pakietów 90%, oraz opóznienie 100 milisekund . Przydatnosć takiej rury jest raczej watpliwa, chyba ze symulujemy jakaś wyjatkowo oporną siec. Aby usunać tą rure, nalezy wydać polecenie:

ipfw pipe 1 delete
lub
ipfw flush

Druga komenda czysci wszystkie reguły ipfw. Wracajac do naszej rury: czasami zachodzi potrzeba zasymulowania róznych warunków transmisji na drodze od-i do-hosta. Sytuację taką mozna łatwo zaimplementować stosujac nastepujace polecenia definiujace dwie rury, jedną dla ruchu przychodzacego i jedną dla wychodzacego:

ipfw add pipe 1 ip from any to 10.0.0.1 in
ipfw add pipe 2 ip from any to 10.0.0.1 out
ipfw pipe 1 config bw 640Kbit/s
ipfw pipe 2 config bw 128Kbit/s

W tym wypadku słowo kluczowe in aplikuje się do adresu 10.0.0.1, tak wiec, parametr bw 640Kbit/s aplikuje się do ruchu wchodzacego do tego adresu. Druga rura obsługuje ruch wychodzacy. Jesli mamy potrzebę zasymulować wielosciezkowosc, wystarczy skorzystać ze słowa kluczowego prob. Przykład ponizej:

ipfw add prob 0.2 pipe 1 ip from any to any
ipfw add prob 0.5 pipe 2 ip from any to any
ipfw pipe 1 config delay 10ms
ipfw pipe 2 config delay 200ms

W tym wypadku, pierwsza rura jest wybierana w 20% przypadków, podczas gdy druga, w 0.5 × 0.8 czyli 40% przypadków. Rury lub kolejki mozna również przypisywać po protokole lub po porcie. Robimy to w nastepujacy sposób:

ipfw add pipe 1 tcp from any to any 80
ipfw add pipe 2 udp from any to any 53
ipfw add pipe 3 icmp from any to any
ipfw pipe 1 config bw 1Mbit/s
ipfw pipe 2 config bw 50Kbit/s
ipfw pipe 3 config bw 50Kbit/s

Powyzszy zestaw reguł pozwala nam na zagwarantowanie obustronnego pasma w protokole TCP na porcie 80 (www) o szerokosci jednego megabita, oraz po 50 kilobitów na DNS (UDP,53), oraz ICMP (ping, traceroute, wiadomosci o błedach niedostepnosci, etc.). Przedostatnim słowem kluczowym, które chciałbym omówić
jest queue. Domyslna wartosć tego parametru to 50. Parametr ten okresla porcję danych (w pakietach lub kilobajtach), które mają zostać urzymane w kolejce do przetworzenia w danej rurze. Jesli ta ilosć zostanie przekroczona, pakiet zostaje odrzucony. Ma to znaczenie przy połaczeniach na których pasmo jest bardzo waskie. Gdy na takim połaczeniu ustawimy ten parametr przesadnie wysoko, bedziemy się musieli liczyć z duzym opóznieniem (system musi przetworzyć na takim waskim łaczu wszystkie pakiety oczekujace w kolejce). Ustawianie tego parametru zbyt nisko, bedzie miało swoje konsekwencje w postaci utraconych pakietów (szczególnie, gdy z danym hostem wymianę informacji prowadzi kilka innych hostów). Ostatni parametr to mask. Pozwala on nam na tworzenie kilku identycznych rur, z których kazda bedzie obsługiwać ruch tego samego rodzaju. Opcja ta jest szczególnie uzyteczna, gdy chcemy kilku komputerom przydzielić taki sam ruch w sieci LAN. Tworzy ona dynamicznie kilka rur o identycznych parametrach.

ipfw add pipe 1 ip from any to 10.0.0.0/24
ipfw pipe 1 config bw 56Kbit/s queue 10 mask dst-ip 0x000000ff


Powyzsza konfiguracja ogranicza ruch w obie strony do kazdego komputera do 56 kilobitów, zmniejsza kolejkę do 10 pakietów. Słowo kluczowe dst-ip pokazuje nam która czesć adresu IP ma być „zamaskowana” aby wydzielić ruchy nalezace do innych dynamicznie tworzonych rur. Ruch mozna dzielić według adresu zródłowego i docelowego, zródłowego i docelowego portu, oraz protokołu. Składnia wyglada nastepujaco:

ipfw add pipe 1 ip from any to 10.0.0.0/24
ipfw pipe 1 config bw 100Kbit/s proto PROTO src-ip
ZRÓDŁOIP dst-ip CELIP src-port ZRÓDŁOPORT dst-port CELPORT

0.4 Kolejki


Kolejka to inny element sterujacy ruchem. W znacznym uproszczeniu, kolejka pozwala nam na przydzielenie odpowiedniej szerokosci pasma uzytkownikowi, stosownie do jego potrzeb. Zazwyczaj kolejka jest podłaczana do rury w nastepujacy sposób:

ipfw add pipe 2 ip from any to any
ipfw add queue 1 ip from 10.0.0.2 to 10.0.0.1
ipfw queue 1 config weight 5 pipe 2
ipfw pipe 2 config bw 300Kbit/s


Tak zdefiniowany zestaw reguł, okresla kolejkę wewnatrz rury numer 2, która posiada wagę 5 (Im wyzsza waga, tym kolejka ma wyzszy priorytet). Kolejki słuzą zazwyczaj do dynamicznego dzielenia pasma pomiedzy kilka połaczen. Parametry kolejek to pipe czyli rura, do której podpieta jest kolejka, weight, czyli „priorytet” obsługi ruchu, queue, czyli rozmiar kolejki,plr, czyli losowa utrata pakietów w kolejce, oraz mask, czyli opcja słuzaca do dynamicznego definiowania kolejek w zaleznosci od klasyfikacji ruchu. Jak działają „wagi” kolejek? Aby łatwiej zilustrować to zagadnienie, posłuzę się przykładem. Załózmy, ze w sieci mamy trzy hosty, z czego na 10.0.0.1 zainstalowany jest dummynet i jego konfiguracja wyglada nastepujaco:

ipfw add pipe 1 ip from any to any
ipfw add queue 1 ip from 10.0.0.2 to 10.0.0.1
ipfw add queue 2 ip from 10.0.0.3 to 10.0.0.1
ipfw queue 1 config weight 1 pipe 1
ipfw queue 1 config weight 19 pipe 1
ipfw pipe 1 config bw 1Mbit/s

Przy drobnej zmianie opóznień oraz długosci kolejki, osiag przesyłu przy kolejce pierwszej bedzie się wahał w okolicach 50 kbit, podczas gdy w przypadku drugiej kolejki, bedzie to około 950 kbit. Kolejki o róznych wagach przepuszczają dane w róznych porcjach, tj. na kazdy pakiet przesłany kolejką pierwszą moze przypadać 19 pakietów wysyłanych kolejką druga. Tak wiec, wagi kolejek ustalają pomiedzy sobą stosunek ruchu, który przetworza.
Aby dynamicznie podzielić dane nam pasmo przez liczbę uzytkowników, nalezy skorzystać z opcji mask.

ipfw add queue 1 all from any to 10.0.0.0/24
ipfw queue 1 config weight 5 pipe 2 buckets 253 mask dst-ip 0x000000ff


Taka konfiguracja dynamicznie stworzy nam tyle kolejek ile jest róznych, aktywnych adresów IP w tej podsieci. Opcja buckets mówi ile takich kolejek moze być maksymalnie stworzonych. Nie nalezy przesadzać przy podawaniu tej wielkosci, ponieważ zbyt duza wartosć moze niepotrzebnie zapełnić bufory sieciowe.

0.5 Ciekawe przykłady zastosowań

Scenariusz 1 Symulacja połaczenia satelitarnego.

ipfw add pipe 1 all from any to any in
ipfw add pipe 2 all from any to any out
ipfw pipe 1 config delay 440ms bw 64Kbit/s queue 10
ipfw pipe 2 config delay 440ms bw 1Mbit/s queue 5

Przy wysokich opóznieniach bedziemy obserwować stopniowe „przyspieszanie” połaczenia . Zmiana wielkosci kolejki nie powinna mieć znaczenia, chyba ze mamy do czynienia z transmisją do kilku komputerów. Jest
to uwarunkowane tym, jak skonstruowany jest protokół TCP: na kazdy pakiet wysłany, musi zostać odebrany pakiet potwierdzajacy odbiór.

Scenariusz 2 Bardzo zajety serwer WWW.

ipfw add queue 1 tcp from any to 10.0.0.1 80
ipfw queue 1 config weight 5 pipe 1 mask src-ip 0xffffffff


Przy takiej konfiguracji, kazdy numer IP ma wydzielone identyczne pasmo do serwera www. Zwróć uwagę na maskę src-ip. Zwrócmy też uwagę na to, ze chcac ustalić numer portu musimy okreslić protokół jako TCP.

ipfw add queue 1 tcp from 10.1.0.0/8 to 10.0.0.1 80
ipfw add queue 2 tcp from any to 10.0.0.1 80
ipfw queue 1 config weight 90 pipe 1 mask src-ip 0x00ffffff
ipfw queue 2 config weight 5 pipe 1 mask src-ip 0xffffffff


Przy takiej konfiguracji, serwer WWW bedzie obsługiwał pewną grupę uzytkowników z wyzszym priorytetem niż reszte. Kazdemu klientowi zostanie przydzielone to samo pasmo.

ipfw add pipe 1 tcp from 10.1.0.0/8 to 10.0.0.1 80
ipfw add pipe 2 tcp fron any to 10.0.0.1 80
ipfw queue 1 config weight 5 pipe 1 mask src-ip 0x00ffffff
ipfw queue 2 config weight 5 pipe 2 mask src-ip 0xffffffff
ipfw pipe 1 config 7Mbit/s
ipfw pipe 2 config 3Mbit/s


Przy powyzszej konfiguracji, łacze najpierw jest podzielone dwoma rurami, odpowiednio po 7 i 3 Megabity, a potem dzielone pomiedzy klientów w poszczególnych rurach tak, aby klient nalezacy do kazdej z rur dzielił ruch z innymi klientami z tej samej rury dostajac równą ilosć pasma.

Scenariusz 3 Sieć osiedlowa.

ipfw add queue 50 tcp from 10.0.0.0/24 to any 80
ipfw add queue 60 tcp from 10.0.0.0/24 to any 22,23,25
ipfw add queue 70 tcp from 10.0.0.0/24 to any 110
ipfw add queue 80 tcp from 10.0.0.0/24 to any
ipfw add queue 90 all from 10.0.0.0/24 to any
ipfw queue config 50 weight 5 pipe 50 buckets 255 mask src-ip 0x000000ff


ipfw queue config 60 weight 5 pipe 60 buckets 255 mask src-ip 0x000000ff
ipfw queue config 70 weight 5 pipe 70 buckets 255 mask src-ip 0x000000ff
ipfw queue config 80 weight 5 pipe 80 buckets 255 mask src-ip 0x000000ff
ipfw pipe 50 config bw 1Mbit/s
ipfw pipe 60 config bw 128Kbit/s
ipfw pipe 70 config bw 128Kbit/s
ipfw pipe 80 config bw 1Mbit/s delay 30ms queue 10
ipfw pipe 90 config bw 384Kbit/s


Pierwsze pieć linijek, dzieli nam ruch wychodzacy na pieć kategorii; przedostatnia to ruch p2p, ostatnia to ruch UDP/ICMP. Kolejne cztery linijki okreslają nam zasady dynamicznego tworzenia kolejek ruchu, i ostatnie pieć linijek okresla nam maksymalne szerokosci pasma, które chcemy zaalokować na poszczególne klasy ruchu.

0.6 Na zakończenie

Mam nadzieje, ze ten dokument pomógł ci zrozumieć zasadę działania pakietu DUMMYNET pod systemem FreeBSD. Jednoczesnie, chciałbym podkreslic, ze dokument ten został przygotowany w oparciu o doswiadczenia własne autora i moze zawierać błedy. Autor nie odpowiada za konsekwencje wynikłe z uzytkowania tego dokumentu.
Jezeli masz jakieś sugestie lub chcesz mnie poinformować o błedzie, zawsze jestem otwarty na słowa konstruktywnej krytyki.
Mój e-mail to jps (at) mars iti pk edu pl.
Jezeli nadal czujesz niedosyt informacji, przeczytaj ten dokument:
http://info.iet.unipi.it/~luigi/ip_dummynet/

© 2002 Jan Szumiec. Dokument ten moze być rozprowadzany i powielany pod warunkiem, ze jego tresć nie ulegnie modyfikacji, oraz ze wiadomosć o autorze pozostanie w dokumencie. Najnowsza wersja zawsze dostepna z http://www.iti.pk.edu.pl/~jps/dummynet.pdf






Artykuł jest z FreeBSD na www.malisz.eu.org
http://www.malisz.eu.org/

Adres tego artykułu to:
http://www.malisz.eu.org/8_Dummynet.htm