Disassembler

Artificial intelligence is no match for natural stupidity.
12červenec2017

Torrent a Tor – Boj s větrnými mlýny


V minulém článku jsem zmiňoval, že jsem dostal za úkol dezinfikovat jednu hotelovou síť, což jsem provedl lehkým zafiltrováním, sběrem statistik provozu a následným zablokováním klientů prokazatelně napadených malwarem. Také jsem poznamenal, že jsem na oné síti potkal torrentové stahovače a rozhodl se jim trochu znepříjemnit život. Hned v perexu nicméně zdůrazním, že na veřejných sítích, kde je zprostředkování konektivity primárním předmětem dohody, rozhodně neschvaluji jakékoliv blokování, unášení nebo přesměrovávání provozu, není-li to jasně zmíněno v podmínkách užívání takové služby. Pokud však máte domácí nebo firemní síť s nějakým hotspotem, tak tam si filtrujte, co chcete. V následujícím článku se budu věnovat hlavně Torrentům a k Toru dojdu až obloukem.

Hruška hrušce


TL;DR: BitTorrent ani Tor se z principu nedají se 100% úspěšností omezit.

Princip P2P (Peer-to-peer) sítí tkví v tom, že neexistuje žádný centrální bod, skrze který by protékal provoz nebo který by jako jediný identifikoval všechny uzly sítě. Na rozdíl od architektury klient-server tedy komunikují přímo jednotliví klienti mezi sebou a spolu s vlastními užitečnými daty si předávají i informace o dalších klientech a jiných uzlech v síti. V případě, že je taková síť šifrovaná a používá buď náhodné porty, nebo se naopak maskuje za „neblokovatelný“ provoz jako třeba HTTPS, není prakticky možné se stoprocentní jistotou říci, o jaká data se jedná a tím pádem není ani možné takový provoz úspěšně selektivě blokovat. Tor ani Torrent ale naštěstí (resp. naneštěstí pro stahovače) nejsou až tak úplně hardcore P2P a oba potřebují nakopnout (bootstrap), aby vůbec věděli, kam se mají napoprvé připojit. Když se jim připojení k první hrstce peerů podaří, ti jim předají informace o dalších, ti o dalších, a tak dále, až se před nimi rozvine celá síť, čítající třeba několik desítek tisíc uzlů. Je tedy možno do jisté míry identifikovat a blokovat tento bootstrap, ale opět to celé stojí a padá na tom, jak chytrý klient je. Pokud se totiž k P2P síti připojí jinde, stáhne si data o peerech a pak přejde na síť blokující bootstrap, bude se schopen připojit stejně, protože informace o dalších uzlech už bude mít a další nakopnutí už nebude k životu nutně potřebovat. Torrent má několik způsobů nakopávání, z nichž některé se použijí při každém novém stahování, takže ty se dají blokovat celkem obstojně. Tor pak nakopává pouze při prvním spuštění klienta a pokud při následujícím zpuštění nemůže načíst čerstvá data, použije ta, která načetl posledně. U Toru jsou si sice všechny uzly rovny, ale některé jsou si rovnější. O tom ale později.

Tunely a tuneláři


Prvním krokem k blokování torrentů s torrenty samotnými vlastně vůbec nesouvisí. Výchozí instalace Windows od dob sedmiček obsahuje Teredo klienta. Teredo je jedním ze způsobů zprostředkování IPv6 konektivity v IPv4 sítích. Výhoda tohoto řešení je, že IPv6 pakety balí do IPv4 datagramů, takže si umí poradit s NAT bez nutnosti dalšího nastavování port forwardingu. To ale pro omezení lačného administrátora sítě znamená, že uživatelé mají přístup k tunelovací technologii, kterou je možno pro torrentění celkem obstojně využít. Naštěstí Teredo navazuje spojení na předem známý vzdálený port 3544/UDP, který se ve firewallu prostě zařízne. Tunelu prostá instalace by pak měla při zjištění stavu zafňukat něco takového:

