Kdo to tady organizuje?
Ve většině protokolů je přenosová session organizována serverem. Server určuje, co se kdy a jak bude dít. V FSP tomu tak není. Přenos souborů pomocí FSP je kompletně organizován klientem. Je na klientu, jak si bude v přenášeném souboru seekovat a jakou strategii zvolí při resendování ztracených packetů. FSP Server je opravdu jen sluha, který slouží klientovi. Klient nemá nad severem absolutní moc – je omezen základním pravidem: „Minimální čas pro přeposlání ztraceného packetu serverem jsou tři sekundy.“
FSP vs. TCP
Základní rozdíl mezi protokoly TCP a FSP je ten, že FSP nepoužívá techniku přenosového okna. Přenos souborů je tak mnohem jednodušší na implementaci a na sofistikované optimalizační algoritmy známé z rodiny TCP je možné zapomenout, protože stejně nejdou v prostředí FSP implementovat.
Optimalizační algoritmy TCP se dají shrnout do dvou základních bodů:
- nepřecpávat již zacpanou síť
- co nejvíce zacpat^H^H^H^H^H^Hvyužít nezacpanou síť
Přeposílání packetů v FSP
U FSP je implementace těchto algoritmů mnohem jednodušší. Bod č. 1 je podobně jako u TCP řešen exponenciálním nárůstem času pro resend. Většina současných FSP stacků čeká na prvotní odezvu serveru 1.34 sec, pak přeposle packet a čas znásobí koeficientem 1.5. Celá akce se opakuje až do doby obdržení odpovědi nebo do timeoutu. Horní čas mezi jednotlivými resendy je omezen na 60 sekund. Na rozdíl od rodiny TCP se po každém round tripu prvotní čas nastaví opět na původních 1.34 s.
Při implementaci tohoto časování se předpoklá, že round trip time mezi jednotlivými počítači nepřesahuje 1.34 s, což splňuje naprostá většina současných sítí. Pokud bychom předpokládali využití FSP i na ostatních sítích, musíme upravit algoritmus tak, aby využíval možnosti počítání RTT ze značek v packetech.
Jelikož máme v drátech vždy jen jeden packet, což je minimální jednotka, kterou je možné odeslat, nemusíme si dělat starosti s možným ucpáním sítě. Jedním packetem to prostě nejde.
Implementace optimalizací bodu 2 je v FSP řešena jediným možným způsobem: Po obdržení odpovědi od serveru pošleme bez čekání žádost o další data. Výhoda této strategie spočívá v tom, že po profouknutí ucpané sítě vyletí přenosovka FSP ihned na nejvyšší možnou rychlost, zatímco TCP ji zvyšuje postupně podle pravidla rychlá brzda, pomalý start.
Sněhové koule
Další z komentářů se zmiňoval o sněhových koulích. Ty vznikají takto: Mějme dva počítače spojené modemem a nekvalitní linkou. Přenášíme soubor a modemy začnou retrainovat, což trvá i několik desítek sekund. Klient odeslal několik žádostí o přeposlání packetu a tyto žádosti skončily ve vstupním bufferu modemu. Po obnovení spojení se všechny tyto žádosti odešlou na server, kam dorazí s nulovými rozestupy. Server zpracuje tyto žádosti a odešle do linky mnoho kopií dat, které způsobí zbytečné zahlcení linky.
U FSP sněhové koule nenastávají, neboť server nepřepošle packet dříve než po třech sekundách. Zpracuje se tak pouze první žádost z nárazové dávky a zbytek se zahodí.
Bezpečnost přenosového protokolu
Scénář č. 1 – útočník se dostane mezi server a klienta
V tomto případě je bezpečnost protokolu stejná jako u plain TCP, tedy nulová. Klientu lze podstrčit libovolná data a on to nepozná. Tento útok zvaný man in the middle je velmi snadný – existuje několik knihoven jak do C, tak do Perlu, které vám při jeho konstrukci pomohou. Pro zabezpečení je nutné použít hračky jako OpenSSL apod nebo alespoň samostatné digitální signatury.
Scénář č. 2 – blind data send
Při tomto útoku posílá útočník předem připravená data na adresu klienta a doufá, že je klient přijme místo dat zasílaných serverem. V dřívějších verzích FSP si klient přijímané packety moc podrobně neprohlížel. Jediné, na čem mu záleželo, bylo správné číslo sekvence. Útočníkovi tedy stačilo uhodnout číslo zdrojového portu a číslo sekvence. Zdrojové porty bývají ve většině TCP implementací stále ještě přiřazovány popořadě a sekvence často začínaly nulou a postupně se zvětšovaly. Ideální pro útok.
Úspěšnost tohoto útoku jsem snížil v poslední verzi FSP stacků, kde jsem implementoval následující:
- čísla sekvence jsou volena náhodně (16 bit)
- testujeme, zda server odpovídá na odesílaný příkaz (8 bit)
- testujeme, zda pozice v souboru odpovídá námi očekávané (32 bit)
Když k tomuto připočteme ještě nutnost uhodnutí source portu klienta (16 bit), měla by být síťová bezpečnost pro běžné použití dostatečná.
Scénář č. 3 – denial of service na server
FSP bylo odjakživa vyvíjeno s ohledem na bezpečnost serveru, a tudíž je fsp daemon velmi odolný proti těmto lumpárnám. Sejmout fspd packet floodem je mnohem obtížnější než sejmout ftpd syn floodingem.
Scénář č. 4 – denial of service na klienta
Jediný v současné době funkční útok. Jeho funkčnost zapříčinila napsání tohoto dílu. Pro uspěšné provedení jsou potřeba tyto údaje: známe IP klienta a IP serveru a umíme posílat packety s podvrženou adresou odesilatele.
Vygenerujeme si jeden libovolný korektní FSP packet s libovolným klíčem a cyklicky ho posíláme na server s podvrženou IP adresou klienta. Jelikož session timeout v FSP protokolu činí 60 sekund, stačí tento packet posílat po 50 sekundách. FSP server bude podle použitého klíče pokládat packet za korektní opakování žádosti o přeposlání dat a po jeho obdržení vynuluje session timeout.
Tato aktivita znemožní opravdovému klientu přístup k serveru, protože session bude udržována na serveru jako aktivní a klient nebude znát platný klíč. Pokud bude session mezi opravdovým klientem a serverem aktivní (např. download .ISO image), nelze se do ní tímto útokem nabourat.
Úhybné manévry
Možná řešení, náměty do diskuze
- Obnovovat session timeout pouze po obdržení packetu s novým klíčem, nikoliv při resendu. Nejsem si zcela jist, zda by toto řešení nemělo nějaký vedlejší efekt. V některých případech musí server vědět, zda se jedná o resendovaný packet, či nikoliv, a tímto opatřením by se snížila úspěšnost této detekce. Některé příkazy, např. MKDIR, jsou totiž v resendovaných packetech ignorovány, protože byly již vykonány v době odeslání původního packetu.
- Na straně serveru je tento útok detekovatelný. IP adresa vykazuje pouze resendy. Není mi zcela jasné, jak odlišit falešné resendy od opravdových, abychom je mohli ignorovat.
- Jelikož odpověď serveru dorazí ke skutečnému klientu, lze probírat všechny dorazivší UDP packety, a pokud narazíme na FSP packet, tak z něj vytáhnout platný klíč a ten pak použít. Naneštěstí uid 0 je nutné.
HTTP over FSP
Jedním z poměrně častých přání je, aby se našel někdo, kdo nakóduje balení HTTP do FSP rámců. Umožnilo by to použití HTTP i na silně zalagovaných sítích, kde TCP protokol nemá šanci.
Nejlepší implementace by spočívala v nakódování proxy serveru, který by měl na jednom konci HTTP a na druhém FSP. Proxy server by musel běžet na obou stranách, pochopitelně s obráceným vstupem/výstupem. Případní zájemci nechť se přihlásí vmailing listu FSP, dostanou práva do CVS.