To ale neřeší ten největší průšvih - že ten standard psal nějaký blackhat.
Ten průšvih je v tom, že si díky ušetřenýmu handshake můžu říct http3 serverům tvým jménem o doručení souborů na tvou IP adresu. A ty to tam prostě nastřílí. Pokud žádost bude 1kB, mám s 5MB souborem multiplikační efekt cca 5000x. Pokud najdu nějaký 5GB image instalaček, mám zesílemí 5E6x. Pro DDoS jak dělaný.
S http2 přitom odejde jenom hlavička, kterou oběť nechtěla (pár bytů) a je po všem. Bez aktivní spolupráce příjemce se přenos nekoná.
Takže jestli chtějí zrychlit navazování komunikace, tak ať místo DV certifikátu dovolí soukromý klíč v DNS + IPSEC + HTTP. Pak se nemusí ověřovat revokace klíče a ušetří tím čas i energii. Pro ostatní certifikáty je holt zpomalení daň za bezpečnost. A mimo rychlejšího navazování komunikace v tomhle případě UDP spíš škodí.
Slyšel jsi někdy o "DNS Amplification"? Pokud tam nebude nějaký extra neprůstřelný mechanismus na ochranu, tohle je nemlich to samý. S jediným rozdílem, místo párkilové DNS odpovědi ti to klidně nableje pár mega v souboru ani nemrkneš. Z jednoho paketu jich udělat (deseti)tisíce, to je sen každýho obchodníka, který nabízí "DDoS as a service".
A i s tím mechanismem, pokud se najde chyba, bude výsledek hodně zajímavý.
Důvod přechodu na UDP je totiž jediný - nezdržovat se dohadováním ohledně spojení a parametrů, server ví jenom co, na jakou IP adresu a jaký port vychrlit. Pokud je to něco větší než dotaz a současně se dá pokyn k odeslání podvrhnout, bude to zneužito k zesílení DDoSu. Nehledě na to, že pokud někdo bude server k zesilování používat opakovaně, odstřihnou od netu "čerti" i ten legitimní web server - další vektor útoku na službu.
Extra neprůstřelným mechanismem myslíte třeba potvrzování přijatých paketů, něco na způsob, jako používá TCP? Pořád se tváříte, jako kdyby QUIC neměl zaručovat přijetí všech paketů a ve správném pořadí na úrovni aplikačního protokolu – jenže bez toho by HTTP nefungovalo. Jenže ve skutečnosti QUIC zajišťuje spojení, stejně jako TCP, takže samozřejmě zaručuje doručení všech paketů a ve správném pořadí – akorát to dělá jinými prostředky, než to zajišťuje TCP.
Někomu připadá bláznovství, že by se mohlo přijít s něčím lepším po více než čtyřiceti letech používání TCP, zkušeností s ním a také po více než čtyřiceti letech změn ve spodních i vyšších vrstvách (před čtyřiceti lety se TCP spojení nepřenášela ani přes LTE, ani stogigabitovými spoji, nestreamovala se přes něj živá vysílání v HD ani přes něj malá čidla neposílala aktuální teplotu každých pár sekund). Někomu zase připadá, že při těch změnách a za tu dobu už se dalo zjistit, že některé něco nejsou ideální, a vymyslet, jak je zlepšit. A zrovna Google má s přenosy protokolem HTTP docela velké zkušenosti, vždyť na tom protokolu celá ta firma stojí.
Takže na tvoje přání to vezmu polopaticky znovu, pro ty, co neznají rozdíl mezi UDP a TCP:
Spojení UDP ze stroje A na stroj B (za dvojtečkou je port), např. DNS:
1) A:X -> B:53: Pošli záznam AAAA pro domena.cz
2) B:53 -> A:X: IP adresa je ...
Většinou se posílá několik dotazů na několik serverů a co dojde, to se použije. DNS serveru je úplně šumák, jestli to došlo. Kdyžtak se zeptá znovu...
Spojení TCP na příkladu SSH:
1) A:X -> B:22: Prosím o spojení na A:X
2) B:Y -> A:X: Nabízím komunikaci na portu Y
3) A:X -> B:Y: Ok, můžeme komunikovat
A v téhle chvíli máme obousměrný tunel A:X <> B:Y se zaručeným pořadím dat a zaručeným doručením, pokud není přerušená linka.
No a teď něco k DDoS. Princip je zahlcení linky oběti. Pokud má 10Gbps uplink, pošlu jí 30Gbps a není tam kapacita pro zpracování legitimního provozu. Abych poslal 30Gbps, musím mít zdroj dat s minimálně 30Gbps. To má málo kdo, takže se používá zesílení přes některý služby (NTP, DNS, ICMP,...). Probíhá to takhle (C je oběť):
AC:X->B:Y: Pošli odpověď na ... // A změní svou IP adresu v paketu na IP adresu oběti
B:Y->C:X: Odpověď delší než dotaz
Celkem triviální záležitost a stačí, když ISP nekontroluje odchozí IP adresy, že patří do jeho rozsahu.
A teď si představme, že se někdo rozhodne po UDP přenášet balíčky souborů na jednu UDP žádost:
AC:X->B:443: Pošli stránku ..., do potvrzení smí odejít 10MB
B:Y->C:X: Stream až 10MB
Při žádosti velikosti řekněme 5kB včetně klíčů pro šifrování (který si můžu vymyslet, server mě nezná) a podpisu (to samý, ví jenom IP adresu, ale ne veřejný klíč) získám až 10MB z jednoho stroje.
Když bude mít průměrný server k dispozici 20Mbps na odbavení dotazu a dá těch 10MB (cca 80Mb) na jeden dotaz, mám ten tok na 0,4s a na saturování 10Gbps linky stačí 10G/200M = 500 dotazů.
500x5kB dotaz = 2,5MB. Za sekundu to musím udělat 2.5x. To znamená, že na dotazy z toku 6.25MB/s ~ 50Mb/s takhle vyrobím DDoS 10Gb/s. To se opravdu vyplatí vyhodit úvodní handshake, že...
<ironie>Ještě že 50mbps+ uplink nikdo nemá doma, dokonce ani ti s gigovou FTTH. </ironie>
Spojení TCP na příkladu SSH:
1) A:X -> B:22: Prosím o spojení na A:X
2) B:Y -> A:X: Nabízím komunikaci na portu Y
3) A:X -> B:Y: Ok, můžeme komunikovat
A v téhle chvíli máme obousměrný tunel A:X <> B:Y se zaručeným pořadím dat a zaručeným doručením, pokud není přerušená linka.
Tohle myslíte naprosto vážně? Tedy ona je to v zásadě je to pravda, ale nerozumím tomu, proč tam zavádíte nějaké Y, když je stejně vždy 22.
A teď si představme, že se někdo rozhodne po UDP přenášet balíčky souborů na jednu UDP žádost:
AC:X->B:443: Pošli stránku ..., do potvrzení smí odejít 10MB
B:Y->C:X: Stream až 10MB
Jak konkrétně to hodláte v případě QUICu provést? Pokud ten falešný request chcete poslat jako nový request, pořád budete muset být schopen nejdřív odpovědět na paket od serveru (poslaný na C), stejně jako u TCP. Pokud se pokoušíte navázat na dřívější komunikaci mezi C a B, musel byste přesvědčit B, že jste C (ve smyslu jejich předchozího spojení), což bude ještě těžší.
"Tohle myslíte naprosto vážně?"
Já ne, specifikace TCP to myslí vážně.
TCP funguje tak, že server POSLOUCHÁ na nějakým portu, na který se navazuje spojení. V reakci na žádost vytvoří proces/vlákno, to si otevře nějaký jiný port, přes který jde obousměrná komunikace s klientem. V další komunikaci už ten port 22, 80, 443,... nefiguruje!!!
A to je na TCP hezký a elegantní, vlastní vlákno na serveru, který se stará o jednoho klienta na jednom portu a všechno je hezky izolovaný...
"Jak konkrétně to hodláte v případě QUICu provést?"
Naprosto normálně, pošlu GET s podvrženou adresou příjemce. Jedna z ambicí http3 je totiž odbourat úvodní handshake kvůli latenci a jedna zpráva pak stačí k tomu, aby začal přenos ještě před potvrzením (to se řeší za běhu). Viz obrázek v článku. TCP chce tři paktery, QUIC jeden a nijak se nezalamuje s ověřením, že příjemce existuje a ty data chce. Pokud bude rychlost a objem dat jako parametr, dáš maximum a je problém. A pokud zavedou psedoochranu jako podpis požadavku, tak taky nic nevyřeší, protože klient není na serveru registrovaný (jaká je pravděpodobnost, že server z TLD .fr zná obecnýho klienta z .cz?), stačí jakýkoliv klíč na podpis požadavku a je vymalováno...
I kdyby délka dat během potvrzování byla fixní třeba 100kB, furt ten attack zesílím z 5kB GET na 100kB odpověď a furt to je lepší, než použít obyčejný DNS Amplification.
TCP funguje tak, že server POSLOUCHÁ na nějakým portu, na který se navazuje spojení. V reakci na žádost vytvoří proces/vlákno, to si otevře nějaký jiný port, přes který jde obousměrná komunikace s klientem. V další komunikaci už ten port 22, 80, 443,... nefiguruje!!!
Prosím vás, buď si (opravdu) přečtěte RFC 791 nebo se třeba na nějaké takové TCP spojení podívejte tcpdumpem nebo wiresharkem, ať se můžeme začít bavit vážně. Pokud budete na tomto tvrzení i poté trvat, poprosil bych o konkrétní místo nebo citaci, kde se v RFC 791 (nebo jiném RFC týkajícím se TCP) něco takového píše.
Naprosto normálně, pošlu GET s podvrženou adresou příjemce. Jedna z ambicí http3 je totiž odbourat úvodní handshake kvůli latenci a jedna zpráva pak stačí k tomu, aby začal přenos ještě před potvrzením (to se řeší za běhu). Viz obrázek v článku. TCP chce tři paktery, QUIC jeden a nijak se nezalamuje s ověřením, že příjemce existuje a ty data chce.
A tady si, prosím, dostudujte aspoň základní popis fungování QUICu, např. z toho odkazu, který jsem sem dával před chvílí. Handshake tam samozřejmě je, ale místo dvou roundtripů (jeden na TCP, jeden na TLS) stačí jeden.
RFC791 řeší "internet protokol". TCP a UDP jsou v IP stacku o level výš. UDP je RFC768, TCP je RFC793.
Nastuduj si https://tools.ietf.org/html/rfc793 - podívej se na "figure 1", kde je jeho místo. Mezi IP a aplikací.
V odkazovaným dokumentu bych navíc doporučoval přečíst a pochopit, co se myslí v kapitole jako párem IP adresa: port pro klienta a server a proč se tam navíc píše o listeningu na well known portu...
Jedna věc je splést si číslo (mimochodem, už 20 minut před vaším příspěvkem jsem se sám opravil), naprosto nepochopi základy fungování je něco úplně jiného. Takže ještě jednou: kde přesně se podle vás píše, že SYNACK paket (stejně jako všechny další) používá (nebo i jen může použít) na straně serveru jiné číslo portu než to, na které klient poslal SYN (a na kterém server poslouchá)? Nebo si prostě pusťte tcpdump/wireshark a podívejte se, jak to vypadá.
"TCP funguje tak, že server POSLOUCHÁ na nějakým portu, na který se navazuje spojení. V reakci na žádost vytvoří proces/vlákno, to si otevře nějaký jiný port, přes který jde obousměrná komunikace s klientem. V další komunikaci už ten port 22, 80, 443,... nefiguruje!!!"
Myslim, ze si pletete pojmy socket a port. Nebyl byste prvni ani posledni.
To myslíte vážně, že v další komunikaci port, na kterém služba poslouchá, už nefiguruje? Server vždycky poslouchá (i pro "další komunikaci") na jenom portu a z něj taky ta komunikace odchází. Jak by pak asi mohl fungovat NAT třeba. Snad si to proboha neplete s nějakým related a established, které na firewallu slouží k tomu, aby se odpověď od serveru dostala přes firewall i druhým směrem ke klientovi, kde logicky dopředu (při konfiguraci) není znám destination port.
> Já ne, specifikace TCP to myslí vážně.
> TCP funguje tak, že server POSLOUCHÁ na nějakým portu, na který se navazuje spojení. V reakci na žádost vytvoří proces/vlákno, to si otevře nějaký jiný port, přes který jde obousměrná komunikace s klientem. V další komunikaci už ten port 22, 80, 443,... nefiguruje!!!
Tohle si zaslouzi oznaceni prvni TCP konspiracni teorie :-D
Co naplat, ze se tak TCP nechova (port 22 ci jiny tam zustane), ale pokud si myslis, ze se v reakci na zadost vytvori proces ci vlakno, tak to asi mluvi za vse :-)
>Naprosto normálně, pošlu GET s podvrženou adresou příjemce. Jedna z ambicí http3 je totiž odbourat úvodní handshake kvůli latenci a jedna zpráva pak stačí k tomu, aby začal přenos ještě před potvrzením (to se řeší za běhu).
Pro zmenu QUIC konspiracni teorie a opet stejny vysledek. QUIC se tak nechova. Smyslem QUIC je snizeni latence - tzn. neco podobneho jako TCP handshake tam je, akorat je to navic k necemu.
V ramci toho handshaku si navic domluvim parametry TLS, takze v momente, kdy skonci, tak uz mam pouzitelny kanal. Misto toho, abych ted zacal delat novy handshake pro sifrovani.