Menuju QUIC: Yang Mendasari HTTP / 3

Tonggak sejarah baru dalam sejarah Internet dimulai di depan mata kita: kita dapat berasumsi bahwa HTTP / 3 telah diumumkan. Pada akhir Oktober, Mark Nottingham dari IETF menyarankan sudah memutuskan nama untuk protokol baru yang telah dibangun IETF sejak 2015. Jadi, alih-alih nama seperti QUIC, HTTP / 3 keras muncul. Publikasi Barat sudah menulis tentang ini dan lebih dari sekali . Sejarah QUIC dimulai di perut Good Corporation pada 2012, sejak saat itu hanya server Google yang mendukung koneksi HTTP-over-QUIC, tetapi waktu terus berjalan dan Facebook sudah mulai menerapkan teknologi ini (7 November, Facebook dan LiteSpeed membuat interaksi pertama melalui HTTP / 3 ); Saat ini, pangsa situs yang mendukung QUIC adalah 1,2%. Akhirnya, kelompok kerja WebRTC juga melihat ke arah QUIC (plus lihat API QUIC ), sehingga dalam waktu dekat video / audio real-time akan melalui QUIC alih-alih RTP / RTCP. Oleh karena itu, kami memutuskan bahwa akan sangat bagus untuk mengungkapkan rincian QUET IETF: khusus untuk Habr, kami menyiapkan terjemahan dari titik yang telah lama dibaca i. Selamat menikmati!

QUIC (Quick UDP Internet Connections) adalah protokol layer transport standar baru yang dienkripsi dan memiliki banyak peningkatan HTTP: keduanya untuk mempercepat lalu lintas dan meningkatkan keamanan. QUIC juga memiliki tujuan jangka panjang - untuk akhirnya menggantikan TCP dan TLS. Pada artikel ini, kita akan melihat chip QUIC kunci dan mengapa web akan mendapat manfaat dari mereka, serta masalah-masalah mendukung protokol yang sama sekali baru ini.

Bahkan, ada dua protokol dengan nama yang sama: Google QUIC (gQUIC), protokol asli yang dikembangkan oleh para insinyur Google beberapa tahun yang lalu, yang, setelah serangkaian percobaan, diadopsi oleh Internet Engineering Task Force (IETF) untuk standardisasi.

IETF QUIC (selanjutnya hanya QUIC) sudah memiliki perbedaan kuat dengan gQUIC sehingga dapat dianggap sebagai protokol terpisah. Dari format paket hingga jabat tangan dan pemetaan HTTP, QUIC telah meningkatkan arsitektur gQUIC asli dengan berkolaborasi dengan banyak organisasi dan pengembang yang memiliki tujuan bersama: untuk membuat Internet lebih cepat dan lebih aman.

Jadi, perbaikan apa yang ditawarkan QUIC?

Keamanan Terpadu (dan Kinerja)


Salah satu perbedaan yang paling mencolok antara QUIC dan TCP terhormat adalah tujuan awalnya yang dinyatakan sebagai protokol transport yang aman secara default . QUIC mencapai ini dengan menggunakan otentikasi dan enkripsi, yang biasanya terjadi pada tingkat yang lebih tinggi (misalnya, dalam TLS), dan bukan dalam protokol transport itu sendiri.

Jabat tangan QUIC asli menggabungkan komunikasi tiga arah biasa melalui TCP dengan jabat tangan TLS 1.3, yang menyediakan otentikasi peserta, serta koordinasi parameter kriptografi. Bagi mereka yang terbiasa dengan TLS: QUIC menggantikan level perekaman TLS dengan format frame sendiri, tetapi pada saat yang sama menggunakan jabat tangan TLS.

Ini tidak hanya memungkinkan koneksi untuk selalu dienkripsi dan dikonfirmasi, tetapi juga lebih cepat untuk membuat koneksi awal: jabat tangan QUIC biasa membuat pertukaran antara klien dan server dalam satu lintasan, sementara TCP + TLS 1.3 membuat dua lintasan.


Namun, QUIC melangkah lebih jauh dan juga mengenkripsi metadata koneksi yang dapat dengan mudah dikompromikan oleh pihak ketiga. Sebagai contoh, penyerang dapat menggunakan nomor paket untuk mengarahkan pengguna di beberapa jalur jaringan ketika migrasi koneksi digunakan (lihat di bawah). QUIC mengenkripsi nomor paket, sehingga tidak dapat dikoreksi oleh orang lain selain peserta sebenarnya dalam koneksi.

