Cómo distribuir intercambios HTTP firmados (SXG) con nginx

Cómo obtener y entregar archivos SXG con nginx, y los desafíos de la precarga de subrecursos

Hiroki Kumazaki
Hiroki Kumazaki

Como distribuidor de intercambios HTTP firmados (SXG), puedes publicar archivos SXG en nombre de los creadores de contenido original. Los navegadores web que admiten SXG mostrarán esos archivos SXG como si se entregaran desde los creadores del contenido original. Esto te permite implementar la carga previa entre sitios sin infringir la privacidad. En esta guía, se muestra cómo distribuir SXG de forma correcta.

Actualmente, Chrome es el único navegador que admite SXG. Consulta la sección Consenso y estandarización de Intercambios HTTP firmados por el origen para obtener información más actualizada.

Obtén archivos SXG

Especifica en el encabezado de solicitud Accept que deseas que el servidor devuelva un archivo SXG junto con la solicitud:

Accept: application/signed-exchange;v=b3,*/*;q=0.8

En esta guía, se supone que colocas tus archivos SXG en /var/www/sxg.

Publica un archivo SXG simple

Adjunta los siguientes encabezados para distribuir un solo archivo SXG:

Content-Type: application/signed-exchange;v=v3
X-Content-Type-Options: nosniff

Configura nginx:

http {
    ...
    types {
        application/signed-exchange;v=b3  sxg;
    }
    add_header X-Content-Type-Options nosniff;

    location / {
        more_set_headers "Content-Type: application/signed-exchange;v=b3";
        alias /var/www/sxg/;
        try_files $uri.sxg $uri =404;
        autoindex off;
    }
    ...

Carga la configuración nueva en nginx:

sudo systemctl restart nginx.service

nginx comenzará a publicar archivos SXG. Cuando Chrome acceda a tu servidor, la dirección del publicador del contenido original aparecerá en la barra.

Cómo recuperar previamente subrecursos

La mayoría de las páginas web consisten en varios subrecursos, como CSS, JavaScript, fuentes e imágenes. El contenido de SXG no se puede cambiar sin la clave privada del creador de contenido. Esto causa problemas cuando el navegador intenta resolver subrecursos.

Por ejemplo, supongamos que index.html.sxg de https://website.test/index.html tiene un vínculo a https://website.test/app.js. Cuando el navegador de un usuario recibe el archivo SXG de https://distributor.test/example.com/index.html.sxg, encontrará el vínculo a https://website.test/app.js. El navegador puede recuperar https://website.test/app.js directamente en el acceso real, pero no debe hacerse en la fase de carga previa para preservar la privacidad. Si el recurso se recuperó durante la fase de carga previa, el creador de contenido (website.test) podría detectar qué distribuidor de contenido (distributor.test) solicita el recurso.

El vínculo a app.js en distributor.test/index.html.sxg apunta a website.test/app.js.

Si el distribuidor quiere publicar app.js.sxg desde su propio servicio y trata de modificar https://website.test/app.js para que sea la versión del distribuidor de ese subrecurso (como https://distributor.test/website.test/app.js.sxg), se producirá una discrepancia de firma y el SXG no será válido.

Un intento de vincular la referencia a app.js en distributor.test/index.html.sxg a distributor.test/app.js causa una discrepancia de firma.

Para resolver este problema, ahora hay una función experimental de precarga de subrecursos de SXG en Chrome. Puedes habilitarlo en about://flags/#enable-sxg-subresource-prefetching. Para usar la carga previa de subrecursos, se deben cumplir las siguientes condiciones:

  • El editor debe incorporar una entrada de encabezado de respuesta en SXG, como link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk=". Esto especifica el subrecurso que se puede sustituir con el hash de integridad específico del SXG.
  • El distribuidor debe adjuntar un encabezado de respuesta cuando publique el SXG, como link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js". Especifica la ruta de acceso de app.js y corresponde al subrecurso.

ancla

La primera es relativamente fácil porque nginx-sxg-module puede calcular los valores hash de integridad y, luego, incorporarlos en los encabezados de vínculos de las respuestas upstream. Sin embargo, la segunda es más difícil porque el distribuidor de contenido debe conocer los subrecursos especificados en el SXG.

Si no hay subrecursos distintos de https://website.test/app.js, todo lo que debes agregar a la configuración de nginx es lo siguiente:

add_header link <https://distributor.test/website.test/app.js.sxg>;rel="alter...

Sin embargo, estos casos son poco frecuentes, ya que los sitios web típicos consisten en muchos subrecursos. Además, el distribuidor debe adjuntar el encabezado de vínculo de anclaje correcto cuando publique un archivo SXG. Por el momento, no hay una forma sencilla de resolver este problema, así que no te pierdas las actualizaciones.

Enviar comentarios

Los ingenieros de Chromium están ansiosos por escuchar tus comentarios sobre la distribución de SXG en webpackage-dev@chromium.org. También puedes unirte a la discusión sobre las especificaciones o informar un error al equipo. Tus comentarios ayudarán en gran medida al proceso de estandarización y también a abordar los problemas de implementación. ¡Gracias!