C:\Windows\system32> netsh interface teredo show state
Teredo Parameters
---------------------------------------------
Type                    : client
Server Name             : win10.ipv6.microsoft.com.
Client Refresh Interval : 30 seconds
Client Port             : unspecified
State                   : offline
Error                   : primary teredo server unreachable over UDP

A abych nebyl nenadržoval jen jedné straně, prozradím potenciálnímu red teamu, že pokud Teredo nefunguje jak má, dá se pošťouchnout příkazem

netsh interface teredo set state type=enterpriseclient

Plně funkční Teredo při dotazu na stav hlásí zhruba následující:

C:\Windows\system32> netsh interface teredo show state
Teredo Parameters
---------------------------------------------
Type                    : enterpriseclient
Server Name             : win10.ipv6.microsoft.com.
Client Refresh Interval : 30 seconds
Client Port             : unspecified
State                   : qualified
Client Type             : teredo client
Network                 : unmanaged
NAT                     : restricted (port)
NAT Special Behaviour   : UPNP: No, PortPreserving: Yes
Local Mapping           : 192.168.2.205:60143
External NAT Mapping    : 12.34.56.78:60143

BitTorrent


Tím jsme se zbavili tunelovací služby, která je (alespoň na Windows) dostupná bez jakéhokoliv úsilí. Dál už je potřeba vědět, jak takový torrent vlastně funguje. Nutno podotknout, že BitTorrent je původně protokol fungující nad TCP, ale postupem času byl v rámci boje s odhalováním a blokováním komplet celý transformován do protokolů založených na UDP a s původním protokolem má společný akorát účel. V první řadě je celkem důležité, že ve chvíli, kdy uživatel stáhne první kousek (chunk) souboru, může ho již sdílet dalšímu vrstevníkovi. Torrenty samotné se v síti identifikují nejčastěji podle BTIH (BitTorrent Info Hash) taktéž nazývaný prostě info hash, což je prachsprostý SHA-1 hash informačních sekcí obsažených v BitTorrentovém metasouboru, určujícím jednotlivé dílčí soubory obsažené v torrentu. A jak se vlastně jednotliví peeři hledají? V případě BitTorrentu existuje několik různých více či méně důmyslných systémů výměny metadat.

Většina torrentových klientů využívá kombinaci výše uvedených systémů výměny informací. Testoval jsem klienty BitComet, BitLord, Deluge, qBitTorrent, Shareaza, Tixati, Transmission, Tribler, μTorrent, Vuze/Azureus a samozřejmě i oficiální BitTorrent klient, což by podle různých průzkumů oblíbenosti mělo obsáhnout 99% používaných klientů. U některých jsem se potkal ještě s pár dalšími špeky. Tak třeba BitComet v současnosti pro dodatečnou výměnu informací o uzlech používá protokol P2SP, který funguje přes HTTPS. Stejně jako v ostatních případech je jej potřeba nakopnout, takže blokování IP adres bootstrap serverů to jistí. Tribler je zase velice zajímavý tím, že operuje nad vlastní šifrovanou distribuovanou databází Dispersy a uniká tak systémům hlídajícím DHT. Opět ale potřebuje bootstrap servery, které jsou vypsané přímo ve zdrojovém kódu. Nejzajímavějším a nejvíce se bránícím klientem je pak Vuze/Azureus. Nejen, že má vlastní PEX protokol. Nejen že má vlastní DHT bootstrap servery. Ale ještě navíc umí automaticky použít Tor síť. A protože se jedná o relativně hojně používaného klienta, právě toto je důvodem mé potřeby blokovat společně s BitTorrentem i Tor. Mimochodem, stahování torrentů přes Tor je silně nedoporučováno i přímo na blogu Tor projektu protože se na něj váže spousta problémů nejen s (de)anonymizací.

