Traffic shaping slouží ke kontrole rychlosti přenosu dat. Lze pomocí něj určovat i prioritu pro různé přenosy, čímž můžeme např. docílit lepší odezvy u her, které hrajeme přes internet, i přesto, že náš soukmenovec stahuje ve vedlejším pokoji z p2p sítí. Celkově je toho mnohem více a my si o tom něco povíme.

Co je dnes na programu?

Pár plků o použitých programech, modulech a patchích

Naším cílem je získat sadu funkčních programů opatchovaných vším možným pro co nejširší možnosti (i když třeba pro některé zbytečnými). Některými patchi se dostanu do části, která patří spíše firewallu, ale snad mi bude odpuštěno.

iptables

Základní stavební kámen ke kontrole síťových spojení apod. Nemá cenu to nějak rozvádět, kdo nezná, nemusí číst dál. Distribuční verze nebude bohužel stačit a budeme muset patchovat, co to dá.

iproute2

Sada programů mezi nimiž je mj. program tc, který je nezbytný pro shaping. Opět se nespokojíme s distribučním balíčkem a budeme muset patchovat a kompilovat.

patch-o-matic-ng (POM)

Sada patchů pro iptables, která se neobejde bez kernelu. Na verzích těchto patchů velice záleží. V jedné verzi najdeme to a v jiné zase ne. Čím novější verze, tím méně patchů. Patche postoupí a jsou zařazeny do jádra a iptables. Několik patchů jsem nenašel nikde, a proto je nutné použít starší verze POM.

Nyní několik patchů z POM, které nás budou zajímat:

connlimit:
Umožňuje nastavit počet spojení, jak třeba na IP, tak i na jednotlivých portech. To je dobré třeba v kombinaci se stahováním ze sítě BitTorrent a starších AP, které nemohly překousnout ohromné množství spojení produkovaných sítí BitTorrent. Uplatnění lze samozřejmě najít i u jiných věcí.
geoip:
I když jsem zastáncem absolutní volnosti, tak tento patch zahrnu. Modul umožňuje pomocí externí databáze blokovat spojení přicházející z určitého státu (asi i města). Nechcete, aby se na váš server nějak pokoušeli připojit tučňáci ze severního pólu? Tohle je pro vás to správné řešení.
ipp2p:
Tento modul je schopen identifikovat pakety z p2p sítí. Tím pádem je můžeme filtrovat.
IPMARK:
Pomocí tohoto modulu můžeme označovat různé pakety, a díky tomu je pak můžeme jednoduše filtrovat. K jejich rozeznání nám poslouží buď zdrojové IP adresy, porty nebo jiná rozšíření typu ipp2p apod.
TARPIT:
Na TCP úrovni umožňuje zvýšit dobu odezvy na určitých portech díky nestandardnímu nastavení v TCP/IP protokolech, které jsou vyvolány útočníkovými akcemi typu scanování, automatizovaných útoků atd. V dnešní době už je ale tarpit rozeznatelný a nevím, na kolik procent je účinný.
nth:
Jednoduše řečeno umí sloučit internetové kapacity (Load Balancing). Řekněme, že máme třeba 3 přístupy na internet po 50 kB/s. Pomocí tohoto modulu je můžeme jakoby spojit a mít přístup s rychlostí stahování 150 kB/s.
time:
Umožňuje nám zacházet s pakety pomocí času/data. Pokud třeba chceme shapovat jinak v noci a jinak přes den atd.
u32:
Slouží k filtrování paketů. Myslím, že si je i umí poznačovat jako iptables pomocí IPMARK, ale není to moc šťastné řešení, jelikož jsou potom problémy se stabilitou (nebo bývaly?).
ROUTE:
Umožňuje měnit paketům výchozí bránu.

layer7 filtr

Tento filtr umožňuje rozeznávat pakety na aplikační úrovni. Ve finále je to něco podobného jako ipp2p. Patch aplikujeme na kernel a iptables.

esfq

Dokáže rovnoměrně rozdělovat traffic mezi uživatele (programy, třídy ...). Když chcete třeba 1Mb linku rovnoměrně rozdělit po 200 kb, tak esfq je to pravé. Není obsažen v iproute2 a musí se patchovat spolu s kernelem. Naproti tomu stávající sfq dokáže rovnoměrně rozdělovat traffic pouze mezi TCP spojeními.

imq

Je virtuální zařízení imq0/1, kam se přesměruje veškerý provoz (nebo provoz, který chceme shapovat) a tím pádem dostaneme zařízení se vstupem či výstupem a můžeme na něm cokoliv ovlivňovat (třeba download a upload). Patchujeme s ním kernel a iptables.

Co a kde stáhnout

Pro nenechavce. Důvodem, proč u wget hned ze začátku používám parametr --continue, je to, že když stahování přeruším, tak pokračuji bez jakéhokoliv dopisování, což se mi zdá mnohem rychlejší. Nejjednodušší je stahovat přímo do /usr/src. Jedním z důvodů je POM, ale případné symlinky můžete linkovat jinam, to je na vás.

