Auf dem Weg zu QUIC: Was ist die Basis von HTTP / 3?

Ursprünglicher Autor: Alessandro Ghedini
  • Übersetzung
Ein neuer Meilenstein in der Geschichte des Internets beginnt vor unseren Augen: Wir können davon ausgehen, dass HTTP / 3 bereits angekündigt wurde. Ende Oktober schlug Mark Nottingham von der IETF vor, über den Namen des neuen Protokolls zu entscheiden , auf dem die IETF seit 2015 aufbaut. Anstelle von QUIC-ähnlichen Namen erschien also ein lautes HTTP / 3. Westliche Publikationen haben bereits darüber geschrieben und nicht einmal . Die Geschichte von QUIC begann im Jahr 2012 in den Tiefen der Corporation of Good. Seitdem unterstützten nur Google-Server HTTP-über-QUIC-Verbindungen. Die Zeit vergeht, und nun begann Facebook, diese Technologie einzuführen (am 7. November führten Facebook und LiteSpeed die erste HTTP / 3-Interaktion durch ); Derzeit beträgt der Anteil der Websites, die QUIC unterstützen, 1,2%. Zum Schluss noch das WebRTC-Teamschaut auch auf QUIC (plus siehe QUIC API ), so dass Echtzeit-Video / Audio in absehbarer Zeit durch QUIC statt durch RTP / RTCP geht. Daher haben wir entschieden, dass es toll wäre, die Details von IETF QUIC offenzulegen. Speziell für Habr haben wir eine Übersetzung des Longrids vorbereitet, Punkt 1. Genieße es!

QUIC (Quick UDP Internet Connections) ist ein neues, verschlüsseltes Protokoll auf Transportebene, das zahlreiche HTTP-Verbesserungen bietet: sowohl zur Beschleunigung des Datenverkehrs als auch zur Erhöhung der Sicherheit. QUIC hat auch ein langfristiges Ziel: Ersetzung von TCP und TLS. In diesem Artikel werden wir uns sowohl mit den QUIC-Schlüsselchips beschäftigen als auch, warum das Web von ihnen profitieren wird, und auf die Probleme, die dieses völlig neue Protokoll unterstützen.

Tatsächlich gibt es zwei Protokolle mit diesem Namen: Google QUIC (gQUIC), das ursprüngliche Protokoll, das Google-Ingenieure vor einigen Jahren entwickelt haben und das nach einer Reihe von Experimenten von der IETF (Internet Engineering Task Force) zu Standardisierungszwecken übernommen wurde.

IETF QUIC (im Folgenden einfach QUIC genannt) weist bereits so große Unterschiede zu gQUIC auf, dass es als separates Protokoll betrachtet werden kann. Vom Paketformat über das Handshake- und das HTTP-Mapping hat QUIC die ursprüngliche gQUIC-Architektur durch Zusammenarbeit mit vielen Organisationen und Entwicklern verbessert, die ein gemeinsames Ziel verfolgen: das Internet schneller und sicherer zu machen.

Welche Verbesserungen bietet QUIC?

Integrierte Sicherheit (und Leistung)


Einer der auffälligsten Unterschiede zwischen QUIC und dem ehrwürdigen TCP ist das ursprünglich festgelegte Ziel, ein Standard- Transportprotokoll zu sein . QUIC verwendet dazu Authentifizierung und Verschlüsselung, die normalerweise auf einer höheren Ebene (z. B. in TLS) und nicht im Transportprotokoll selbst auftreten.

Der erste Handshake bei QUIC kombiniert die übliche dreifache TCP-Kommunikation mit dem TLS 1.3-Handshake, der die Authentifizierung der Teilnehmer sowie die Koordination der kryptographischen Parameter ermöglicht. Für diejenigen, die mit TLS vertraut sind: QUIC ersetzt den TLS-Aufnahmepegel durch ein eigenes Frame-Format, verwendet jedoch TLS-Handshakes.

