Wstęp
Konfiguracja opisywanej tu wersji NieShapera może przysporzyć pewnym problemów,
stąd po wstępnym przyjrzeniu się dołączonym przykładowym plikom konfiguracyjnym ( które same w sobie są całkiem niezłym wprowadzeniem ),
należy zapoznania się z niniejszą dokumentacją, w przeciwnym wypadku może nie udać się stworzyć optymalnie działającego podziału łącza.
Dlatego bardzo rzadko odpisuję na listy pisane w stylu: "nie działa", "nie uruchamia się", "nie potrafię zainstalować",
czy jakże dowcipne: "wyskakuje jakiś błąd".
Za to z przyjemnością czytam listy od osób które zadały sobie trud by zrozumieć program,
i skonfigurować swój router linuksowy do świadczenia swoim klientom wysokiej jakości usługi dostępu do internetu.
Wymagania
W minimalnej konfiguracji niezbędny jest router z systemem linux oraz narzędzia iptables i tc z pakietu iproute. Z filtrami u32 i/lub fw.
NiceShaper bardzo się stara ale nie jest w stanie przewidzieć wszystkich Twoich intencji, dlatego pomocna będzie znajomość tych narzędzi.
Opcjonalną częścią programu jest obsługa IMQ, pomagająca kontrolować ruch wychodzący z sieci SNATowanej a także obsługiwanej przez serwer proxy, uruchomiony na tej samej maszynie routującej.
Instalacja
Ściągnięty oraz rozpakowany pakiet kompiluje i instaluje się w dość standardowy sposób, do przeprowadzenia kompilacji wymagane są pakiety kompilatora c++ z gcc i program make:
$ make
$ su
# make install
w efekcie w katalogu /usr/local/bin pojawi się gotowy program.
Jeśli jeszcze nie posiadamy w systemie plików konfiguracyjnych, można przekopiować pliki przykładowe:
# cp -R etc/niceshaper /etc/
W przeciwnym wypadku należy upewnić się czy między starą a aktualnie instalowaną wersją, nie zaszły zmiany składni.
Konfiguracja
Składnia plików konfiguracyjnych.
Wymagane podstawowe pliki konfiguracji to /etc/niceshaper/config.conf oraz /etc/niceshaper/class.conf.
include file <sciezka> - dyrektywa include użyta w tych plikach pozwala włączać kolejne. Dyrektywa include obsługuje ścieżki absolutne (z rozpoczynającym znakiem slash) oraz relatywne do katalogu konfiguracyjnego (domyslnie /etc/niceshaper).
Konfiguracja składa się z kilku typów dyrektyw różniących się składnią:
Zapis - "parametr" "wartość" ["wartość"] czyli parametr z przypisanymi mu pojedynczymi lub oddzielonymi białymi znakami (spacja, tabulator) wartościami, np.:
rate 128kB/s
debug iptables iproute
Zapis - "dyrektywa" "parametr" "wartość" ["parametr" "wartość"], czyli dyrektywa z listą parametrów i przypisanymi im pojedyńczymi wartościami, np.:
stats
file /var/www/stats/nsstats.txt
unit kB/s
mode 644
W obydwu przypadkach parser konfiguracji automatycznie rozbije podane wartości lub pary parametrów z wartościami, więc w ramach własnych preferencji powyższe przykłady można także zapisać następująco:
rate 128kB/s
debug iptables
debug iproute
stats file /var/www/stats/nsstats.txt
stats unit kB/s
stats mode 644
Kolejność parametrów nie jest istotna jednak niektóre koliduja lub nawet wykluczają się wzajemnie. Np. uzycie schedulera esfq powoduje że parametry odnoszące sie do innych typów schedulerów nie są brane pod uwagę, uzycie do-not-shape wyklucza virtual i odwrotnie, itd.
Zapis dyrektyw match oraz include to również lista par parametr i wartość, jednak nie można ich rozbijać na osobne linie gdyż zburzyło by to sens/spójność więc i zachowanie tych dyrektyw o czym więcej w odpowiednich częściach dokumentacji.
Zapis dyrektywy class nie podlega żadnej elastyczności.
Podstawowe jednostki przepustowości to b/s-bit na sekundę, oraz B/s-bajt na sekundę. Z przedrostkami k(K)-kilo, m(M)-mega. Jednak dopisek '/s' nie jest obowiązkowy a rozróżnienie między przepustowością a ilością przesłanych danych odbywa się na podstawie kontekstu użycia. Jednostką domyślną jest b/s (bit na sekundę).
NiceShaper udostępnia kilka znaków specjalnych:
- Znak '#' jest komentarzem i odnosi się do reszty linii za nim, również znaki <# komentarz #> tworzą komentarz, z tą różnicą że stosuje się je w parze a obejmują dowolnie duży wycinek konfiguracji. Zakomentowana część konfiguracji nie jest brana pod uwagę.
- Znak średnika zastępuje przejście do nowej linii konfiguracyjnej, pozwala zminimalizować długość pliku konfiguracyjnego klas, czasem pozytywnie a czasem negatywnie wpływa na czytelność.
Zmiany w konfiguracji wymagają zrestartowania programu.
Wszystkie konfiguracje dostarczone z pakietem są tylko przykładami i nie są optymalne dla każdej sieci.
Główny plik konfiguracyjny, na przykładzie łącza asymetrycznego 4Mbit/512kbit.
Domyślnie głównym plikiem konfiguracyjnym jest plik /etc/niceshaper/config.conf. Jest on podzielony na sekcje,
gdzie wymagana jest sekcja globalna o nazwie global oraz minimum jedna sekcja na potrzeby kontroli określonego filtrami ruchu.
Dla każdej sekcji uruchomiony zostanie niezależny proces NiceShapera, dysponujący własnymi ustawieniami oraz kontrolujący wyłącznie sobie przypisane klasy.
<global>
- run download upload
- mark-on-ifaces eth0
- stats unit kB/s
- stats file /var/www/stats/nsstats.txt
- stats owner root group root mode 644
- log syslog yes
- log terminal yes
- log file no
<download>
- match dstip 192.168.0.0/24
- 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
- mode download
- reload 3s
Opcje globalne:
run - lista sekcji na potrzeby których uruchomione zostaną skonfigurowane instancje NiceShapera.
mark-on-ifaces - lista interfejsów wyjściowych na których w miejsce filtru u32 użyty zostanie filtr fw czyli markowania pakietów. Opcja ta jest niezbędna by kontrolować upload hostów z adresacją prywatną poddawanych maskowaniu na adres publiczny routera lub korzystać z możliwości filtrowania które posiadają iptablesy lecz już filtr U32 nie.
lang {en|pl} - określa język komunikatów (domyślnie definiowany przez zmienną środowiskową LANG. Aktualnie poza domyślnym językiem angielskim, obsługiwana jest wartość pl_PL.UTF-8 tej zmiennej).
stats {unit|classes|sum|file|owner|group|mode|listen} <> - wyświetlanie statystyk pracy.
- unit - wyświetlane jednostki przepustowości (domyślnie: kB/s).
- classes {all|active|working|no} - klasy wyświetlane w statystykach (domyślnie: working).
-
- all - wyświetla wszystkie skonfigurowane klasy.
- active - wyświetla klasy które wykazały aktywność.
- working - wyświetla klasy które wykazały ostatnią aktywność w czasie krótszym od ustawienia parametru hold.
- sum {top|bottom|no} - miejsce wyświetlania podsumowania obciążenia sekcji.
- file {plik|no} - włącza funkcjonalność automatycznego zrzucania statystyk do wskazanego pełną ścieżką pliku (domyślnie: no).
- owner - ustawia systemowego właściciela pliku (domyślnie: root).
- group - ustawia systemową grupę do której należy plik (domyślnie: root).
- mode - ustawia uprawnienia do pliku w trybie numerycznym (domyślnie: 644). 3 ostatnie parametry nie mają zastosowania jeśli automatyczny zrzut nie został włączony (file no).
- listen - {ip[:port]}, steruje nasłuchiwaniem niceshapera na wskazanym adresie lokalnym, umożliwiając zdalne odczytywanie statystyk (domyślnie: 127.0.0.1:6423 - tcp).
log {syslog|terminal|file} <> - sposoby logowania komunikatów.
- syslog {yes/no} - domyślnie: yes.
- terminal {yes/no} - domyślnie: yes, po poprawnej inicjalizacji zostaje automatycznie wyłączone.
- file {plik|no} - logowanie do wskazanego pełną ścieżką pliku (domyślnie: no).
fallback [iproute] - .
Opcje i konfiguacja sekcji:
match test <> [test <>]
Jest to dyrektywa filtra. Umieszczona w ramach konfiguracji sekcji przyporządkowuje jej określony ruch IP.
Najczęściej określana tu będzie cała podsieć/podsieci lokalne,
stąd powyższe przykłady są w zasadzie na ten moment wystarczającym tłumaczeniem.
Pełny opis filtrów NiceShapera znajduje się w dalszej części dokumentacji.
Filtry sekcji w przeciwieństwie do filtrów klas, nie mają żadnego wpływu na HTB,
ich rolą jest umieszczenie w tabeli mangle odpowiednich wpisów,
kierujących pasujące pakiety do utworzonego przez NiceShapera
łańcucha (z przedrostkiem ns_) w którym rezydują filtry klas tej sekcji.
Konstrukcja ta ma za zadanie umożliwienie zliczania ruchu generowanego przez klasy,
i ew. dodatkowo przypisywania znaczników mark lub przekierowywanie na interfejsy IMQ.
Nie występuje już wzorem NiceShapera 0.6 dyrektywa iface której częścią były właśnie filtry.
Należy zadbać by zadeklarowane klasy NiceShapera obsługiwały cały przypisany sekcji ruch
w przeciwnym razie pojawią się niemożliwe do kontrolowania przecieki.
Np. w przypadku gdy nie wszystkie hosty w sieci lokalnej zostaną przypisane do klas,
te nie kontrolowane będą odbierały pasmo pozostałym.
section {speed|shape} <> - 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 łącza.
Jeśli zbyt wysoko ustawimy ten parametr, będzie cierpiał 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 pierwszym sygnałem do "obcinania", jest właśnie przekroczenie tej wartości.
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ść parametru musi się mieścić w przedziale 0.1s do 600s z krokiem 0.1s.
mode {download|upload} - parametr ten jest bardzo ważny,
gdyż sekcje integrują się z łańcuchami tabeli mangle iptablesów,
w sposób odmienny by kontrolować pakiety płynące w kierunku z internetu do sieci lokalnej/serwera,
oraz odwrotnie dla tych podążających z sieci lokalnej/serwera do internetu.
Dla mode download następuje ulokowanie filtrów głównych sekcji w łańcuchu POSTROUTING,
a dla mode upload w łańcuchu PREROUTING.
Parametr ten ma w pewnych sytuacjach wpływ na inne zachowania programu,
więc zmiany łańcucha tabeli mangle jeśli zajdzie taka potrzeba nie należy
dokonywać za jego posrednictwem, służy temu dyrektywa iptables z parametrem hook.
iptables {hook|hook-mode} <> - parametry odnoszące się bezpośrednio do iptables w systemie.
- hook {PREROUTING|POSTROUTING} - parametr będący składnikiem mode, pozwala zmienić domyślny dla ustawionego trybu łańcuch iptables (domyślnie: dla download to POSTROUTING, dla upload to PREROUTING).
- hook-mode {append|insert} - dla append reguła zostanie zapisana na końcu łańcucha, dla insert wstawiona na początek (domyślnie: append).
debug [iptables] [iproute] - 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).
default - definiuje parametry domyślne dla wszystkich klas w sekcji. Mogą być one indywidualnie modyfikowane w pliku klas. Jawne użycie słowa
default nie jest wymagane może jedynie wpłynąć na czytelność konfiguracji.
Pojęcie klasy w NiceShaperze
Plik /etc/niceshaper/class.conf zawiera definicję klas, które można uznać za odpowiednik/rozszerzenie klas w HTB.
Klasa zbudowana jest z nagłówka i opcji konfiguracyjnych (w tym obowiązkowo z minimum jednego filtra).
Pakiet zostaje zakwalifikowany do pierwszej dopasowanej za pomocą filtrów klasy.
Budowa klasy
Definicję klasy rozpoczyna nagłówek klasy a kończy nagłówek kolejnej lub koniec pliku klas.
class <sekcja> <interfejs> <nazwa>
sekcja - sekcja w skład której wchodzi klasa.
interfejs - interfejs na którym realizowane jest kolejkowanie klasy przez HTB.
nazwa - nazwa klasy wyświetlana m.in. przez stats.
Interfejs jest tu niezwykle ważny a poprawnego wskazanie tego na którym należy założyć kolejkę HTB może sprawić pewien problem.
Co ważne!! Pomijąc zabiegi typu użycie interfejsów wirtualnych IMQ, które są opisane w odpowiedniej części dokumentacji,
kernel z HTB kształtuje ruch na interfejsie którym pakiet OPUSZCZA router i ten interfejs należy tu wskazać.
Przykładowo jeśli łącze internetowe podłączone jest do interfejsu eth0 a sieć lokalna do eth1.
Przy kształtowaniu pasma downloadu klientów poprawnym interfejsem klasy będzie eth1,
zaś przy kształtowaniu pasma wychodzącego z sieci czyli uploadu klientów będzie to eth0.
Iptables i Iproute nie rozróżniają aliasów interfejsów.
Które nawiasem mówiąc są przestarzałym rozwiązaniem z czasów powszechnego stosowania ifconfig zastąpionego przez polecenie ip.
Stąd w przypadku takich interfejsów z aliasami, w konfiguracji NiceShapera pomijamy część aliasową czyli dwukropek i liczbę za nim.
Natomiast vlany zapisywane w formie ethX.vid są w pełni obsługiwane.
Obowiązkowym parametrem ciała klasy jest filtr:
match test <> [test <>]
Filtry definiują ruch którym dana klasa będzie zarządzać.
Odpowiednie wpisy tworzone są przez NiceShapera zarówna w łańcuchu iptables sekcji,
jak i tworzony jest filtr HTB U32 lub FW jeśli interfejs klasy został wymieniony w dyrektywnie mark-on-ifaces.
Te pierwsze za zadanie mają zliczanie pasma wykorzystywanego przez klasę,
te drugie kierowanie do odpowiedniej klasy HTB kształtującej pasmo.
Naturalnie testy można ze sobą łączyć by uzyskać bardziej szczegółowe filtry,
zaś w skład klasy wchodzić może dowolna liczba filtrów.
Przykładowa najprostsza klasa ma postać:
class download eth1 pc55
match dstip 192.168.0.55
Lub przykłady w zwiniętej postaci (w dalszej części dokumentacji używany jest pierwszy sposób zapisu):
class download eth1 pc55; match dstip 192.168.0.55
class download eth1 pc58; match dstip 192.168.0.58
Parametry klas:
low - minimalny przydział pasma (domyślnie: 0)
ceil - maksymalny przydział pasma (domyślnie równe section shape).
rate - stały przydział pasma.
strict {0 do 100} - określa jak bardzo nie lubimy przeginających (domyślnie: 70).
Wartości niskie będą skutkowały bardziej restrykcyjnym traktowaniem tychże delikwentów.
Wartości bliskie 100 przy przeciążeniu łącza, "współodpowiedzialnością ogółu".
hold - czas nieaktywności po którym klasa zostaje wyładowana z HTB (domyślnie: 30s).
iptables {target} <> - parametry odnoszące się bezpośrednio do iptables w systemie.
- target {accept|return|drop} - cel w iptables, pakietów zakwalifikowanych do filtrów klasy.
-
- accept - jest to domyślny cel, pakiet po zakwalifikowaniu przez filtry kończy swoja drogę w danym łańcuchu wbudowanym tabeli mangle.
- return - pakiety zakwalifikowane do klasy będą wracały z spowrotem do łańcucha PREROUTING/POSTROUTING np. w celu dalszej obróbki przez firewalla.
- drop - pakiet jest odrzucany, daje to prostą metodę np. na blokowanie klientów nie płacących z poziomu NiceShapera.
htb {prio|scheduler} <> - parametry odnoszące się bezpośrednio do skonfigurowanych klas w 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: 5).
- scheduler {sfq|esfq|no} - wybór schedulera dla klasy w htb (domyślnie: sfq).
sfq {perturb} <> - konfiguracja schedulera sfq jeśli zostanie użyty w ramach klasy.
- perturb - parametr perturb dla sfq (domyślnie: 10).
esfq {perturb|hash} <> - konfiguracja schedulera esfq jeśli zostanie użyty w ramach klasy.
- perturb - parametr perturb dla esfq (domyślnie: 10)
- hash {classic|src|dst} - hash esfq (domyślnie: classic).
imq {autoredirect} <> - parametry IMQ.
- autoredirect {yes|no} - automatyczne przekierowanie na interfejs IMQ (domyślnie: yes).
type {standard-class|wrapper|do-not-shape|virtual} - do dyspozycji poza standardową klasą standard-class, mamy 3 dodatkowo predefiniowane typy:
- 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 dopuścić do przeciążenia lokalnej sieci radiowej),
Podział ruchu zakwalifikowanego do tej klasy dzielony jest statycznie a wygenerowane obciążenie nie jest brane pod uwagę przez algorytm podziału.
Klasa ta ustala kontrolowane pasmo na poziomie parametru ceil
- do-not-shape - klasa tego typu w ogóle nie zostaje wprowadzona do HTB, skonfigurowane zostają wyłącznie filtry
mające za zadanie ominięcie kolejki swojej sekcji. Dzięki czemu ruch nie jest w żaden sposób ograniczany.
Klasa ta pojawią się jednak w iptables dzięki czemu możemy mierzyć wykorzystywane przez nią pasmo.
UWAGA!! Klasa wrapper jest bezpieczniejszym rozwiązaniem.
- virtual - posiada wpisy tylko i wyłącznie w iptables. Klasa tego typu służy do mierzenia pasma przez określoną filtrem aktywność.
Tak jak w przypadku poprzednich dwóch typów klas ruch zakwalifikowany do tej klasy nie partycypuje w utylizacji sekcji a dodatkowo nie
zostaje usunięty z łańcucha w iptables i należy zadbać by w dalszej kolejności został skwalifikowany do klasy innego typu.
Wszystkie powyższe dyrektywy i parametry klasy mogą zostać użyte w konfiguracji sekcji.
By parametrów nie powtarzać dla każdej klasy z osobna w ramach konfiguracji sekcji używa się opcji/flagi default,
a następnie jeśli zaistnieje potrzeba zróżnicowania ustawień klas nadpisuje wybrane z parametrów.
Testy podstawowe:
proto {tcp|udp|icmp} - protokół.
srcip - adres źródłowy.
dstip - adres docelowy.
srcport|sport - port źródłowy. Wymaga wskazania protokołu tcp lub udp.
dstport|dport - port docelowy. Wymaga wskazania protokołu tcp lub udp.
in-iface - interfejs którym pakiet przychodzi do routeru.
out-iface - interfejs którym pakiet opuszcza router.
to-local - umożliwia kontrole pasma pobierania przez router, zastępuje dstip. Szczegółowy opis w rozdziale "Jak traktować ruch z i do routera". Wymaga wskazania interfejsu wchodzącego in-iface.
from-local - umożliwia kontrole pasma wysyłania przez router, zastępuje srcip. Patrz opis szczegółowy jak wyżej. Wymaga wskazania interfejsu wychodzącego out-iface.
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:
match srcip 192.168.0.77 - pakiety pochodzące z adresu 192.168.0.77.
match srcip 217.74.65.69 srcport 110 dstip 192.168.0.0/29 proto tcp - poczta pobierana z interii do podsieci 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 mark-on-ifaces.
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.
not-srcip - adres źródłowy inny niż podany.
not-dstip - adres docelowy inny niż podany.
not-srcport|not-sport - port źródłowy inny niż podany ( należy wskazać protokół tcp lub udp ).
not-dstport|not-dport - port docelowy inny niż podany ( należy wskazać protokół tcp lub udp ).
length - długość pakietu w bajtach, np. 500, :500( od 0 do 500), 500: ( 500 i większe ), 128:500 ( 128 do 500 ).
state {new|established|related|invalid|untracked} - stan pakietu:
- new - pakiet rozpoczyna nowe połączenie.
- established - pakiet nalezy do nawiązanego połączenia.
- related - pakiet rozpoczynający nowe połączenie jednak powiązany z istniejącą konwersacją (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ą.
Obsługa markowania pakietów:
Jeśli w danej sekcji na danym interfejsie przez mark-on-ifaces włączone zostanie markowanie pakietów.
NiceShaper dla każdego filtra wchodzącego wraz ze swoją klasą do tej sekcji, automatycznie przypisze niepowtarzalny znacznik w iptables.
By uzyskać możliwość operowania znacznikami pojawiają się odpowiednie parametry.
Trzeba tu pamiętać że każdy znacznik użyty w ramach tych parametrów zostanie poddany ochronie i NiceShaper nigdy nie użyje go we własnym zakresie, daje to gwarancje tego że żaden inny filtr nie otrzyma go automatycznie.
mark - wychwytuje pakiety oznaczone tym znacznikiem a podana wartość zostanie zachowana.
set-mark - podmienia przypisaną do filtra (automatycznie lub przez mark) wartość znacznika. Parametr ten jeśli użyty zostanie w ciele klasy (samodzielnie poza filtrem) przeniesie to oznaczenie na wszystkie filtry należące do danej klasy, dając jednak możliwości nadpisania w ramach konkretnego filtra.
Przykład:
class download eth1 pc77-79
- set-mark 6
- match dstip 192.168.0.77
- match dstip 192.168.0.78
- match dstip 192.168.0.79 set-mark 11
Pierwsze dwa filtry zostaną oznaczone znacznikiem 6 a ostatni 11.
Gdyby pierwsza opcja set-mark nie została użyta dwa pierwsze filtry otrzymały by znacznik automatycznie.
Wykorzystanie interfejsów IMQ
Od strony konfiguracji NiceShapera, interfejsów IMQ używa się analogicznie jak tych fizycznych.
Praktycznie zapomnieć można o ich wirtualności, z pełną swobodą mieszać klasy z kolejkami
na interfejsach fizycznych oraz IMQ.
NiceShaper automatycznie przekierowuje ruch na interfejs IMQ a zachowanie to jest konfigurowalne z poziomu sekcji oraz klas:
imq autoredirect {yes|no}
W przypadku wyłączenia automatycznego przekierowania na IMQ,
należy takowe wykonać dla NiceShapera: iptables ... -j IMQ --todev ...
Najwygodniej jest umieścić tą dyrektywe w konfiguracjach odpowiednich sekcji,
tym spobem stanie się ona domyślną dla wszystkich przynależnych do tych sekcji klas.
Co oczywiste zachowanie to znów można niezależnie modyfikować w ramach poszczególnych klas.
Przykładowy wycinek pliku config.conf:
<upload>
- match srcip 10.10.5.0/24
-
- ...
Oraz pliku class.conf:
class upload imq5 pc5.82
class upload imq5 pc5.83
Jak traktować ruch z i do routera
Poza forwardowaniem ruchu między siecią lokalną a internetem,
router również na własne potrzeby pobiera i wysyła dane,
np. rozwiązując nazwy dns czy przydzielając adresy ip poprzez dhcp.
Najczęściej są to pomijalnie małe w stosunku do przepustowości kontrolowanego łącza ilości danych.
Jednak w realnym świecie małych firm i sieci osiedlowych, router z Linuksem pełni często również rolę serwera usługowego,
chociażby serwując stronę www czy obsługując firmową pocztę i zasoby plikowe.
Ze względu na to że kształtowanie ruchu odbywa się na interfejsie którym pakiety opuszczają router
kontrola pasma pobierania danych jest utrudniona, wymaga wykorzystania interfejsów IMQ.
Kontrola pasma między routerem a siecią lokalną wymaga za to, no właśnie... pominięcia kontroli,
przecież nie należy ograniczać transferów lokalnych po wydajnym ethernecie nie obciążających łącza,
ba dużym błędem byłoby zakwalifikowanie ich do wykorzystania pasma przez sekcje.
Jeśli komputery w sieci lokalnej na zewnątrz maskowane są do adresu routera może pojawić się problem odróżnienia
ruchu klientów od generowanego i odbieranego przez samą maszynę routera.
Już po tych kilku zdaniach wstępu widać że zagadnienie staje się ciut bardziej zawiłe
niż mogło by się wydawać na pierwszy rzut oka.
Ze względu na architekturę NiceShapera wykorzystującego iptables w celu zliczania ruchu,
ew. markowania i przekierowywania na IMQ oraz całkowicie przecież niezależny od iptablesów QOS,
potrzeba trochę akrobacji by spiąć te 2 mechanizmy w współpracujący duet.
By praktycznie rozpatrzyć ten temat, najwygodniejsze będzie rozbicie zagadnienia na 4 niezależne scenariusze:
a) Wymiana ruchu routera z internetem (angażuje pasmo łącza).
- 1. Internet => Router - pobieranie danych przez router z internetu.
- 2. Internet <= Router - wysyłanie danych z routera do internetu.
b) Wymiana ruchu routera z siecią lokalną (nie angażuje pasma łącza).
- 3. Router => Localnet - pobieranie danych z routera przez sieć lokalną.
- 4. Router <= Localnet - wysyłanie danych do routera przez sieć lokalną.
We wszystkich przypadkach należy do filtrów dodać parami - tzn. from-local z out-iface a to-local z in-iface - testy:
from-local <ip> - zastępuje test srcip
a wskazany adres ip musi być poprawnie skonfigurowany na którymś z interfejsów routera.
W sytuacji kiedy iptables hook sekcji to PREROUTING, zmienia sposób konfigurowania filtra w iptables.
Zostaje utworzony duplikat filtra w łańcucha OUTPUT z celem w łańcuchu sekcji.
Zabieg ten jest niezbędny gdyż pakiety wychodzące z serwera nie pojawiają się w łańcuchu PREROUTING.
to-local <ip> - analogicznie jak from-local
z tą różnicą że zastępuje test dstip a dodatkowe dowiązanie tworzonego jest w łańcuchu INPUT,
jesli iptables hook sekcji to POSTROUTING.
out-iface <iface> - do reguł iptables zostaje dodany
podany interfejs jako interfejs wychodzący.
in-iface <iface> - do reguł iptables zostaje dodany
podany interfejs jako interfejs wchodzący.
Należy pamiętać że najczęściej klasy tego typu powinny znajdować się na samym początku listy klas,
chyba że chcemy osiągnąć inny efekt niż jestem w stanie przewidzieć w ramach poniższych przykładów.
Przechodząc do przykładów.
Przyjmujemy że łącze internetowe podłączone jest do interfejsu eth0 a sieć lokalna do eth1.
Adres zewnętrzny routera to 80.53.211.226 a sieci lokalnej 192.168.0.0/24
oraz że zostały skonfigurowane sekcje o nazwach download i upload z trybami pracy analogicznymi jak ich nazwy
czyli mode download i mode upload.
1. Internet => Router - pobieranie danych przez router z internetu.
Ruch z internetu do routera (np. strony pobierane przez serwer proxy, czy aktualizacje systemu mogące zabierać pasmo klientom):
class download eth0 z_internetu
- match
to-local 80.53.211.226
in-iface eth0
proto tcp
srcport 80
- match
to-local 80.53.211.226
in-iface eth0
proto tcp
srcport 8080
Użycie klasy typu download i filtrowania to-local nie wymaga tutaj szerszego komentarza.
Adres lokalny oraz interfejs wejściowy dają pewność że ruch do routera zostanie poprawnie zakwalifikowany w fazie przetwarzania papietów przez łańcuchy iptables.
Klasy należące do sekcji typu download rezydują w łańcuchu dowiązanym z POSTROUTING'u
gdzie interesujące nas pakiety nigdy się nie pojawią więc za pomocą to-local tworzymy dowiązanie z łańcucha INPUT.
Dodatkowo wykorzystywane jest pasmo przychodzące klientów
więc naturalnie należy ten ruch wliczyć do całkowitego wykorzystania pasma download,
by nie dopuścić do rozregulowania dynamicznego podziału czemu służy umieszczenie klasy w odpowiedniej sekcji.
Jednak pojawia się kłopot, jeśli nie wykorzystujemy interfejsów IMQ nie mamy kontroli nad pasmem klasy.
Można zauważyć że wskazanie interfejsu eth0 nie ma najmniejszego sensu,
występuje tu tak naprawdę tylko dlatego że testy poprawności konfiguracji NiceShapera wymagają żeby jakis interfejs został podany...
Klasa HTB na tym interfejsie nie spełni swojej roli a router uzyska bezwzględny priorytet nad hostami użytkowników.
Sytuacja ta może być akceptowalna w sytuacji gdy najbardziej cenimy sobie ruch www,
który udostępniamy klientom za pomocą serwera proxy,
wtedy można rozważyć akceptacje faktu że każdy inny ruch będzie dyskryminowany na korzyść serwera proxy.
Użycie IMQ sprowadza się do wskazania tego interfejsu w dyrektywnie class.
NiceShaper dokona przekierowania na ten interfejs, utworzy na nim klasę HTB która spełni swoją rolę.
class download imq0 z_internetu
- match
to-local 80.53.211.226
in-iface eth0
proto tcp
srcport 80
Ważny jest fakt że w ramach testu in-iface niezmieniony pozostaje interfejs fizyczny eth0.
Filtry iptables muszą wychwycic pakiety na podstawie fizycznego interfejsu, którym pakiet przychodzi do routera
a nie jest to przecież interfejs IMQ. Przekierowanie na IMQ sygnalizuje dyrektywa class.
2. Router => Internet - wysyłanie danych z routera do internetu.
Np. zapytania generowane lokalnie słane w świat: poczta, www i inne usługi internetowe na naszym routero-serwerze:
class upload eth0 www_do_internetu
- match
from-local 80.53.211.226
out-iface eth0
proto tcp
srcport 80
- ceil 64kB/s
class upload eth0 mx_do_internetu
- match
from-local 80.53.211.226
out-iface eth0
proto tcp
dstport 25
- ceil 128kB/s
Użycie klasy typu upload i filtrowania z parametrem from-local nie wymaga tutaj szerszego komentarza.
Daje nam pewność że właściwie zostanie zliczany ruch routera do internetu.
Klasa upload posiada łańcuch dowiązany z PREROUTING'u gdzie interesujące nas pakiety generowane lokalnie nigdy się nie pojawią,
więc from-local informuje NiceShapera by ten utworzył filtr w łańcuchu OUTPUT.
Wykorzystujemy pasmo wychodzące łącza, więc naturalnie by nie rozregulować dynamicznego podziału
musimy ten ruch kontrolować i wliczać do całkowitego wykorzystania pasma upload
Jeśli hosty lokalne są maskowane do adresu zewnętrznego routera obowiązkowo interfejs wychodzący musi się pojawić na liście parametru mark-on-ifaces.
3. Router => Localnet - pobieranie danych z routera przez sieć lokalną.
Np. lokalny serwer ftp, samby, pop3.
Warto rozpocząć od wyjaśnienia że dla scenariuszy 3 i 4 czyli ruchu między routerem a siecią lokalną
to czy klasy będą należeć do sekcji typu download czy upload jest drugoplanowe.
Przecież będziemy się starali takiego ruchu nie wliczać do ruchu generowanego przez wymianę z siecią internetową,
więc przykładowe przyporządkowania do odpowiednich sekcji dokonano ze względu na to że intuicyjnie
pasmo używane przy wysyłaniu danych z sieci lokalnej do routera to część uploadu klientów
a w drugą stronę czyli z routera do klientów to ich download.
class download eth1 pop3_z_localhosta
- match
from-local 80.53.211.226
out-iface eth1
proto tcp
srcport 110
dstip 192.168.0.0/24
- match
from-local 192.168.0.1
out-iface eth1
proto tcp
srcport 110
dstip 192.168.0.0/24
- type wrapper
- rate 20mB/s
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 ale za pomocą statycznie przydzielonego pasma,
lecz ciągle nie wliczamy do wykorzystania łącza.
4. Localnet => Router - wysyłanie danych na router przez sieć lokalną.
Ruch z sieci lokalnej do routera.
Np. wysyłanie poczty za pomocą lokalnego serwera smtp, umieszczanie plików na lokalnym serwerze plików itd.
Sytuacja jest przejrzysta, intuicyjnie tworzymy klasę w sekcji upload gdyż nasze hosty lokalne wysyłają dane.
Tu znów pojawia się kłopot z scenariusza 1, filtry definiujemy standardowe lecz,
jeśli nie wykorzystujemy interfejsów IMQ nie mamy kontroli nad transferem, klasa typu wrapper nie zadziała.
Klasa może wyglądać następująco:
class upload eth1 smtp_do_localhosta
- match
srcip 192.168.0.0/24
to-local 80.53.211.226
in-iface eth1
proto tcp
dstport 25
- type do-not-shape
Tutaj problem jest mniejszy, ruch tu pasujący nie obciąża łącza internetowego,
więc wystarczy nie wliczać go do niego, osiągnąć to można za pomocą dyrektywy do-not-shape.
Możemy jednak wpłynąć na transfer gdy np. nie chcemy przeciążyć linku radiowego, znów używając interfejsu IMQ:
class upload imq0 smtp_do_localhosta
- match
srcip 192.168.0.0/24
to-local 80.53.211.226
in-iface eth1
proto tcp
dstport 25
- rate 100kB/s
- type wrapper
Plik userów
Mimo przejścia w wersji 0.6 na konfigurację poprzez klasy, jako ukłon w stronę Administratorów pamiętających dobrze wersję 0.5 NiceShapera,
pozostawiono notację tak zwanego pliku userów jednocześnie nawet rozszerzając możliwości jego użycia.
Rozwiązanie to jest mało elastyczne, ogranicza możliwości wprowadzone od wersji 0.6 dzięki klasom,
jednak w podstawowych konfiguracjach z jednym łączem i dwoma sekcjami
odpowiedzialnymi odpowiednio za download i upload z sieci, daje bezsprzecznie
wygodny sposób wprowadzenia adresów ip maszyn poddawanych kształtowaniu pasma.
Domyślne położenie pliku w którym powinny się znaleźć deklaracje userów to /etc/niceshaper/users.conf.
W wskazanym domyślnym lub alternatywnym pliku muszą zostać umieszczone adresy IP hostów z sieci lokalnej,
z oddzielonymi spacją, nazwami fizycznych (z pominięciem części aliasowej) interfejsów sieciowych je obsługującego. np.:
192.168.0.101 eth1
192.168.0.102 eth1
192.168.0.103 eth1
192.168.0.104 eth1 dl_ceil 50kB/s
192.168.0.105 eth1 dl_rate 20kB/s dl_prio 1
192.168.0.106 eth2 ul_low 3kB/s ul_ceil 6kB/s
192.168.0.107 eth2
jak można się domyślić, dodatkowe parametry pozwalają nadpisać ustawienia globalne dla wybranych przypadków:
dl_low, ul_low - minimalny przydział (dla downloadu i/lub uploadu).
dl_ceil, ul_ceil - maksymalny przydział (dla downloadu i/lub uploadu).
dl_rate, ul_rate - stały przydział (dla downloadu i/lub uploadu).
dl_prio, ul_prio - priorytet klasy w HTB, przyjmuje wartości między 0 a 7, czym niższa wartość tym wyższy priorytet.
(dla downloadu i/lub uploadu). Domyślnie ma wartość 5.
Obsługa plików userów
Należy zdać sobie sprawę z faktu że plik/pliki userów nie są natywnie obsługiwane przez obecną wersję NiceShapera.
Są one w pierwszej kolejności konwertowane do postaci klas w trakcie inicjalizowania programu.
Dzieje sie to (o czym dalej) całkowicie automatycznie lub w sposób umożliwiający ingerencje w wygenerowane klasy.
Jako że w wersji 0.6 wraz ze zmianą pewnych podstawowych założeń programu, usunięto niektóre dyrektywy
dostarczające informacji potrzebnych do użycia pliku userów w sekcji global, pojawia się
zastępująca je dyrektywa users. Uzupełnia ona konfigurację o dane niezbędne do wykonania konwersji.:
users {replace-classes|download-section|upload-section|iface-inet|resolve-hostname} <> - parametry wymagane przy użyciu plików userów. Parametry te są wspólnymi (domyślnymi) dla wszystkich sposobów obsługi plików userów.
- replace-classes {yes|no} - decyduje czy plik użytkowników w pełni zastąpi domyślną konfigurację przez plik klas (domyślnie: no).
- download-section - w NiceShaperze 0.5 istniały dwie wbudowane sekcje o nienaruszalnych nazwach, obecnie nazewnictwo i ilość sekcji jest dowolna stąd wymagane jest poinformowanie konwertera która sekcja pełni rolę sukcesora sekcji download.
- upload-section - identycznie jak powyższe lecz dla sekcji upload. Dodatkowo jedna z sekcji może zostać pominięta.
- iface-inet - interfejs wychodzący określony był w samym pliku konfiguracyjnym. Jako że odpowiednia opcja nie pojawiła się w nowej wersji NiceShapera, należy określić którym interfejsem pakiety wysyłane przez użytkowników opuszczają router.
- resolve-hostname {yes|no} - parametr określający, to czy nazwa klasy przybiera postać adresu ip czy nazwy hosta, w przypadku niepoprawnej konfiguracji resolvera lub chwilowej niedostępności serwera dns pobranie adresu hosta może być niemożliwe i znacznie wydłuży czas uruchamiania. Tutaj bezpieczną wartością jest no (domyślnie: no).
NiceShaper udostępnia obsługę plików userów na 3 sposoby:
Poprzez dyrektywe users replace-classes sekcji global:
Dzięki dyrektywie sekcji global users replace-classes yes, użycie klas zostaje całkowicie wyłączone
na rzecz zastępujących je plików userów, co jest sposobem najprostszym w użyciu
i najbardziej zbliżonym do tego z wersji 0.5 zachowaniem.
<global>
- run download upload
- mark-on-ifaces eth0
- users replace-classes yes
- users download-section download
- users upload-section upload
- users iface-inet eth0
- users resolve-hostname no
- ...
Poza tym najprostszym i najwygodniejszym sposobem, plików userów używać można za pomocą jeszcze dwóch sposobów.
Wtedy parametr replace-classes otrzymać musi wartość 'no' a pozostałe parametry tej dyrektywy pozostają obowiązkowe
i stają się wartościami domyślnymi dla wszystkich operacji na plikach userów.
Dzięki temu że wartości te można nadpisywać daje to możliwość włączania/generowania wielu różnych pliku userów,
nawet przypisywania ich do różnych sekcji i interfejsów wyjściowych co zbliża możliwościami do pliku klas
jednak zaczyna być mało wygodne i nieprzejrzyste.
Poprzez dyrektywę include w pliku klas
Dzięki dyrektywie pliku klas include usersfile, która wkleja wskazany i przekonwertowany automatycznie plik userów
w miejscu wystąpienia tej dyrektywy.
Nic nie stoi na przeszkodzie by w pliku klas stworzyć klasy specjalnego przeznaczenia, np. klasy obsługujące hosta lokalnego,
ruch priorytetowy itd. a dalej w dowolnym jego punkcie włączyć wygodny w edycji plik users.
NiceShaper automatycznie i niezauważalnie dokona transformacji na klasy. Przykład:
<global>
- users replace-classes no
- users ... ...
- ...
Składnia dyrektywy include pliku klas jest bardzo podobna:
include {usersfile|download-section|upload-section|iface-inet|resolve-hostname} <> - parametry identyczne jak w dyrektywie users, nie występuje tu parametr replace-classes pojawia się parametr usersfile.
- usersfile plik - Jedyny wymagany parametr podający ścieżkę do pliku userów.
- download-section
- upload-section
-
- iface-inet
-
- resolve-hostname {yes|no}
Wartości niewymienionych parametrów pobierane są z dyrektywy users.
Oczywiście wybrane jak napisano wcześniej mogą być nadpisane nowymi wartościami,
np. tutaj włączenie dwóch plików userów w ramach jednego pliku klas:
class download eth1 poczta
- match srcport 110 proto tcp
- match srcport 143 proto tcp
- rate 100kB/s
include
usersfile /etc/niceshaper/users.conf
include
usersfile /etc/niceshaper/users2.conf
upload-section upload_isp2
iface-inet eth4
Poprzez manualnie sterowaną konwersje
Ostatnia metoda polega na użyciu parametru uruchomieniowego convert i ręczne przekierowanie/wklejenie,
wyniku konwersji do odpowiedniego pliku klas.
Znaczenie parametrów jest identyczne jak w poprzednich metodach.
Również i tutaj działa zasada wartości domyślnych ustanawianych przez dyrektywę users, które można tutaj pominąć lub nadpisać.
Pamiętać należy o poprzedzeniu każdego parametru dwoma znakami minus.
# niceshaper convert
--usersfile /etc/niceshaper/users.conf
--download-section download
--upload-section upload
--iface-inet eth0
--resolve-hostname yes
Sposób z konwersją pokazuje w jaki sposób z wskazanego lub domyślnego pliku userów i podanych parametrów generowane są klasy,
jednak jest on najmniej wygodny gdyż wymaga wykonywania dodatkowych czynności.
Dwa pierwsze sposoby konwersje przeprowadzają w pełni automatycznie i w sposób przezroczysty w trakcie uruchamiania programu,
dlatego w trakcie zaznajamiania się z funkcjonalnością plików userów oraz w przypadku podejrzeń co do poprawności
konfiguracji, zalecane jest testowe wygenerowanie pliku klas konwerterem. Tak by upewnić się że efekt
jest zgodny z oczekiwaniami i następnie przejście do metod z automatyczną konwersją.