MikroTik, na kterém jsem celou anabázi absolvoval sice nějaký vestavěný p2p filtr má, ale vzhledem ke stáří zbytku systému se obávám, že rozeznává leda tak protokoly, které existovaly na konci devadesátých let. BitTorrent jím prošel jako horký nůž máslem. V repozitáři L7 filtru, který MikroTik také podporuje, existuje regulární výraz pro blokování torrentového provozu. Ve světle výše uvedených faktů je ale také neúčinný. Navíc jim v něm chybí jedno svislítko. Sestavil jsem si tedy svůj vlastní regulární výraz (with blackjack and hookers). Respektive dva. Jeden pro TCP a druhý pro UDP. Pokud by se někomu nezdál onen regulární výraz pro UDP, vězte, že L7-filter přeskakuje null bajty, protože používá engine, ve kterém null byte značí konec regulárního výrazu. Opět zdůrazňuji, že se jedná o naivní blokování, takže pokud si někdo donese vlastní DHT nebo PEX nebo přijde s úplně jiným systémem distribuce, která je třeba ještě navíc šifrovaná, nepomůže ani svěcená voda.

Tohle vyřeší standardní záležitosti, jako HTTP a UDP announce a DHT. DHT routery se pak šmahem zaříznou blokováním portu 6881/UDP a různé „proprietární“ PEX protokoly a distribuované databáze pak zacpu IP blacklistem, který je na P2P síť až pozoruhodně krátký. V řeči RouterOSu tedy bude skript pro blokování torrentů vypadat následovně.

/ip firewall layer7-protocol
add name=torrent-tcp regexp="^(\\x13BitTorrent protocol|GET /announce\\\?info_hash=)"
add name=torrent-udp regexp="^(\\x04\\x17\\x27\\x10\\x19\\x80|d1:ad2:id20:)"

/ip firewall address-list
add address=dht.vuze.com list=Torrent
add address=inside.bitcomet.com list=Torrent
add address=dispersy1.tribler.org list=Torrent
add address=dispersy2.tribler.org list=Torrent
add address=dispersy3.tribler.org list=Torrent
add address=dispersy4.tribler.org list=Torrent
add address=dispersy5.tribler.org list=Torrent
add address=dispersy6.tribler.org list=Torrent
add address=dispersy7.tribler.org list=Torrent
add address=dispersy8.tribler.org list=Torrent

/ip firewall filter
add action=jump chain=forward comment="Jump to OUT-Torrent" jump-target="OUT-Torrent" out-interface=ether1-WAN
add action=drop chain="OUT-Torrent" comment="Bootstrap hosts" dst-address-list=Torrent
add action=drop chain="OUT-Torrent" comment="Teredo" dst-port=3544 protocol=udp
add action=drop chain="OUT-Torrent" comment="DHT Routers" dst-port=6881 protocol=udp
add action=drop chain="OUT-Torrent" comment="L7 UDP" layer7-protocol=torrent-udp protocol=udp
add action=drop chain="OUT-Torrent" comment="L7 TCP" layer7-protocol=torrent-tcp protocol=tcp
add action=return chain="OUT-Torrent"

Tor


The Onion Router. Decentralizovaná, anonymizovaná síť, v níž je komunikace zabezpečená několika vrstvami TLS. Právě princip vrstvení této síti propůjčil jméno. V síti Tor mohou uzly plnit několik funkcí. Základní stupeň anonymity navazuje připojení přes tři uzly. První (vstupní) uzel se označuje jako guard node. S jeho pomocí se Tor klient dostane dovnitř. Uvnitř sítě si jej pak mezi sebou předávají relay node a zpět do internetu vyleze skrze exit node. Cestička mezi těmito uzly, tedy klient -> guard node -> relay node -> exit node -> internet se nazývá okruh (circuit) a je sestavena ještě předtím, než klient vůbec pošle nějaká užitečná data. Pro každný nový cílový bod v internetu se navíc sestavuje i nový okruh, takže na různé weby klient přistupuje z pokaždé jiných exit nodů. Klient při sestavení postupně dostává veřejné klíče od všech uzlů po cestě a data všemi klíči zašifruje. Jednotlivé uzly jsou pak schopny rozšifrovat pouze svou „slupku“ svým soukromým klíčem a zjistit, kam mají data poslat dále, aniž by viděly skutečný obsah dat nebo jejich zdroj a cíl zároveň. Jediný exit node se pak může dostat k surovým datům, takže pro zachování úplného soukromí je důležité i přes Tor síť navštěvovat stránky pouze skrze HTTPS nebo používat služby které implementují TLS. To je také jeden z důvodů, proč se přes Tor nedoporučuje provozovat Torrent.