Dadurch kann die Verbindung nicht nur immer verschlüsselt und authentifiziert werden, sondern auch die erste Verbindung wird schneller: Der normale QUIC-Handshake führt den Austausch zwischen Client und Server in einem Durchgang aus, während TCP + TLS 1.3 zwei Durchgänge benötigt.


QUIC geht jedoch noch weiter und verschlüsselt auch Verbindungsmetadaten, die von Dritten leicht gefährdet werden können. Beispielsweise können Angreifer Paketnummern verwenden, um Benutzer bei der Verbindungsmigration über mehrere Netzwerkpfade zu leiten (siehe unten). QUIC verschlüsselt Paketnummern, so dass sie nur von den tatsächlichen Teilnehmern an der Verbindung angepasst werden können.

Die Verschlüsselung kann auch wirksam sein gegen „Konservatismus“ - ein Phänomen , das nicht die Flexibilität des Protokolls in der Praxis nicht verwendet aufgrund falscher Annahmen Implementierungen (Verknöcherung - dass aufgrund dem , was die lange verzögerte TLS 1.3 offen legen . Nach nur auslegen mehr Änderungen , dass unerwünschte Blockierungen für neue TLS-Versionen verhindern).

Head-of-Line-Blockierung


Eine der wichtigsten Verbesserungen, die uns HTTP / 2 gebracht hat, ist die Möglichkeit, verschiedene HTTP-Anforderungen in einer TCP-Verbindung zu kombinieren. Auf diese Weise können HTTP / 2-Anwendungen Anforderungen parallel verarbeiten und den Netzwerkkanal besser nutzen.

Dies war natürlich ein bedeutender Schritt nach vorne. Denn früher mussten Anwendungen viele TCP + TLS-Verbindungen initiieren, wenn sie gleichzeitig mehrere HTTP-Anforderungen verarbeiten wollten (z. B. wenn der Browser sowohl CSS als auch JavaScript erhalten muss, um die Seite zu rendern). Das Erstellen neuer Verbindungen erfordert mehrere Handshakes sowie das Initialisieren des Überladungsfensters. Dies bedeutet, dass das Rendern der Seite verlangsamt wird. Kombinierte HTTP-Anforderungen vermeiden dies.



Es gibt jedoch einen Nachteil: Da mehrere Anforderungen / Antworten über dieselbe TCP-Verbindung übertragen werden, sind sie alle gleichermaßen vom Paketverlust abhängig, auch wenn die verlorenen Daten nur eine der Anforderungen betreffen. Dies wird als "Turn Start Blocking" bezeichnet.

QUIC geht tiefer und bietet erstklassige Unterstützung für das Kombinieren von Anforderungen. Beispielsweise können verschiedene HTTP-Anforderungen als unterschiedliche QUIC-Transportanforderungen betrachtet werden, sie verwenden jedoch alle dieselbe QUIC-Verbindung. Das heißt, es sind keine zusätzlichen Handshakes erforderlich Durch die Überlastungsbedingung werden QUIC-Anforderungen unabhängig übermittelt - am Ende wirkt sich der Paketverlust in den meisten Fällen nur auf eine Anforderung aus.

So ist es möglich, die Zeit für beispielsweise das vollständige Rendern einer Webseite (CSS, JavaScript, Bilder und andere Ressourcen) erheblich zu reduzieren, insbesondere bei einem überlasteten Netzwerk mit hohem Paketverlust.

So einfach, ja?


Um seine Versprechen zu erfüllen, muss das QUIC-Protokoll einige Annahmen überwinden, die viele Netzwerkanwendungen für selbstverständlich halten. Dies kann die Implementierung und Implementierung von QUIC erschweren.

QUIC wurde für die Bereitstellung auf UDP-Datagrammen entwickelt, um die Entwicklung zu erleichtern und Probleme mit Netzwerkgeräten zu vermeiden, die Pakete mit unbekannten Protokollen ablegen (da die meisten Geräte UDP unterstützen). Dadurch kann QUIC auch im Benutzerraum leben. So können Browser beispielsweise neue Protokollchips einfügen und diese an Endbenutzer kommunizieren, ohne auf Betriebssystemaktualisierungen zu warten.

