>

QUIC: lo que se esconde detrás de HTTP/3

Siro Ramírez Losada     Colaboraciones    24/05/2019


Este artículo ha sido escrito por Fernando Ruiz y publicado originalmente en el blog de Solid GEAR.

HTTP/3 es la tercera versión oficial del popular protocolo de transferencia de hipertexto utilizado para intercambiar información binaria en la World Wide Web. Las mejoras más notables de HTTP/3 vienen de la mano de QUIC, un nuevo protocolo de la capa de red desarrollado por Google.

El 28 de octubre de 2018, Mark Nottingham, Presidente de los Grupos de Trabajo HTTP y QUIC de la IETF, hizo la petición oficial de renombrar HTTP-over-QUIC comoHTTP/3 y en las discusiones posteriores que siguieron y se prolongaron durante varios días, la propuesta de Nottingham fue aceptada por otros miembros de la IETF, quienes en noviembre de 2018 dieron su sello oficial de aprobación para que HTTP-over-QUIC se convirtiera en HTTP/3.

Introducción a QUIC

QUIC (Quick UDP Internet Connection) soporta un conjunto de conexiones multiplexadas a través de UDP y ha sido diseñado para proporcionar una seguridad equivalente a TLS/SSL reduciendo la latencia tanto en la conexión como en el transporte de datos.

QUIC viene a resolver algunos de los problemas detectados en TCP. Por ejemplo, TCP examina cada paquete en un único flujo de datos y por el contrario, QUIC utiliza el concepto de streams, originalmente utilizado en protocolos como HTTP/2 y SCTP. Cuando a cada recurso se le asigna un flujo conceptual individual, es posible que la capa de transporte sepa que, cuando se pierde un paquete, los paquetes siguientes pueden seguir utilizándose si contienen datos de otro recurso que no estaba en el paquete perdido. Otro ejemplo de problemas que QUIC resuelve es el lento establecimiento de la conexión de TLS/SSL, el cual requiere varios intercambios de información (round trip times, RTTs), mientras que QUIC reduce este coste de conexión a prácticamente cero RTTs.

Handshakes en TCP, TCP+TLS y QUIC

Handshake

La mejora en el handshake de QUIC se basa, entre otros, en un cambio relacionado con el modo de identificar las conexiones. TCP, durante el proceso de negociación, utiliza una tupla de 4 elementos que contienen las IP’s y lospuertos utilizados en la conexión. Un problema común para TCP es que la conexión no sobrevive cuando cambia alguna de las IP’s o puertos de los endpoints (por ejemplo, cuando el cliente cambia de 4G a WiFi). Cuando esto sucede, los paquetes no pueden ser identificados por el otro endpoint y la conexión se finaliza al alcanzar un timeout. Si la conexión sigue siendo deseada por cualquiera de los dos endpoints, deberá iniciarse de nuevo el proceso de negociación, lo que conlleva un aumento de la carga de tráfico.

QUIC resuelve este problema utilizando un identificador único e independiente para cada extremo de la conexión. Este ID de conexión tiene un tamaño de entre cuatro y dieciocho bytes, que es creado de manera específica para la implementación de cada endpoint, lo que asegura que el endpoint pueda identificar su propio ID en un paquete QUIC, ya que el ID de conexión de destino está presente en cada paquete. El hecho de que este ID sea dinámico permite reducir la sobrecarga de paquetes cuando se utiliza QUIC para configuraciones más simples (por ejemplo, P2P), utilizando un pequeño ID de conexión. Sin embargo, en situaciones más complejas (por ejemplo, el balanceo de carga) es posible almacenar información adicional en el ID de conexión.

Pasos del proceso de negociación

El handshake de QUIC comienza cuando un cliente envía un “Hello” al servidor, que es un paquete inicial que contiene los identificadores de conexión y la versión de QUIC con la que el cliente desea iniciar dicha conexión. En el payload del paquete se encuentran los datos que son utilizados por TLS para negociar el conjunto de cifrado y otros secretos. Este payload es encriptado usando el algoritmo de encriptación por defecto de la versión de QUIC utilizada. Todos los paquetes, excepto la negociación de versiones y el restablecimiento sin estado, se cifran mediante un algoritmo de cifrado de autenticacióncon datos asociados (AEAD). En cuanto a las claves de este algoritmo de encriptación, se utilizan la versión, el ID de conexión, el número de paquete y el encabezado en su totalidad para generarlas.

A continuación, cuando el servidor recibe el paquete “Hello” del cliente, primero comprueba la versión utilizada en la cabecera del paquete. El campo versión es uno de los campos fijos de las cabeceras en QUIC, por lo tanto estará presente en las cabeceras de todas las versiones de QUIC. Si la versión dada no está en su propia lista de versiones soportadas, el servidor crea un paquete de negociación de versión y se lo envía al cliente. Si la versión es compatible, el servidor responde al paquete con un paquete de negociación, que se utiliza para enviar datos relacionados con el handshake, que contiene el “Hello”. Al recibir el “Hello” del cliente y generar el “Hello” de vuelta, el servidor ha terminado con la negociación.

Sin embargo, el cliente todavía necesita terminar este proceso recibiendo el mensaje “Hello” del servidor. Cuando el cliente recibe este paquete de negociación, el handshake se completa en el cliente y puede derivar claves de su pila TLS para proteger el payload de todos los paquetes transmitidos. Los paquetes que se encriptan con estas nuevas claves se denominan paquetes 1-RTT protegidos.

El cliente todavía necesita indicar al servidor que ha terminado el handshake. Estos datos, procedentes de su pila TLS,se envían con un paquete de negociación. Todos los datos después de este paquete se envían con un paquete protegido 1-RTT. Después de recibir el último paquete de handshake del cliente, el servidor sabe que el cliente ha terminado la negociación. El servidor también puede enviar un ticket de sesión al cliente para hacer posible la reanudación de la sesión en la siguiente conexión que se lleve a cabo.

Handshake con QUIC con un solo RTT para una conexión segura

0-RTT

QUIC proporciona una forma de que las conexiones empiecen a intercambiar datos sin esperar a que se produzca un único RTT para el handshake (0-RTT). Esto es posible cuando el cliente inicia una conexión con un servidor con el que ya se había puesto en contacto anteriormente, por lo que la conexión se inicia con información adicional de la sesión de la conexión anterior. Usando esta información, es posible exportar claves de encriptación que pueden ser usadas para encriptar el payload. El servidor que recibe este payload puede exportar las mismas claves de encriptación de la información de sesión que se proporciona en el paquete”Hello” del cliente. A continuación, el servidor puede descifrar el payload utilizando las primeras claves de datos.

Handshake 0-RTT de QUIC

Este mecanismo es posible porque QUIC utiliza TLS/1.3 para el cifrado de datos.

Conclusiones

Desde Chrome 29 y Opera 16 ya está implementado el soporte para QUIC, lo que significa que estos dos navegadores web ya están preparados para la transición.

QUIC en Chrome

Dicho esto, no pretendo decir que QUIC vaya a tener un éxito desde el principio e inmediatamente gane una gran parte del pastel, sino que mi opinión es que la cuota de despliegue irá creciendo lentamente, aunque espero que sea más rápido que con IPv6