
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
| |