Das gute Ziel, die Netzwerkprobleme zu reduzieren, macht es jedoch schwieriger, Pakete zu schützen und sie ordnungsgemäß weiterzuleiten.

Ein NAT, um alle zusammenzubringen und einen einzigen schwarzen Willen zu schmieden


Normalerweise arbeiten NAT-Router mit TCP-Verbindungen unter Verwendung eines 4-wertigen Tupels (Quell-IP und -Port plus IP und Zielport) sowie der Überwachung von TCP-SYN-, ACK- und FIN-Paketen, die über das Netzwerk übertragen werden. Router können feststellen, wann eine neue Verbindung hergestellt wurde und wann sie beendet wurde. Daher ist es möglich, NAT-Bindungen (Verbindungen zwischen interner und externer IP und Ports) präzise zu verwalten.

Im Falle von QUIC ist dies noch nicht möglich. Moderne NAT-Router kennen QUIC noch nicht. Daher werden sie normalerweise auf die standardmäßige und weniger genaue UDP-Verarbeitung heruntergestuft. Dies bedeutet Zeitüberschreitungen beliebiger (manchmal geringer) Dauer , die sich auf langfristige Verbindungen auswirken können.

Wenn eine erneute Bindung auftritt (z. B. aufgrund eines Timeouts), empfängt das Gerät außerhalb des Umkreises des NAT Pakete von einer anderen Quelle, weshalb es unmöglich ist, die Verbindung nur mit einem Tupel von 4 Werten aufrechtzuerhalten.


Und es ist nicht nur NAT! Eine der QUIC-Funktionen wird als Verbindungsmigration bezeichnet und ermöglicht es Geräten, nach eigenem Ermessen Verbindungen zu anderen IP-Adressen / Pfaden zu übertragen. Beispielsweise kann ein mobiler Client eine QUIC-Verbindung von einem mobilen Netzwerk an ein bereits bekanntes WiFi-Netzwerk übertragen (ein Benutzer hat sich in einem bevorzugten Café usw. angemeldet).

QUIC versucht, dieses Problem mit dem Konzept der Verbindungs-ID zu lösen: Eine Information beliebiger Länge, die in QUIC-Paketen übertragen wird und die Identifizierung der Verbindung ermöglicht. Endgeräte können diese ID verwenden, um ihre Verbindungen zu verfolgen, ohne das Tupel abzugleichen. In der Praxis sollte es eine Reihe von IDs geben, die auf dieselbe Verbindung verweisen, z. B. um bei der Migration einer Verbindung die Verbindung verschiedener Pfade zu vermeiden, da der gesamte Prozess nur von Endgeräten und nicht von mittleren Boxen gesteuert wird.

Für Telekommunikationsbetreiber, die Anycast und ECMP-Routing verwenden, kann jedoch ein Problem auftreten, bei dem eine IP-Adresse möglicherweise Hunderte oder Tausende von Servern identifiziert. Da die Grenzrouter in diesen Netzwerken noch nicht wissen, wie sie mit dem QUIC-Verkehr umgehen sollen, kann es vorkommen, dass UDP-Pakete von einer QUIC-Verbindung, aber mit unterschiedlichen Tupeln an verschiedene Server gesendet werden, was bedeutet, dass die Verbindung unterbrochen wird.



Um dies zu vermeiden, müssen die Bediener auf Stufe 4 möglicherweise einen intelligenteren Balancer implementieren. Dies kann programmgesteuert erreicht werden, ohne die Grenzrouter selbst zu beeinflussen (zum Beispiel das Katran- Projekt von Facebook).

QPACK


Eine weitere nützliche HTTP / 2-Funktion war die Header-Komprimierung (HPACK) , die es Endgeräten ermöglicht, die Größe der übertragenen Daten zu reduzieren, indem unnötige Anforderungen und Antworten verworfen werden.