Enkripsi juga dapat efektif terhadap "stagnasi" - sebuah fenomena yang tidak memungkinkan fleksibilitas protokol untuk digunakan dalam praktik karena asumsi yang salah dalam implementasi (pengerasan - inilah mengapa TLS 1.3 ditata untuk waktu yang lama . Kami mempostingnya hanya setelah beberapa perubahan yang cegah blok yang tidak diinginkan untuk revisi TLS baru).

Memblokir awal antrian (Head-of-line blocking)


Salah satu peningkatan besar yang diberikan HTTP / 2 adalah kemampuan untuk menggabungkan permintaan HTTP yang berbeda dalam satu koneksi TCP. Ini memungkinkan aplikasi HTTP / 2 memproses permintaan secara paralel dan memanfaatkan saluran jaringan dengan lebih baik.

Tentu saja, ini adalah langkah maju yang signifikan. Karena aplikasi sebelumnya diperlukan untuk memulai banyak koneksi TCP + TLS jika mereka ingin memproses beberapa permintaan HTTP secara bersamaan (misalnya, ketika browser perlu menerima CSS dan JavaScript untuk membuat halaman). Membuat koneksi baru memerlukan beberapa jabat tangan, serta menginisialisasi jendela kelebihan: ini berarti memperlambat rendering halaman. Permintaan HTTP gabungan menghindari ini.



Namun, ada kekurangannya: karena beberapa permintaan / respons dikirimkan melalui koneksi TCP yang sama, semuanya semuanya sama-sama tergantung pada kehilangan paket, bahkan jika data yang hilang hanya menyangkut salah satu permintaan. Ini disebut "memblokir awal antrian."

QUIC melangkah lebih dalam dan memberikan dukungan kelas satu untuk menggabungkan permintaan, misalnya, permintaan HTTP yang berbeda dapat dianggap sebagai permintaan QUIC transport yang berbeda, tetapi pada saat yang sama mereka semua akan menggunakan koneksi QUIC yang sama - yaitu, jabat tangan tambahan tidak diperlukan, ada satu jabat tangan status kemacetan, permintaan QUIC dikirimkan secara independen - sebagai hasilnya, dalam banyak kasus, kehilangan paket hanya mempengaruhi satu permintaan.

Dengan demikian, dimungkinkan untuk secara signifikan mengurangi waktu, misalnya, perenderan penuh halaman web (CSS, JavaScript, gambar, dan sumber daya lainnya), terutama dalam kasus jaringan yang kelebihan beban dengan kehilangan paket yang tinggi.

Sangat sederhana, ya?


Untuk memenuhi janjinya, protokol QUIC harus mengatasi beberapa asumsi bahwa banyak aplikasi jaringan telah menerima begitu saja. Ini dapat mempersulit implementasi dan implementasi QUIC.

QUIC dirancang untuk dikirimkan melalui datagram UDP untuk memfasilitasi pengembangan dan menghindari masalah dengan perangkat jaringan yang menjatuhkan paket protokol yang tidak dikenal (karena sebagian besar perangkat mendukung UDP). Ini juga memungkinkan QUIC untuk hidup di ruang pengguna, jadi, misalnya, browser akan dapat mengimplementasikan fitur protokol baru dan menyampaikannya kepada pengguna akhir, tanpa menunggu pembaruan OS.

Namun, tujuan yang baik untuk mengurangi masalah jaringan membuatnya lebih sulit untuk melindungi paket dan merutekannya dengan benar.

Satu NAT untuk bersatu dan bersatu dengan satu kehendak hitam


Biasanya, router NAT bekerja dengan koneksi TCP menggunakan tuple 4 nilai (sumber IP dan port plus IP dan port tujuan), serta memonitor paket TCP SYN, ACK dan FIN yang dikirimkan melalui jaringan; router dapat menentukan kapan koneksi baru dibuat dan kapan berakhir. Oleh karena itu, manajemen yang tepat dari ikatan NAT (komunikasi antara IP dan port internal dan eksternal) dimungkinkan.

Dalam kasus QUIC, ini belum memungkinkan, karena Router NAT modern belum tahu tentang QUIC, sehingga biasanya downgrade ke pemrosesan UDP default dan kurang akurat, yang berarti timeout dari durasi sewenang-wenang (kadang-kadang pendek) , yang dapat mempengaruhi koneksi jangka panjang.

Ketika pengikatan kembali terjadi (misalnya, karena batas waktu), perangkat di luar perimeter NAT mulai menerima paket dari sumber lain, yang membuatnya tidak mungkin untuk mempertahankan koneksi hanya menggunakan tupel dari 4 nilai.