cd /usr/src
wget -c ftp://ftp.cz.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.27.tar.bz2

Kernel řady 2.6.17 ještě nepoužívám. Donedávna byly problémy i s některými patchi pro řadu 2.6.16. Na patchování používat zásadně vanilla kernel. Distribuční kernel by se vám nemuselo podařit buď opatchovat nebo zkompilovat..

wget -c http://www.netfilter.org/projects/iptables/files/iptables-1.3.5.tar.bz2
wget -c http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/patch-o-matic-ng-20060626.tar.bz2
wget -c http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/patch-o-matic-ng-20060511.tar.bz2

Verze 20060511 je poslední, která obsahuje patch geoip, takžeme budeme muset patchovat 2x. Myslím, že od verze 20060707 už není zahrnut v POM patch pro ipp2p, takže bych se vyhnul novějším verzím POM. Osobně mám vyzkoušenou verzi 20060626. Mohli bychom také patchovat ipp2p ručně, ale proč si zbytečně přidělávat práci.

wget -c http://www.linuximq.net/patchs/linux-2.6.16-imq2.diff
wget -c http://www.linuximq.net/patchs/iptables-1.3.0-imq1.diff
wget -c http://fatooh.org/esfq-2.6/esfq-2.6.15.1.tar.gz
wget -c http://umn.dl.sourceforge.net/sourceforge/l7-filter/netfilter-layer7-v2.2.tar.gz

Když jsem dělal experimenty, tak byl odkaz z domovské stránky projektu pouze na verzi 2.1, někde jsem našel odkaz na 2.2, ve které už jde opatchovat kernel 2.6.16 a teď koukám, že už je k dispozici i verze 2.3 pro kernel 2.6.17. Rozhodnutí ponechávám na vás, ale vzhledem k označení si myslím, že asi nebude fungovat na starších jádrech.

wget -c http://developer.osdl.org/dev/iproute2/download/iproute2-2.6.16-060323.tar.gz

Doplňující balíčky, které nejsou předmětem dnešní debaty, ale patří k výše zmiňovaným filtrům:

wget -c http://puzzle.dl.sourceforge.net/sourceforge/l7-filter/l7-protocols-2006-05-21.tar.gz
wget -c http://people.netfilter.org/peejix/geoip/tools/csv2bin-20041103.tar.gz

Nakonec by bylo ještě dobré, kdybychom si všechno rozbalili:

tar xvfj linux-2.6.16.27.tar.bz2
tar xvfj iptables-1.3.5.tar.bz2
tar xvfz iproute2-2.6.16-060323.tar.gz
tar xvfj patch-o-matic-ng-20060626.tar.bz2
tar xvfj patch-o-matic-ng-20060511.tar.bz2
tar xvfz esfq-2.6.15.1.tar.gz
tar xvfz netfilter-layer7-v2.2.tar.gz

Na závěr ještě vytvořit symlinky:

ln -s /usr/src/linux-2.6.16.27 /usr/src/linux
ln -s /usr/src/iptables-1.3.5 /usr/src/iptables

Patchování

Nejdříve opatchujeme iptables a kernel pomocí imq:

cd iptables
patch -p1 < ../iptables-1.3.0-imq1.diff

cd /usr/src/linux
patch -p1 < ../linux-2.6.16-imq2.diff

Opatchujeme iptables a kernel pomocí filtru layer7:

patch -p1 < ../netfilter-layer7-v2.2/kernel-2.6.13-2.6.16-layer7-2.2.patch

cd /usr/src/iptables
patch -p1 < ../netfilter-layer7-v2.2/iptables-layer7-2.2.patch

Musíme ještě nastavit příslušná práva pro nová rozšíření v iptables:

chmod +x extensions/.layer7-test
chmod +x extensions/.IMQ-test
chmod +x extensions/.IMQ-test6

Dále opatchujeme iproute2 a kernel pomocí esfq:

cd /usr/src/iproute2-2.6.16-060323
patch -p1 < ../esfq-2.6.15.1/esfq-iproute2.patch

cd /usr/src/linux
patch -p1 < ../esfq-2.6.15.1/esfq-kernel.patch

A nakonec jsme si nechali POM. Jsou dva způsoby, jak použít patche z obou verzí POM. Buď chybějící patche dodáme do novějších POM, nebo budeme 2x patchovat, čemuž osobně dávám přednost. Nejdříve ovšem budeme muset (pokud nechcete ručně upravovat Makefile v kernelu) opatchovat samotné POM.

První patch je pro geoip. Naleznete ho zde: patch-geoip.patch a na internetu se nachází v konferenci na lists.netfilter.org.

Tento soubor si uložte do /usr/src/ a můžeme se hned pustit do opatchování geoip:

cd /usr/src/patch-o-matic-ng-20060511
patch -p1 < ../patch-geoip.patch

Dále si opatchujeme connlimit a IPMARK v novější verzi POM. Zde je patch: patch-connlimit.patch a na internetu se nachází na patchwork.netfilter.org.

Tento patch si uložíme do /usr/src/ a hned můžeme opatchovat POM:

cd /usr/src/patch-o-matic-ng-20060626
patch -p1 < ../patch-connlimit.patch

Tak a nyní můžeme s klidným svědomím opatchovat kernel a iptables:

/usr/src/patch-o-matic-ng-20060511
./runme geoip nth

Jelikož jsme si vytvořili symlinky, tak nemusíme pracně zadávat cestu ke kernelu a iptables a můžeme jen potvrdit nabízené cesty. Kdyby se objevila nějaká otázka, tak "y" a enter je správná odpověď.

Pokud na nás ovše vyskočí nějaká chybka typu :

Hey! KERNEL_DIR is not set.

Tak nám nezbývá než definovat proměnou KERNEL_DIR nějak takto :

export KERNEL_DIR=/usr/src/linux-2.6.16.27

Nyní přejdeme k ostatním patchům v novějším POM:

cd /usr/src/patch-o-matic-ng-20060626
./runme time u32 connlimit ipp2p IPMARK ROUTE TARPIT

Postup je stejný jako v předchozím případě.

Pokud byste se rozhodli zkusit i jiné patche, třeba pomocí ručního výběru příkazem

./runme extra

tak vás musím upozornit, že se můžete dočkat chybových hlášeních typu (toto je např. z neopatchovaného geoip):

Do you want to apply this patch [N/y/t/f/a/r/b/w/q/?] y
unable to find ladd slot in src /tmp/pom-8915/net/ipv4/netfilter/Makefile (./patchlets/geoip/linux-2.6/./net/ipv4/netfilter/Makefile.ladd)

A otázka na akci vyskočí znovu. Řešením je zadat "f" jako force. Patch se aplikuje, jediný problém je, že se neaplikuje zápis do příslušného Makefile v kernelu, a tudíž ani po výběru položky se daný modul nezkompiluje. To lze vyřešit. Jak jinak, než ručním dopsáním Makefile. Najdete si Makefile patche, který se jmenuje Makefile.ladd. V našem případě je to v podadresářích /patchlests/geoip/linux-2.6/net/ipv4/netfilter/Makefile.ladd. Obsah tohoto souboru přepište do Makefile v kernelu v příslušných podsekcích. Takže nějak takto:

cat /usr/src/patch-o-matic-ng-20060511/patchlets/geoip/linux-2.6/net/ipv4/netfilter/Makefile.ladd >> /usr/src/linux/net/ipv4/netfilter/Makefile

Některé patche nemusíte zkoušet vůbec, buď jsou zbytečné, nebo s nimi jádro nezkompilujete. Např. tyto:

rpc
rtsp-conntrack
sip-conntrack-nat
quake3-conntrack-nat

Nastavení kernelu

Osobně se okolo iptables a shapování držím pravidla: Co jde, tak zkompilovat do modulu. Konečné rozhodnutí je na vás. Hlavní položky v kernelu pro shaping jsou tyto:

Networking --->
[*] Networking support
Networking options --->
[*] Network packet filtering (replaces ipchains) --->

V těchto podsekcích zaškrtáme, co se dá:

Core Netfilter Configuration --->
IP: Netfilter Configuration --->
IPv6: Netfilter Configuration (EXPERIMENTAL) --->

V této sekci se nacházejí shapovací filtry:

Networking --->
[*] Networking support
Networking options --->
QoS and/or fair queueing --->

Pozor na imq. Položka, která vytváří virtuální imq, se nachází zde:

Device Drivers --->
Network device support --->
<M> IMQ (intermediate queueing device) support

Tady ještě přikládám můj přeplácaný config.

Kompilace a instalace

Nejtriviálnější věc nakonec, to už tu snad nemusím ani uvádět, ale pro úplnost. Hlavně nezapomeňte odinstalovat distribuční verze programů iproute2 a iptables!

iproute2

Tady pozor. Když se vyskytne při kompilaci nějaká chyba, tak ji to jen vypíše a pokračuje dál. Pokud tedy nebudete sledovat, zda tam nemáte nějaký error, tak se nakonci dozvíte, že je všechno ok, ale pak vám půlka věcí nepůjde. Podle mých zkušeností byste v Debianu měli mít nainstalované mj. tyto balíčky: libdb2-dev, bison, flex. U jiných distribucí to bude asi obdobné.

cd /usr/src/iproute2-2.6.16-060323
make
make install

iptables

cd /usr/src/iptables
make
make install

kernel

...
make
make install
make modules_install
...

Závěr

Tak, teď byste měli být vybaveni pro trochu lepší shaping. Pokračování bude na téma shapovacích skriptů - celé výsledné řešení.