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

Cómo obtener y entregar archivos SXG con nginx y los desafíos de la carga previa 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 compatibles con SXG mostrarán esos archivos SXG como si los hubieran enviado los creadores del contenido original. Esto te permite implementar la precarga entre sitios sin infringir la privacidad. En esta guía, se muestra cómo distribuir SXG correctamente.

Compatibilidad con varios navegadores

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

Cómo obtener archivos SXG

En el encabezado de tu solicitud Accept, especifica que deseas que el servidor muestre un archivo SXG junto con la solicitud:

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

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

Entrega 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 editor del contenido original aparecerá en la barra.

Carga previa de subrecursos

La mayoría de las páginas web constan de varios subrecursos, como CSS, JavaScript, imágenes y fuentes. El contenido de SXG no se puede modificar sin la clave privada del creador del contenido. Esto genera problemas cuando el navegador intenta resolver los 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 reciba 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 hacerlo en la fase de precarga para preservar la privacidad. Si se recuperó el recurso durante la fase de precarga, el creador del 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 dirige 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 generará una discrepancia de firma y se invalidará el SXG.

Si se intenta vincular la referencia a app.js en distributor.test/index.html.sxg a distributor.test/app.js, se produce una discrepancia de firma.

Para resolver este problema, ahora hay una función experimental de carga previa de subrecursos SXG en Chrome. Puedes habilitarla 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 por el hash de integridad específico de 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". Esto especifica la ruta de acceso de app.js y corresponde al subrecurso.

ancla

El primero es relativamente fácil porque nginx-sxg-module puede calcular hashes de integridad y, luego, incorporarlos en encabezados de vínculos desde respuestas ascendentes. 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 además de https://website.test/app.js, todo lo que necesitas agregar a tu configuración de nginx es el 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 constan de muchos subrecursos. Además, el distribuidor debe adjuntar el encabezado del vínculo de anclaje adecuado al publicar un archivo SXG. Actualmente, no hay una manera fácil de resolver este problema, así que mantente atento a las actualizaciones.

Enviar comentarios

A los ingenieros de Chromium les interesa recibir tus comentarios sobre la distribución de SXG en webpackage-dev@chromium.org. También puedes unirte a la conversación sobre las especificaciones o informar un error al equipo. Tus comentarios serán de gran ayuda para el proceso de estandarización y también ayudarán a abordar los problemas de implementación. Gracias.