Dan itu bukan hanya NAT! Satu fitur QUIC disebut migrasi koneksi dan memungkinkan perangkat untuk mentransfer koneksi ke alamat / jalur IP lain sesuai kebijakan mereka. Misalnya, klien seluler dapat mentransfer koneksi QUIC dari jaringan seluler ke jaringan WiFi yang sudah dikenal (pengguna telah memasuki kedai kopi favorit, dll.).

QUIC mencoba menyelesaikan masalah ini dengan konsep ID koneksi: sepotong informasi yang panjangnya berubah-ubah, dikirimkan dalam paket QUIC dan memungkinkan untuk mengidentifikasi koneksi. Perangkat Endpoint dapat menggunakan ID ini untuk melacak koneksi mereka tanpa berdamai dengan tuple. Dalam praktiknya, harus ada banyak ID yang menunjukkan koneksi yang sama, misalnya, untuk menghindari menghubungkan jalur yang berbeda ketika koneksi dimigrasi - karena seluruh proses dikendalikan hanya oleh perangkat akhir, bukan oleh middlebox.

Namun, mungkin ada masalah bagi operator telekomunikasi yang menggunakan anycast dan routing ECMP, di mana satu IP berpotensi mengidentifikasi ratusan atau ribuan server. Karena router perbatasan di jaringan ini belum tahu cara menangani lalu lintas QUIC, mungkin paket UDP dari koneksi QUIC yang sama, tetapi dengan tupel yang berbeda, akan dikirim ke server yang berbeda, yang berarti pemutusan.



Untuk menghindari hal ini, operator mungkin perlu menerapkan penyeimbang tingkat yang lebih pintar. Ini dapat dicapai secara terprogram tanpa memengaruhi router perbatasan itu sendiri (misalnya, lihat proyek Katran dari Facebook).

Qpack


Fitur lain yang berguna dari HTTP / 2 adalah Header Compression (HPACK) , yang memungkinkan perangkat akhir untuk mengurangi ukuran data yang dikirim dengan membuang permintaan dan tanggapan yang tidak perlu.

Secara khusus, di antara teknik-teknik lain, HPACK menggunakan tabel dinamis dengan header yang telah dikirim / diterima dari permintaan / tanggapan HTTP sebelumnya, yang memungkinkan perangkat untuk merujuk permintaan / respons baru ke header yang sebelumnya ditemui (alih-alih mengirimnya lagi) .

Tabel HPACK harus disinkronkan antara encoder (pihak yang mengirim permintaan / respons) dan decoder (sisi penerima), jika tidak, decoder tidak dapat men-decode apa yang diterimanya.

Dalam hal HTTP / 2 melalui TCP, sinkronisasi ini transparan karena layer transport (TCP) mengirimkan permintaan / tanggapan dalam urutan yang sama dengan yang dikirim. Artinya, Anda dapat mengirim instruksi ke decoder untuk memperbarui tabel dalam permintaan / respons sederhana. Tetapi dengan QUIC, segalanya menjadi jauh lebih rumit.

QUIC dapat mengirimkan beberapa permintaan / respons HTTP ke berbagai arah pada saat yang bersamaan, yang berarti QUIC menjamin pesanan pengiriman dalam satu arah, sementara tidak ada jaminan seperti itu dalam hal berbagai arah.

Misalnya, jika klien mengirim permintaan HTTP A dalam aliran QUIC A, serta permintaan B dalam aliran B, maka karena permutasi paket atau kehilangan jaringan, server akan menerima permintaan B sebelum permintaan A. Dan jika permintaan B dikodekan sebagai ditunjukkan di header permintaan A, maka server tidak akan dapat men-decode permintaan B, karena permintaan belum terlihat A.

Protokol gQUIC memecahkan masalah ini dengan hanya membuat semua header (tetapi bukan badan) dari permintaan HTTP / tanggapan berurutan dalam aliran gQUIC tunggal. Ini memastikan bahwa semua header datang dalam urutan yang benar, apa pun yang terjadi. Ini adalah skema yang sangat sederhana, dengan bantuannya, solusi yang ada dapat terus menggunakan kode yang dipertajam di bawah HTTP / 2; di sisi lain, ini meningkatkan kemungkinan memblokir awal antrian, yang dirancang untuk mengurangi QUIC. Oleh karena itu, kelompok kerja QUET IETF mengembangkan pemetaan baru antara HTTP dan QUIC (HTTP / QUIC), serta prinsip kompresi tajuk baru, QPACK.