Kromě guard, relay a exit rolí mohou ještě jednotlivé uzly poskytovat adresářové služby a bonzovat tak adresy dalších uzlů, což se tak nějak v P2P síti očekává. K tomu, aby Tor klient věděl, kam se má vůbec připojit, slouží takzvaný network consensus, což je dokument dynamicky vytvářený všemi členy Tor sítě obsahující adresy většiny uzlů. A tady se právě dostávám k tomu, že všechny uzly jsou si rovny, ale některé jsou si rovnější. V současné chvíli existuje devět Tor uzlů, které jsou vedeny jako autoritativní adresářové servery. To znamená, že jejich data jsou svatá a co řeknou, to platí. Tyto servery jsou opět natvrdo zakódovány přímo ve zdrojovém kódu Tor klienta. Mimo ně zdrojový kód také uvádí 151 pokémonů fallback serverů, na které se Tor klient může připojit, pokud z nějakého důvodu nedosáhne na oněch devět vyvolených. Jedna ze strategií tedy pomalu začíná být jasná. Podobně jako v případě bootstrap serverů u Torrentů se dá blokovat těchto 160 Tor uzlů. Mějte však na paměti, že seznam uzlů se v čase mění a klientovi stačí znát jedinou neblokovanou adresu vstupního uzlu k tomu, aby stáhl síťový konsensus a dozvěděl se o adresách všech ostatních uzlů. Stejně tak má uživatel možnost Tor klientu adresu adresářového serveru vnutit. Navíc různé verze a různé implementace Tor klientů mohou využívat různé sady fallback serverů, takže tato strategie rozhodně nemusí být stoprocentní. Zdá se ale, že na blokování Tor provozu torrentového klienta Vuze to stačí.

Na chvilku teď odbočím. Je nad slunce jasné, že Tor je vstupenkou do dark webu a dají se skrze něj páchat a prohlížet různá zvěrstva. Jelikož provozuji technický blog, nechci zabřednout do nějakých morálních a politických otázek, nicméně jsem si jist, že pokud někdo chce skutečně škodit, cestu si vždycky najde i pokud nebude moci použít Tor. Na druhou stranu může být Tor využit i různými aktivisty, disidenty nebo novináři v zemích s různými autoritativními režimy a pomoci dostat na světlo informace, u kterých by to jinak nebylo možné, takže jeho blokování je na zvážení každého z vás. Síť Tor se dá blokovat ze dvou stran. Častější varianta je, že nechcete, aby se do vaší sítě z Toru dalo připojit, a v takovém případě budete blokovat exit nody. Ty do jisté míry blokuje například Wikipedie protože se z nich nedají upravovat encyklopedická hesla. Já ale řeším blokování Torrentů a zbytek je mi celkem volný, takže bych zařízl naopak pouze guard nody. Píšu „pouze“, ale z nějakých 7100 uzlů zapsaných v síťovém konsensu jich je vstupních skoro 2500, takže blacklist nebude žádný drobeček. K síťovému konsensu se můžu dostat buď tak, že si nainstaluju Tor klienta (což může být klidně i malá pythonovská knihovna) a adresy z něj budu tahat přímo, anebo zneužiju dobroty cizích a adresy budu tahat z webových služeb zprostředkujících informace o Tor síti. Jednou takovou službou je třeba https://torstatus.blutmagie.de/, která nabízí seznam uzlů ke stažení v CSV formátu. Proženu jej tedy společně s výše zmíněnými soubory zdrojového kódu shell skriptíkem a vyrobím další skript pro RouterOS, podobný tomu, kterým řeším malwarové blacklisty v minulém článku.