HPACK verwendet unter anderem dynamische Tabellen mit Headern, die bereits von früheren HTTP-Anforderungen / -Antworten gesendet / empfangen wurden. Dadurch können Geräte auf neue Anfragen / Antworten auf zuvor gefundene Header verweisen (anstatt sie erneut zu senden). .

HPACK-Tabellen müssen zwischen dem Encoder (der Partei, die die Anfrage / Antwort sendet) und dem Decoder (der empfangenden Partei) synchronisiert werden, andernfalls kann der Decoder das, was er empfängt, einfach nicht decodieren.

Im Fall von HTTP / 2 über TCP ist diese Synchronisierung transparent, da die Transportschicht (TCP) Anforderungen / Antworten in derselben Reihenfolge übermittelt, in der sie gesendet wurden. Das heißt, Sie können die Decoderanweisungen zum Aktualisieren der Tabellen in einer einfachen Anfrage / Antwort senden. Bei QUIC ist alles viel komplizierter.

QUIC kann mehrere HTTP-Anforderungen / -Antworten in verschiedene Richtungen gleichzeitig liefern, was bedeutet, dass QUIC die Zustellung in eine Richtung garantiert. Bei mehreren Richtungen gibt es keine Garantie.

Wenn zum Beispiel ein Client die HTTP-Anfrage A im QUIC-Stream A sowie die Anfrage B im Stream B aufgrund von Paketaustausch oder Netzwerkverlusten sendet, empfängt der Server die Anfrage B vor der Anfrage A. Und wenn die Anfrage B verschlüsselt wurde wurde im Anforderungsheader A angegeben, der Server kann die Anforderung B einfach nicht decodieren, da er die Anforderung A noch nicht gesehen hat.

Im gQUIC-Protokoll wurde dieses Problem einfach dadurch gelöst, dass alle Header (nicht aber der Body) der HTTP-Anforderungen / -Antworten konsistent gemacht wurdeninnerhalb eines gQUIC-Stroms. Dadurch wurde sichergestellt, dass alle Header in der richtigen Reihenfolge angezeigt wurden, unabhängig davon, was passiert ist. Dies ist ein sehr einfaches Schema, mit dessen Hilfe bestehende Lösungen den für HTTP / 2 geschärften Code weiterhin verwenden können. Auf der anderen Seite erhöht dies die Wahrscheinlichkeit, dass die Warteschlange blockiert wird, um die QUIC zu reduzieren ist. Daher hat die QUIC-Arbeitsgruppe aus der IETF eine neue Abbildung zwischen HTTP und QUIC (HTTP / QUIC) sowie ein neues Prinzip der Header-Komprimierung entwickelt - QPACK.

Im endgültigen Entwurf der HTTP / QUIC- und QPACK-Spezifikationen verwendet jeder HTTP-Anforderungs- / Antwort-Austausch seinen eigenen bidirektionalen QUIC-Stream, sodass das Starten der Warteschlange nicht blockiert wird. Um QPACK zu unterstützen, erstellt jeder Teilnehmer zwei zusätzliche unidirektionale QUIC-Streams, einen zum Senden von Tabellenaktualisierungen und den anderen zum Bestätigen des Empfangs. Daher kann der QPACK-Encoder die Verknüpfung zu der dynamischen Tabelle erst verwenden, nachdem sein Empfang vom Decoder bestätigt wurde.

Reflexionsreflexion


Ein häufiges Problem bei UDP-basierten Protokollen ist ihre Anfälligkeit für Reflexionsangriffe, wenn ein Angreifer einen Server veranlasst, eine riesige Datenmenge an das Opfer zu senden. Der Angreifer ersetzt seine IP-Adresse, sodass der Server der Meinung ist, dass die Datenanforderung von der Adresse des Opfers stammt.


Diese Art von Angriff kann sehr effektiv sein, wenn die Antwort des Servers unvergleichlich größer ist als die Anforderung. In diesem Fall sprechen wir über den "Gewinn".