Dalam draf akhir spesifikasi HTTP / QUIC dan QPACK, setiap pertukaran permintaan / respons HTTP menggunakan aliran QUIC dua arahnya sendiri, sehingga memblokir awal antrian tidak terjadi. Juga, untuk mendukung QPACK, setiap peserta membuat dua aliran QUIC searah tambahan, satu untuk mengirim pembaruan tabel, yang lain untuk mengonfirmasi penerimaan mereka. Dengan demikian, encoder QPACK dapat menggunakan tautan ke tabel dinamis hanya setelah decoder mengonfirmasi penerimaannya.

Refleksi pembiasan


Masalah umum dengan protokol berbasis UDP adalah kerentanan mereka terhadap serangan refleksi, ketika penyerang memaksa server untuk mengirim sejumlah besar data kepada korban. Penyerang memalsukan IP-nya sehingga server berpikir bahwa permintaan data berasal dari alamat korban.


Jenis serangan ini bisa sangat efektif ketika respons server jauh lebih besar daripada permintaan. Dalam hal ini, mereka berbicara tentang "keuntungan."

TCP biasanya tidak digunakan untuk serangan seperti itu, karena paket-paket di jabat tangan asli (SYN, SYN + ACK, ...) memiliki panjang yang sama, sehingga mereka tidak memiliki potensi untuk "amplifikasi".

Di sisi lain, jabat tangan QUIC sangat asimetris: seperti pada TLS, pertama server QUIC mengirim rantai sertifikatnya, yang bisa sangat besar, meskipun fakta bahwa klien harus mengirim hanya beberapa byte (pesan dari ClientHello klien TLS dibangun ke dalam paket QUIC ) Untuk alasan ini, paket QUIC asli harus ditingkatkan ke panjang minimum tertentu, bahkan jika isi paket jauh lebih kecil. Meskipun demikian, ukuran ini masih tidak terlalu efektif, karena respons server tipikal berisi beberapa paket dan karenanya mungkin lebih dari paket klien yang diperbesar.

Protokol QUIC juga mendefinisikan mekanisme verifikasi sumber eksplisit: server, alih-alih memberikan respons besar, hanya mengirim paket coba lagi dengan token unik, yang kemudian dikirim klien ke server dalam paket baru. Jadi server lebih percaya diri bahwa klien tidak memiliki alamat IP pengganti dan Anda dapat mengakhiri jabat tangan. Kurang dari keputusan - waktu jabat tangan meningkat, alih-alih satu pass, dua sudah diperlukan.

Solusi alternatif adalah mengurangi respons server ke ukuran di mana serangan refleksi menjadi kurang efektif - misalnya, menggunakan sertifikat ECDSA (biasanya mereka jauh lebih kecil dari RSA). Kami juga bereksperimen dengan mekanisme kompresi sertifikat TLS menggunakan algoritma kompresi yang tersedia seperti zlib dan brotli; ini adalah fitur yang pertama kali muncul di gQUIC tetapi saat ini tidak didukung di TLS.

Kinerja UDP


Salah satu masalah konstan QUIC adalah perangkat keras dan lunak yang ada yang tidak dapat bekerja dengan QUIC. Kami telah memeriksa bagaimana QUIC mencoba menangani middlebox jaringan seperti router, tetapi area lain yang berpotensi bermasalah adalah kinerja pengiriman / penerimaan data antara perangkat QUIC melalui UDP. Selama bertahun-tahun, upaya telah dilakukan untuk mengoptimalkan implementasi TCP sebanyak mungkin, termasuk kemampuan offload bawaan dalam perangkat lunak (misalnya, sistem operasi) dan dalam perangkat keras (antarmuka jaringan), tetapi tidak ada yang menyangkut UDP.

Namun, hanya masalah waktu sebelum implementasi QUIC melampaui peningkatan dan manfaat ini. Lihatlah upaya baru-baru ini untuk mengimplementasikan pemuatan UDP di Linux , yang akan memungkinkan aplikasi untuk menggabungkan dan mentransmisikan beberapa segmen UDP antara ruang pengguna dan tumpukan jaringan ruang kernel dengan biaya sekitar satu segmen; contoh lain adalah dukungan zerocopy untuk soket di Linux , berkat aplikasi mana yang dapat menghindari biaya menyalin memori ruang pengguna ke ruang kernel.

Kesimpulan


Seperti HTTP / 2 dan TLS 1.3, protokol QUIC harus membawa banyak fitur baru yang akan meningkatkan kinerja dan keamanan situs web dan peserta lain dalam infrastruktur Internet. Kelompok kerja IETF bermaksud untuk meluncurkan versi pertama dari spesifikasi QUIC pada akhir tahun ini, jadi inilah saatnya untuk memikirkan bagaimana kita dapat memanfaatkan manfaat QUIC secara maksimal.

Source: https://habr.com/ru/post/id430436/


All Articles