#!/bin/bash

RSCFILE=/var/www/html/tor.rsc
TMPDIR=$(mktemp -d)

echo -e "/ip firewall address-list\nremove [find list=Tor-Dir]\nremove [find list=Tor-Guard]\nremove [find list=Tor-Exit]" >${RSCFILE}

wget -q https://gitweb.torproject.org/tor.git/plain/src/or/fallback_dirs.inc -O ${TMPDIR}/tor.dir
wget -q https://gitweb.torproject.org/tor.git/plain/src/or/config.c -O - | sed '/^static const char \*default_authorities/,/^};$/!d;//d' >>${TMPDIR}/tor.dir
grep -Po '(\d+\.){3}\d+' ${TMPDIR}/tor.dir | sort -u | sed 's/^/add list=Tor-Dir address=/' >>${RSCFILE}

wget -q https://torstatus.blutmagie.de/query_export.php -O ${TMPDIR}/tor.csv
awk -F, '$12 == 1 {print "add list=Tor-Guard address="$5}' ${TMPDIR}/tor.csv | sort -u >>${RSCFILE}
awk -F, '$10 == 1 {print "add list=Tor-Exit address="$5}' ${TMPDIR}/tor.csv | sort -u >>${RSCFILE}

rm -rf ${TMPDIR}

Chcete-li onu písmenkovou polívku vysvětlit, pak první wget stahuje kompletní soubor fallback_dirs.inc, druhý wget stáhne config.c a hned jej prožene přes sed, který vyzobne pouze tělo mezi řádky static const char *default_authorities a nejbližší následující ukončovací množinovou závorkou a přilepí k obsahu s fallback záznamy. Následující grep z této směsky vyloví všechny IPv4 adresy a sort a další sed vyrobí úhledný seznam pro RouterOS. Třetí wget pak stáhne CSV s adresami a funkcemi uzlů a následující dva řádky s awk z něj vyzobou IP adresy (5. sloupec) guard (12. sloupec) a exit (10. sloupec) uzlů. Skript pak opět vrznete o cronu a je to. Vzhledem k relativně línému tempu propagace změn v Tor síti nemá smysl jej spouštět častěji než jednou za půl hodiny. Část pro MikroTik je pak myslím celkem jasná.

/ip firewall filter
add action=drop chain=input comment="Block Tor exit nodes" dst-address-list=Tor-Exit
add action=jump chain=forward comment="Jump to OUT-Tor rules" in-interface=bridge1-local jump-target=OUT-Tor out-interface=ether1-WAN
add action=drop chain=OUT-Tor comment="Block Tor directory nodes" dst-address-list=Tor-Dir
add action=drop chain=OUT-Tor comment="Block Tor guard nodes" dst-address-list=Tor-Guard
add action=return chain=OUT-Tor comment="Return from OUT-Tor rules"

Jeden typ Tor uzlu jsem vynechal. Psal jsem, že síťový konsensus obsahuje adresy většiny uzlů. Neobsahuje však bridge nody. Bridge jsou utajené uzly, přes které se dá dostat do sítě Tor, ale protože neexistuje žádný jejich veřejný seznam, nedají se blokovat stejným způsobem jako ostatní uzly. Na druhou stranu jejich použití vyžaduje manuální konfiguraci. A protože mým záměrem bylo blokovat Torrenty a k Toru jsem se dostal pouze vinou Vuze, které využívá konfiguraci automatickou, nějaké bridge mě vůbec netrápí a v klidu je nechám žít.

Úplně nakonec už jen zmíním, že výše uvedené snippety ještě s hromádkou dalších skriptů pro MikroTik se dají nalézt i u mě na GitHubu.