Peer-To-Peer - často označováno jako P2P. V překladu doslova znamená "rovný s rovným". V počítačových sítích tak označujeme stroje (nodes), které plní zároveň funkci serveru i klientu. Peer-To-Peer je používáno především pro sdílení dat - většinou se jedná o audio a video soubory, ale výjimku netvoří ani streaming či IP telefonie.
V mém případě bylo nejprve důležité zjistit, co samotný traffic způsobuje. Po noci a půl strávené za terminálem s mými nejlepšími kamarády (což jsou TCPdump, kafe a dobrá muzika) jsem odhalil viníka. Za toho byl prohlášen DC++ společně s Kazou - klienty P2P sítí.
Traffic není nic jiného než tok dat v síti. Správci větších počítačový sítí jej s oblibou rozdělují na webový traffic - množství dat přenesené návštěvníky webových stránek, mail traffic - množství dat přenesených při odesílání elektronické pošty a peer-to-peer traffic - množství dat přenesených klienty povětšinou decentralizovaných sítí.
DC++ je open-source peer-to-peer klient, kterým se lze připojit do velmi rozsáhlé internetové sítě Direct Connect Network. Na rozdíl od programu KaZaA neobsahuje žádný spyware. Existuje nespočetné množství jeho modifikací včetně několika českých. Stejně jako KaZaa disponuje funkcemi sekvenčního stahování a navíc experimentálně přidává nové funkce, jako je například omezování rychlosti či hashování.
Ihned po odhalení protivníka jsem počal upravovat pravidla firewallu, ovšem jak se ve velmi krátkém čase ukázalo - zcela bezúspěšně. V okamžiku, kdy jsem zablokoval patřičný port, přes který jeden z klientů komunikoval, tak se na dalším kanále otevřel port nový, v té chvíli neblokovaný. Pochopil jsem, že tudy cesta nevede a vydal jsem se pátrat po internetu, jakým způsobem se těchto potvůrek navždy zbavit.
Na konferencích jsem vyčetl spoustu postřehů, jak bojovat proti P2P sítím na firewallu za pomoci blokování portů, omezování počtu aktivních konexí či hledání řetězce daného protokolu v každém paketu. To mě však vnitřně neuspokojilo, neboť se vždy jednalo pouze o polovičatá řešení, která měla negativní účinky, a to většinou v podobě zablokování jiných služeb, které jsem běžně na routeru provozoval. Srdce mi zaplesalo teprve poté, co jsem objevil programy iptables-p2p, L7-filter a ipp2p.
Jako první jsem vyzkoušel iptables-p2p. Bylo potřeba stáhnout hlavičkové soubory iptables, vše zkompilovat a zavést do jádra. Po této operaci jsem začal s testováním. Zjistil jsem, že iptabes-p2p výtečně blokují postarší klienty sítě Fastrack, ovšem DC++ si funguje vesele dál. Na domovských stránkách bylo datum posledního release 6. 3. 2004, takže jsem nedoufal v rychlé vyřešení problému a vydal se dál - testovat L7-filter.
FastTrack je peer-to-peer protokol používaný především programem KaZaA a jeho modifikacemi - jako je iMesh či Grokster. Jeho oblíbenost stoupla díky možnosti navázání přerušeného stahování a možností tzv. sekvenčního stahování (současné stahování stejného souboru nebo jeho části od několika uživatelů najednou).
L7-filter potřeboval stejně jako iptables-p2p patch do iptables a do jádra. Po úspěšném zkompilování a prostudování manuálu jsem byl mile překvapen možností zvolit z několika desítek protokolů (od filtrování služby SNMP přes FTP až po ne příliš standardní protokoly, jakým je například quake-halflife). Z changelogu jsem poznal, že se projekt neustále vyvíjí a navíc mě utěšovala možnost dopsat si vlastní blokovací řetězec pro protokol, který by mi v budoucnu chyběl. Blokování programů KaZaA a DC++ až na malé detaily fungovalo tak, jak se sluší a patří. Jediné, co mě zamrzelo, byl zvýšený load serveru, a tak jsem se rozhodl do třetice všeho dobrého ještě vyzkoušet IPP2P.
KaZaA je momentálně jeden z nejpoužívanějších peer-to-peer klientů využívající sítě FastTrack. Slouží převážně k výměně hudebních souborů a videonahrávek přes síť internet. Oficiální klient je sponzorován obsaženou reklamou, mallwarem a spywarem navzdory hlášce "No Spyware" na jejich domovské stránce.
Stáhl jsem si z domovské stránky projektu poslední (ne)stabilní verzi a pročetl manuál. U IPP2P jsem měl na výběr dvě možnosti kompilace. Buďto použít sadu patchů z balíku Patch-O-Matic. Nebo vše bez patchů ručně zkompilovat. Vydal jsem se druhou cestou. Bylo třeba získat zdrojové kódy pro aktuální verzi iptables a kernelu. Jádro jsem zvolil z řady 2.6. Důvodem této volby byl modul CONNMARK (potřebný pro plnou funkčnost IPP2P). Na kernelech z 2.4 řady byl problém s jeho kompilací, kdežto u kernelů řady 2.6 se jedná pouze o malý patch. V kernelu 2.6.10 a vyšším je pak již modul CONNMARK přímo obsažen.
Kompilace jádra probíhala standardně. Použil jsem konfigurační soubor předešlého kernelu, který byl ve stejné verzi a tím pádem pouze stačilo pozměnit položku CONFIG_IP_NF_TARGET_CONNMARK na CONFIG_IP_NF_TARGET_CONNMARK=m a poté jádro zkompilovat. Následně jsem zkompiloval iptables a restartoval testovací router. Posledním krokem byla kompilace samotného modulu IPP2P. Ta je velmi přímočará - stačí v rozbaleném adresáři se zdrojovými kódy zadat obligátní příkaz make. Po pár vteřinách se vygenerují dva soubory. První z nich je libipt_ipp2p.so, který nakopírujeme do adresáře knihoven iptables - v mém případě /usr/lib/iptables. Druhým souborem je pak ipt_ipp2p.ko, který nakopírujeme do adresáře netfilteru - v mém případě /lib/modules/2.6.15/kernel/net/ipv4/netfilter. Jakmile máme nakopírováno, vygenerujeme novou mapu závislostí příkazem depmod -a a nahrajeme modul do jádra příkazem modprobe ipt_ipp2. Pokud je vše v pořádku, měla by se nám po zadání příkazu iptables -m ipp2p -h vylistovat stručná nápověda. IPP2P na rozdíl od L7-filter podporuje pouze omezování P2P sítí, které je ovšem na druhou stranu daleko propracovanější než u výše zmíněných programů. Podporovány jsou následující protokoly:
- eDonkey/eMule/Overnet na protokolech TCP i UDP
- Direct Connect na protokolu TCP
- KaZaA na protokolech TCP i UDP
- Gnutella na protokolech TCP i UDP
- BitTorrent na protokolech TCP i UDP
- AppleJuice na protokolu TCP
- WinMX na protokolu TCP
- SoulSeek na protokolu TCP
- Ares na protokolu TCP
Experimentálně (ve verzi 8.1) pak:
- Mute na protokolu TCP
- Waste na protokolu TCP
Jak je vidět, podpora P2P sítí je celkem široká. Samotná integrace IPP2P na router navíc nebude dělat problémy nikomu, kdo již má zkušenosti s konfigurací samotných iptables. Základní příkaz do firewallu by pak mohl vypadat asi nějak takto:
iptables -A FORWARD -p tcp -m ipp2p --kazaa -j DROP
Tímto příkazem zahodíme všechny pakety, které putují přes náš server na vrstvě TCP a jsou generovány programem KaZaA. Ne vždy je však nutno všechny pakety přímo blokovat - jsou případy, kdy P2P sítě potřebujeme pouze označkovat, vyhradit jim určitou šířku pásma, nastavit jim TOS flagy a podobně. Nový příkaz (například pro označkování paketů) by pak vypadal následovně:
ToS znamená anglickou zkratku "Type of Service" neboli typ služby. ToS je včleněn do hlavičky IPv4 paketů a používá se obvykle při prioritizaci jednotlivých spojení. Mezi pět nejznámějších ToS flagů patří: minimize delay (minimální zpoždění), maximize throughput (maximální propustnost), maximize reliability (maximální spolehlivost), minimize monetary cost (minimální cena) a normal service (standardní služba).
iptables -A PREROUTING -p tcp -m ipp2p --kazaa -j MARK --set-mark 10
Tento typ značkování je samozřejmě za podmínky správného umístění ve firewallu plně funkční, má ovšem jednu obrovskou nevýhodu. Pokud byste řekněme v době od 23:00 do 7:00 měli pro značku 0xa ve firewallu pravidlo
iptables -A PREROUTING -p tcp -m mark --mark 10 -j ACCEPT
a ráno v 7:00 ho změnili na
iptables -I PREROUTING -p tcp -m mark --mark 10 -j DROP
byli byste pravděpodobně asi zklamaní. Stahovačům se již sice nepodaří otevřít nová spojení, ovšem ta spojení, která jsou již navázaná, budou fungovat i nadále. Na grafech pak v lepším případě uvidíte velmi pozvolné snižování trafficu, namísto jeho totálního "utnutí".
O funkčnosti takového filtru vás možná přesvědčí graf průtoku dat na jednom z routerů ve firemní síti. Úmyslně jsem toto blokovací pravidlo zapnul chvíli před osmou hodinou. Postupně pak na grafu můžete sledovat snižování uploadu přibližně až do druhé hodiny ranní, kdy již není žádná P2P sít funkční a všechna spojení jsou zablokovaná.
Když jsem s omezováním P2P sítí začínal, nepřikládal jsem tomu "efektu" přílišnou váhu a spíše jsem si říkal, že je to vlastně výhoda, neboť jednotlivým klientům stahování neskončí například v 95 %, aby pak museli zbytečně čekat na další den. Slovy klasika to mohu shrnout větou "šedivá je teorie, zelený strom praxe…" Uživatelé na tuto "výhodu" během několika málo dní přišli, a místo aby zapínali své "sčoty" na noc, vždy si jen o půl hodinky přivstali a spustili stahování, které jim v ideálním případě vydrželo přes celý den až do večera, kdy byly P2P sítě opět povoleny.
Proti této nectnosti se však lze úspěšně bránit použitím zmíněného modulu CONNMARK. Ten funguje na principu jakéhosi sledování paketů. Označí si první paket, který obsahuje řetězec KaZaA, ale sleduje i ostatní pakety, které na něj navazují. Za použití CONNMARKu pak můžeme utnout okamžitě veškerý P2P traffic, a to v kteroukoliv chvíli se nám zamane. Příkazy iptables pro označení všech protokolů IPP2P na protokolu TCP by byly následující:
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK -restore-mark iptables -t mangle -A PREROUTING -p tcp -m mark ! --mark 0 -j ACCEPT iptables -t mangle -A PREROUTING -p tcp -m ipp2p --edk -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --dc -j MARK --set-mark 0x2 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --kazaa -j MARK --set-mark 0x3 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --gnu -j MARK --set-mark 0x4 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --bit -j MARK --set-mark 0x5 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --apple -j MARK --set-mark 0x6 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --winmx -j MARK --set-mark 0x7 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --soul -j MARK --set-mark 0x8 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --ares -j MARK --set-mark 0x9 iptables -t mangle -A PREROUTING -p tcp -m ipp2p --mute -j MARK --set-mark 0xa iptables -t mangle -A PREROUTING -p tcp -m ipp2p --waste -j MARK --set-mark 0xb iptables -t mangle -A PREROUTING -p tcp -m ipp2p --xdcc -j MARK --set-mark 0xc iptables -t mangle -A PREROUTING -p tcp -j CONNMARK -save-mark
Ti bystřejší z vás si jistě všimli, že markujeme všechny známé protokoly, ovšem pouze na vrstvě TCP. Autor filtru IPP2P totiž na domovských stránkách důrazně doporučuje umístit markování paketů na UDP vrstvě samostatně (klidně i se stejnou značkou) až za modul CONNMARK.
V této chvíli máme tedy P2P pakety označkovány a záleží jen na nás, jak s nimi naložíme - můžeme je trvale vypnout, povolit pouze v určitou denní dobu za použití CRONu (nebo například modulu time do iptables), případně je také omezit na šířce pásma.
Uveďme si proto malý příklad. Řekněme, že bychom měli linku o rychlosti 1536 kbit a chtěli bychom v ní omezit veškerý provoz sítě KaZaA na pásmo o šířce maximálně 64 kbit při zatížené síti a na 128 kbit při síti nezatížené. Sekvence příkazů by pak vypadala přibližně následovně:
iptables -t mangle -A PREROUTING -j CONNMARK -restore-mark iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT iptables -t mangle -A PREROUTING -m ipp2p --kazaa -j MARK --set-mark 0xa iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark tc qdisc add dev eth1 root handle 1:0 htb default 2 tc class add dev eth1 parent 1:0 classid 1:1 htb rate 1536kbit tc class add dev eth1 parent 1:1 classid 1:2 htb rate 1536kbit tc class add dev eth1 parent 1:1 classid 1:3 htb rate 64kbit ceil 128kbit tc filter add dev eth1 parent 1:0 protocol ip prio 2 handle 10 fw classid 1:3
Považuji za ideální spojit tyto dva uvedené příklady dohromady. Dostanete tak mocnou zbraň, která vám dává možnost omezit "sosače" v přesně stanovenou dobu na přesně stanovenou rychlost. Krásnou ukázkou může být opět graf průtoku části naší sítě, kde jsou P2P povoleny pouze v době od 23:00 do 7:00 ráno.
Na naší síti není žádoucí filtrovat jiné protokoly než ty, které jsou používány P2P programy, a proto jsem se rozhodl právě pro IPP2P. Po dlouhodobém používání tohoto filtru mohu říct, že jsem v souvislosti s ním nikdy nepozoroval žádné problémy. Pro někoho bude spíš výhodný layer7 filtr, který, co se týče blokování P2P sítí, nedosahuje takových kvalit, ale má zase jiné výhody. U svých kolegů jsem viděl i kombinaci obou programů. Instalaci iptables-p2p bych však již nikomu nedoporučoval.