- konfiguracja w pliku /etc/niceshaper0.6/config, dzieli się na sekcje,
wymagana jest sekcja globalna oraz minimum jedna sekcja,
na potrzeby kontroli okreslonych klas ip na okreslonych interfejsach.
- dla każdej sekcji w systemie zostanie powołany proces potomny niceshapera,
kontrolujący wyłącznie sobie przypisane klasy.
- konfiguracja składa się z "dyrektyw",
oraz ich "parametrów" i "wartości".
- każda linia konfiguracji musi rozpoczynać sie od "dyrektywy.
- dyrektywy zaopatrzone w wiele "parametrów", w zalezności od preferencji,
mogą zostać dla wygody i czytelności rozbite na niezależne linie .
- nie wolno rozbijać dyrektyw iface oraz support.
- akceptowane jednostki przepustowości to bit, bps lub b/s oznaczające bity na sekundę, B, Bps lub B/s oznaczające Bajty na sekundę, do których można dowolnie dodawać przedrostki 'k|m'.
- gdy jednostka zostaje pominięta użyta zostaje jednostka domyślna czyli b/s ( bit na sekundę ).
- dozwolone jest komentowanie za pomocą znaku '#' i odnosi się do reszty linii za znakiem '#'
- znak ';' jest zamiennikiem konca linii, pozwala zminimalizować długość pliku konfiguracyjnego klas.
- wszelkie zmiany w konfiguracji do wejścia w życie wymagają zrestartowania programu.
- poniższa konfiguracja i dostarczona z pakietem są tylko przykładem i nie są optymalne dla każdej sieci.
Opcje globalne:
<global>
run download upload
support mark on eth0
stats unit kB/s
stats file /var/www/stats/nsstats.txt
stats owner root group root mode 644
</global>
run - lista sekcji na potrzeby których należy uruchomić instancje (muszą być skonfigurowane).
wygodne by tymczasowo wyłączyć jedną z sekcji bez potrzeby usuwania lub komentowania konfiguracji.
support mark on - lista interfejsów oddzielonych spacją na których w miejsce filtru u32 należy użyć filtru fw.
opcja niezbędna gdy chcemy korzystać z możliwości filtrowania które posiadają iptablesy lecz już filtr U32 nie.
stats - wyświetlanie statystyk pracy.
{unit} - wyświetlane jednostki przepustowości.
{file} - zrzut będzie na bieżąco wykonywany do wskazanego pliku ( none wyłącza ).
{owner} - ustawia systemowego właściciela pliku ( domyslnie root ).
{group} - ustawia systemową grupę do której należy plik ( domyslnie root ).
{mode} - ustawia uprawnienia do pliku w trybie numerycznym ( domyslnie 644 ).
3 ostatnie opcje nie mają zastosowania jeśli automatyczny zrzut nie został włączony ( file none )
Konfiguacja sekcji:
<download>
iface eth1 match dstip 192.168.0.0/24
iface eth2 match dstip 192.168.1.0/24
section speed 512kB/s
section shape 450kB/s
default low 10kB/s
default ceil 100kB/s
default htb-prio 5
default htb-scheduler sfq
default hold 30s
debug iptables iproute
mode download
reload 3s
</download>
iface interfejs match test
- przyporządkowujemy określony ruch IP danej sekcji określając go za pomocą filtrów niceshapera. ( opis niżej )
- informujemy na którym interfejsie należy założyć kolejkę HTB.
Co ważne!! HTB dokonuje kolejkowania WYŁĄCZNIE na interfejsie którym pakiet opuszcza router i ten interfejs należy tu definiować.
- nie występuje już wzorem ns0.5 żadne rozróżnienie na interfejs zewnętrzny i wewnętrzny.(inet/local)
- do danej sekcji można przyporządkować dowolną ilość niezależnych regułek.
- zdefiniowane filtry dotyczą wyłącznie iptablesów, konstruując reguły dla klas należy zadbać
by były one częścią tego ruchu, w przeciwnym razie ruch faktyczny i mierzony przez ns w ramach sekcji
może się różnić.
- najczęściej określana tu będzie wyłącznie obsługiwana podsieć lokalna, stąd w uproszczonej składni :
iface eth1 dst network 192.168.0.0/24
iface eth0 src network 192.168.0.0/24
- iptables i iproute nie rozróżnia aliasów na interfejsach stąd w przypadku takich interfejsów pomijamy wszystko za dwukropkiem.
- vlany zapisywane w formie ethX.vid obsługiwane są identycznie jak to ma miejsce w linuksie.
eth1 - interfejs fizyczny eth1
eth1 - alias eth1:1
eth1.100 - vlan z vid = 100 na interfejsie fizycznym eth1
section - ogólne parametry pracy sekcji (zwykle parametry łącza lub przyporządkowanej części).
{speed} - fizyczna wydajność pasma.
{shape} - poziom na jakim chcemy utrzymać obciążenie.
- ważne by dobrać wartość o kilkanaście procent mniejszą od faktycznej wydajności naszego łącza.
Jeśli zbyt wysoko ustawimy ten parametr, będzie cierpieć ruch interaktywny.
- bardzo częstym błędem jest określanie tu tak wysokiej wartości że realne obciążenie nigdy nie sięga tej wartości,
NiceShaper nie będzie spełnia swojej roli, a użytkownicy otrzymają maksymalne przydziały.
Dla NiceShapera pietrwszym sygnałem do "obcinania", jest właśnie wykrycie przekroczenia tej wartości.
default - definiuje parametry wspólne dla wszystkich klas,
które mogą być następnie indywidualnie modyfikowane w pliku class.
{low} - minimalny przydział
{ceil} - maksymalny przydział.
{rate} - stały przydział.
{htb-prio} - priorytet dla klasy w htb,
przyjmuje wartości od 0 do 7, przy czym niższa wartość to wyższy priorytet. Domyślnie ma wartość 5.
{htb-scheduler} - wybór schedulera dla klasy w htb, z pomiędzy obsługiwanych { none|sfq }.
{hold} - czas nieaktywności po którym klasa zostaje wyładowana z HTB.
{iptables-return} - pakiety zakwalifikowane do klasy będą wracały z spowrotem do łańcucha PREROUTING/POSTROUTING
np. w celu dalszej obróbki przez firewalla. Domyślnie wybierany jest cel ACCEPT i pakiet kończy swoja drogę w danym łańcuchu wbudowanym tabeli mangle
reload - okres taktowania, w sekundach.
wartość domyślna 4s jest bezpieczna i w miarę efektywna dla każdej maszyny klasy pentium I.
na maszynach z szybszym procesorem warto zwiększyć częstotliwość wykonywania nawet do 2s,
co wyraźnie zwiększa interaktywność.
Wartośc parametru musi się mieścić w przedziale 0.1s do 600s z krokiem nie mniejszym niż 0.1s.
mode - drobna opcja dla iptables ale w tej postaci wydaję się być bardziej czytelna
dla nieznających w minimalnym stopniu tego firewall'a,
a za zadanie ma ona określić czy wpis ma zostać ulokowany w łańcuchu PREROUTING ( dla upload ),
czy POSTROUTING ( dla download ).
debug - wyświetla przekazywane do systemu instrukcje.
{iptables} - wyświetla instrukcje przekazywane iptables.
{iproute} - wyświetla instrukcje przekazywane do programów z pakietu iproute ( tc, ip ).
- plik /etc/niceshaper0.6/class zawiera definicję klas, które można uznać za odpowiednik klas w HTB.
- klasa zbudowana jest z nagłówka i dyrektyw konfiguracyjnych.
- każdy pakiet zostaje zakwalifikowany do danej klasy po uprzednim sprawdzeniu wszystkich filtrów klas w kolejności
w jakiej zostały umieszczone w pliku konfiguracyjnym.
- Do dyspozycji poza standardową klasą mamy 3 dodatkowo predefiniowane typy:
do-not-shape - klasa tego typu nie zostaje wprowadzona do HTB, powołane zostają jedynie filtry kierujące ruch
do kolejki root tak by zdefiniowany w tej klasie ruch nie był w żaden sposób ograniczany.
Klasa ta istnieje jednak w iptables dzięki czemu możemy mierzyć wykorzystywane przez nią pasmo.
virtual - posiada wpisy tylko i wyłącznie w iptables. Klasa tego typu służy do mierzenia wykorzystywanego pasma.
W przeciwieństwie do poprzedniego typu ruch zakwalifikowany do tej klasy nie partycypuje w utylizacji sekcji a dodatkowo nie
zostaje usunięty z łańcucha w iptables i może być dalej zakwalifikowany do jednej z kolejnych fizycznych lub virtualnych klas
wrapper - klasa ta jest przydatna gdy chcemy ograniczyć coś co nie wpływa na wykorzystanie łącza,
( np. transfer z lokalnego serwera plików, który kontrolujemy jedynie dlatego by nie przeciążać lokalnej sieci radiowej ),
więc nie potrzebujemy podziału dynamicznego ani wliczania tego ruchu do wykorzystania łącza.
(*)Odpowiednia opcja umożliwi tutaj określenie by ruch był wliczany w sumaryczną utylizacje przez sekcję,
w tym momencie klasa taka może zostać użyta do mierzenia ruchu którego nie jesteśmy w stanie kontrolować lub który
uzyskać ma bezwzględny priorytet, inne klasy zostaną ograniczone tak by wartość
link shape nie została przekroczona.
budowa klasy
przykładowa najprostsza klasa ma postać:
class download eth1 Mariusz
match dstip 192.168.0.77
lub w zagnieżdzonej postaci ( w dalszej części będzie używany pierwszy czytelniejszy sposób zapisu ):
class download eth1 Mariusz ; match dstip 192.168.0.77
definicje klasy rozpoczyna nagłówek klasy a kończy kolejny nagłówek lub koniec pliku:
class sekcja interfejs nazwa
{sekcja} - w tym momencie ciągle jeszcze jedna z wbudowanych: download lub upload
{interfejs} - interfejs na którym realizowane jest kolejkowanie danej klasy przez HTB.
{nazwa} - nazwa klasy wyświetlana przez stats
Obowiązkowym parametrem ciała klasy jest filtr:
match test
- filtry definiują ruch którym dana klasa będzie zarządzać.
- każdą klasę może budować dowolna liczba filtrów ( minimum jeden ).
- naturalnie powyższe testy można ze sobą łączyć by uzyskać bardziej szczegółowe filtry.
Testy podstawowe:
{proto} - protokół ( tcp, udp lub icmp ).
{srcip} - adres źródłowy.
{dstip} - adres docelowy.
{srcport} - port źródłowy ( należy wskazać protokół tcp lub udp ).
{dstport} - port docelowy ( należy wskazać protokół tcp lub udp ).
{from localhost} - oznacza wszystko co pochodzi z localhosta, szczegółowy opis wykożystania w rozdziale "Jak traktować localhosta"
{to localhost} - oznacza wszystko co skierowane jest do localhosta, szczegółowy opis wykożystania w rozdziale "Jak traktować localhosta"
srcip oraz dstip mogą wskazywać adres ip lub podsieć adresów o zasięgu zdefiniowanym w standardowy sposób przez maskę,
zapisaną w formacie bitowym lub kropkowo-dziesiętnym.
Maska nie musi być ciągła ( np. 255.255.128.255 ) jednak należy pamiętać że takiej sytuacji nie obsługuje filtr u32
i dla masek nieciągłych trzeba posłużyć się markowaniem pakietów.
przykładowe filtry:
pakiety skierowane do adresu 192.168.0.77:
match srcip 192.168.0.77
poczta pobierana z interii do podsieci 192.168.0.0/29:
match srcip 217.74.65.69 srcport 110 dstip 192.168.0.0/29
Testy wymagające włączonego markowania na interfejsie:
Iptables został zaopatrzony w olbrzymią liczbę filtrów, które nie są niestety możliwe do zrealizowania przy użyciu filtra U32. Dlatego też poniższe filtry wymagają mark'owania przez (support mark on). Każdy wychwycony i oznaczony przez iptables pakiet może już być bez problemu skolejkowany do odpowiedniej klasy HTB dzięki filtrowi fw który zostaje użyty w miejsce filtra u32 ten aspekt będzie szczególnie rozbudowywany w kolejnych wersjach testowych i zależny jest od możliwości iptables w systemie.
{state} - stan pakietu:
new - pakiet rozpoczyna nowe połączenie
established - pakiet nalezy do nawiązanego połączenia
related - pakiet rozpoczynajacy nowe połączenie jednak powiązany z istniejącą konwersjacją ( np. transfer danych po ftp )
invalid - pakiet niemoże zostać rozpoznany
untracked - pakiet nie należący do śledzonego połączenia
{tos} - wartość pola TOS pakietu.
{ttl} - TTL pakietu równe podanej wartości
{ttl-lower} - TTL pakietu mniejsze od podanej wartości
{ttl-greater} - TTL pakietu większe od podanej wartości
{mark} - pakiety oznaczone podaną wartością
dodatkowe parametry sterujące pracą danej klasy:
W ramach dodatkowych parametrów nadpisać możemy każdy z domyślnych parametrów zdefiniowanych w ramach dyrektywy default ( rate, low, ceil, htb-prio, hold )
Wykorzystanie interfejsów IMQ
NiceShaper nie przekierowuje automatycznie na interfejs IMQ tak jak to było w poprzednich wersjach,
ze względu na elastycznośc którą zyskujemy przez możliwość dowolnego kombinowania wielu interfejsów fizycznych i IMQ.
Obecnie interfejsy IMQ konfiguruje się analogicznie jak te fizyczne pomijając ich wirtualność.
Właśnie przekierowanie na dany interfejs wirtualny w ramach iptables należy wykonać poza NiceShaperem lub jawnie
tego zarządać od programu poprzez dodanie do wybranych klas parametru:
imq-redirect
dla ułatwienia w ramach konfiguracji sekcji posłużyć się można opcją default która automatycznie doda ten atrybut do wszystkich przyporządkowanych sobie klas:
default imq-redirect
Przykładowy wycinek pliku config:
iface eth1 match dstip 192.168.0.0/24
iface eth2 match dstip 192.168.1.0/24
iface imq5 match dstip 10.10.5.0/24
default imq-redirect
Jak traktować localhosta
Ze względu na możliwość wykorzystania takich technologii jak NAT czy IMQ, zagadnienie to jest ciut bardziej zawiłe niż mogło by się wydawać na pierwszy rzut oka. Poza faktem forwardowania ruchu między siecią lokalną a internetem router samemu może pobierać lub wysyłać dane, jeśli komputery sieci lokalnej maskowane są do adresu routera powstaje problem odróżnienia ruchu klientów od generowanego i odbieranego przez samą maszynę routera. W realnym świecie router często jest także serwerem usług, tutaj nie zadowala nas wydzielenie kolejki dla ruchu routera lecz bardziej zaawansowany przydział różnego pasma dla każdej z nich. Na wstępie wspomnę o kilku zasadach:
Rozszerzenie filtrów o dyrektywy from/to localhost zmienia sposób konfigurowania klasy w iptables.
Powoduje stworzenie dowiązania z łańcuchów OUTPUT/INPUT, a do samych reguł zostaje dodany także podany interfejs,
jako interfejs wychodzący/wchodzący.
Należy pamiętać by klasy tego typu znajdowały się na samym początku chyba że chcemy osiągnąć inny efekt niż jestem w stanie przewidzieć w ramach krótkiej notki.
Tak więc by dobrze przyjrzeć się sytuacji posłużę się czterema możliwymi kombinacjami:
1. wymiana ruchu między routerem a siecią lokalną ( niema problemu NATu, adresy źródłowe i docelowe widzimy w oczekiwany sposób ):
a) Ruch z localhosta do sieci lokalnej ( np. lokalny serwer ftp, samby, pop3 ).
Sytuacja jest bardzo przejrzysta, tworzymy klasę typu download gdyż to nasze hosty lokalne ściągają dane,
można także użyć klasy typu upload, lecz wtedy należy rozszerzyć filtry o opcje from localhost. Dlaczego?
Dla klas typu upload tworzymy łańcuch dowiązany z tabeli PREROUTING,
gdzie dane wysyłane przez nasz router nigdy się nie pojawią, from localhost tworzy dowiązanie z tabeli OUTPUT.
Ogólnie bezpiecznie jest zawsze sygnalizować że mamy do czynienia z localhostem, gdyż to właśnie tabela OUTPUT daje nam możliwość 100 procentowego
określenia że ruch pochodzi z procesów lokalnych.
Dowiązanie do sekcji typu download czy upload jest drugoplanowe, bo z reguły będziemy się starali takiego ruchu nie wliczać do ruchu
generowanego przez wymianę z siecią internetową.
class download eth1 pop3_z_localhosta
match from localhost srcip 192.168.0.1 srcport 110 dstip 192.168.0.0/16 proto tcp
rate 100kB/s
do tego zalecane jest by klasa była jednym z poniższych predefiniowanych typów:
do-not-shape
# transfery są lokalne więc nie tniemy i nie wliczamy do sumarycznego wykorzystania łącza
wrapper
# transfery są lokalne ale boimy się przypchać radiówkę więc ograniczamy, lecz dalej nie wliczamy do wykorzystania łącza.
b) Ruch z sieci do localhosta ( np. zapytania do serwera proxy, wysyłanie poczty za pomocą localnego serwera smtp,
wrzucanie danych na lokalny serwer plików ).
Sytuacja jest bardzo przejrzysta, tworzymy klasę typu upload gdyż to nasze hosty lokalne wysyłają dane,
można także użyć klasy typu download, lecz wtedy należy rozszerzyć filtry o opcje to localhost. Dlaczego?
Dla klas typu download tworzymy łańcuch dowiązany z tabeli POSTROUTING,
gdzie dane odbierane przez nasz router nigdy się nie pojawią, to localhost tworzy dowiązanie z tabeli INPUT.
Ogólnie bezpiecznie jest zawsze sygnalizować że mamy do czynienia z localhostem, gdyż to właśnie tabela INPUT daje nam możliwość 100 procentowego
określenia że ruch zmierza do procesów lokalnych.
Dowiązanie do sekcji typu download czy upload jest drugoplanowe, bo z reguły będziemy się starali takiego ruchu nie wliczać do ruchu
generowanego przez wymianę z siecią internetową.
Tu powstaje mały kłopot, filtry definiujemy standardowe lecz, jeśli nie wykorzystujemy interfejsów IMQ nie mamy kontroli nad transferem. Stąd klasa może wyglądać następująco:
class upload eth0 smtp_do_localhosta
match to localhost dstip 192.168.0.1 dstport 25 srcip 192.168.0.0/16 proto tcp
do-not-shape
# gdyż nie jesteśmy w stanie wpłynąć na ten ruch a że nie wpływa on na wykorzystania łącza internetowego nie wliczamy go do niego.
Możemy wpłynąć na transfer gdy np. nie chcemy przeciążyć linku radiowego używając interfejsu IMQ:
class upload imq0 smtp_do_localhosta
match to localhost dstip 192.168.0.1 dstport 25 srcip 192.168.0.0/16 proto tcp
rate 100kB/s
wrapper
imq-redirect
Oczywiście interfejs IMQ musi być danej sekcji znany, i tu warto wspomnieć o elastyczności do której dąży NiceShaper 0.6,
interfejs ten może należeć do sekcji która obsługuje ruch klientów, a może należeć do sekcji stworzonej specjalnie na potrzeby cięcia ruchu lokalnego.
Jednym słowem pełna swoboda.
2. Wymiana ruchu między localhostem a internetem.
a) Ruch z localhosta do internetu ( np. zapytania generowane lokalnie słane w świat, poczta, www i inne usługi internetowe na naszym serwerze ):
class upload eth0 localhost_do_internetu
match from localhost srcip 80.53.211.226 srcport 80
Użycie klasy typu upload i filtrowania z from localhost nie wymaga tutaj szerszego komentarza.
Daje nam pewność że właściwie odróżnimy ruch lokalny od hostów w sieci, klasa upload posiada łańcuch dowiązany z PREROUTING'u
gdzie interesujące nas pakiety nigdy się nie znajdą więc za pomocą from localhost tworzymy dowiązanie z łańcucha OUTPUT.
Dodatkowo wykorzystujemy pasmo wychodzące klientów więc naturalnie musimy ten ruch wliczyć do całkowitego wykorzystania pasma upload,
by nie rozregulować dynamicznego podziału.
b) Ruch z internetu do localhosta ( np. strony pobierane przez serwer proxy, czy aktualizacje systemu mogące zabierać pasmo klientą ):
class download eth0 localhost_z_internetu
match to localhost dstip 80.53.211.226 srcport 80
match to localhost dstip 80.53.211.226 srcport 21
Użycie klasy typu download i filtrowania z to localhost nie wymaga tutaj szerszego komentarza.
Daje nam pewność że właściwie odróżnimy ruch lokalny od hostów w sieci, klasa download posiada łańcuch dowiązany z POSTROUTING'u
gdzie interesujące nas pakiety nigdy się nie znajdą więc za pomocą to localhost tworzymy dowiązanie z łańcucha INPUT.
Dodatkowo wykorzystujemy pasmo przychodzące klientów więc naturalnie musimy ten ruch wliczyć do całkowitego wykorzystania pasma download,
by nie rozregulować dynamicznego podziału.
Tu powstaje mały kłopot, filtry definiujemy standardowe lecz, jeśli nie wykorzystujemy interfejsów IMQ nie mamy kontroli nad transferem.
Router uzyska bezwzględny priorytet na hostami klientów, sytuacja ta może być przydatna w sytuacji gdy najbardziej cenimy sobie ruch www,
który udostępniamy klienta za pomocą serwera proxy, wtedy każdy inny ruch będzie dyskryminowany na korzyść serwera proxy.
Użycie interfejsów IMQ jest identyczne jak w przykładzie dotyczącym ruchu wchodzącego z sieci lokalnej.
To tyle tytułem wstępu do tematu localhosta, z chęcią wysłucham pomysłów na inne bardziej zawiłe sytuacje do których postaram się znaleść rozwiązania celem rozszerzenie powyższego opisu.
bez parametrów dla downloadu i uploadu( zapis równoważny zapisowi w wersji 0.5 i starszych ):
192.168.0.101 section download eth1 section upload eth0
192.168.0.102 section download eth2 section upload eth0
z parametrami:
192.168.0.101 section download eth1 low 32kB/s ceil 1024kB/s section upload eth0 low 12kB/s ceil 24kB/s
192.168.0.102 section download eth2 low 16kB/s ceil 256kB/s section upload eth0 low 6kB/s ceil 12kB/s
w sytuacji gdy chcemy otrzymać klasy w kilku sekcjach:
192.168.0.101 section download eth1 section upload eth0 section upload_proxy imq0
192.168.0.102 section download eth2 section upload eth0 section upload_proxy imq0
- low - minimalny przydział
- ceil - maksymalny przydział
- rate - stały przydział
- htb-prio - priorytet klasy w HTB, przyjmuje wartości między 0 a 7, czym niższa wartość tym wyższy priorytet. Domyślnie ma wartość 5.
jak widzimy deklaracja dla danej sekcji zaczyna sie od słowa kluczowego section i z kolejnym lub z końcem linii się kończy.
--confdir /wspolna_sciezka_do_wszystkich_plikow_konfiguracyjnych
--conffile /sciezka/plik_konfiguracyjny
--classfile /sciezka/plik_z_klasami
--usersfile /sciezka/plik_users
O ile opcja --confdir nadpisuje połozenie katalogu dla wszystkich plików co powoduje w dalszej kolejności wyszukiwanie
pliku konfiguracyjnego, pliku z klasami i pliku users w danym katalogu, o tyle opcje --conffile, --classfile, --usersfile nadpisują
to ustawienie globalne wskazując że wybrany/wybrane pliki znajdują się poza tym katalogiem i dodatkowo moga się inaczej nazywać niż domyślnie.
opcja usersfile póki nie zostanie zaimplementowana konwersja w czasie uruchamiania ma zastosowanie jedynie dla trybu convert.