TCP wird normalerweise nicht für solche Angriffe verwendet, da die Pakete im ursprünglichen Handshake (SYN, SYN + ACK, ...) dieselbe Länge haben, sodass sie kein Potenzial für "Gewinn" haben.

Andererseits ist der QUIC-Handshake sehr asymmetrisch: Wie in TLS sendet der QUIC-Server zuerst seine Zertifikatskette, die recht groß sein kann, obwohl der Client nur wenige Bytes senden muss (die Nachricht vom ClientHLS-TLS-Client ist eingebaut.) ). Aus diesem Grund muss das ursprüngliche QUIC-Paket auf eine bestimmte Mindestlänge erhöht werden, auch wenn der Inhalt des Pakets wesentlich kleiner ist. Diese Maßnahme ist jedoch immer noch nicht sehr effektiv, da eine typische Serverantwort mehrere Pakete enthält und daher möglicherweise größer ist als ein erweitertes Clientpaket.

Das QUIC-Protokoll definiert auch einen expliziten Quellverifikationsmechanismus: Anstatt eine große Antwort zu senden, sendet der Server nur ein Wiederholungspaket mit einem eindeutigen Token, das der Client dann in einem neuen Paket an den Server sendet. Der Server hat daher mehr Vertrauen, dass der Client keine gefälschte IP-Adresse hat und Sie den Handshake abschließen können. Das Minus der Entscheidung ist, dass die Zeit des Hendzhaek zunimmt, statt eines Durchgangs sind bereits zwei erforderlich.

Eine alternative Lösung besteht darin, die Antwort des Servers auf eine Größe zu reduzieren, in der der Reflexionsangriff weniger effektiv wird, beispielsweise durch Verwendung von ECDSA-Zertifikaten (normalerweise sind sie viel kleiner als RSA). Wir haben auch mit dem TLS-Zertifikatskomprimierungsmechanismus experimentiert.Standardkomprimierungsalgorithmen wie zlib und brotli verwenden; Dies ist eine Funktion, die erstmals in gQUIC erschienen ist, aber derzeit nicht von TLS unterstützt wird.

UDP-Leistung


Ein ständiges Problem von QUIC ist die vorhandene Hardware und Software, die nicht mit QUIC arbeiten kann. Wir haben bereits darüber nachgedacht, wie QUIC versucht, mit Netzwerk-Mid-Boxes wie Routern zurechtzukommen, aber ein anderer möglicherweise problematischer Bereich ist die Sende- / Empfangsleistung von Daten zwischen QUIC-Geräten über UDP. Im Laufe der Jahre wurden Anstrengungen unternommen, die TCP-Implementierungen so weit wie möglich zu optimieren, einschließlich integrierter Entladefunktionen in Software (z. B. Betriebssysteme) und Hardware (Netzwerkschnittstellen). Dies betrifft jedoch nicht UDP.

Es ist jedoch nur eine Frage der Zeit, bis die QUIC-Implementierungen diese Verbesserungen und Vorteile übertreffen. Sehen Sie sich die jüngsten Bemühungen zur Einführung von UDP-Offloading unter Linux andie es Anwendungen ermöglichen würde, mehrere UDP-Segmente zwischen dem Benutzerraum und dem Kernelraum zu dem Netzwerkstapel zu kombinieren und zu übertragen, und dies für ungefähr ein Segment; Ein anderes Beispiel ist die Zerocopy- Unterstützung für Sockets in Linux , dank derer die Kosten für das Kopieren von Benutzerspeicherplatz in den Kernelraum vermieden werden können.

Fazit


Wie HTTP / 2 und TLS 1.3 sollte das QUIC-Protokoll eine Unmenge neuer Funktionen mit sich bringen, die die Leistung und Sicherheit von Websites und anderen Teilnehmern der Internetinfrastruktur erhöhen. Die IETF-Arbeitsgruppe beabsichtigt, die erste Version der QUIC-Spezifikationen bis Ende des Jahres einzuführen. Es ist also an der Zeit, darüber nachzudenken, wie wir die Vorteile von QUIC optimal nutzen können.

Jetzt auch beliebt: