Comment distribuer des échanges HTTP signés (SXG) à l'aide de nginx

Comment obtenir et diffuser des fichiers SXG à l'aide de nginx, et défis du préchargement des sous-ressources.

Hiroki Kumazaki
Hiroki Kumazaki

En tant que distributeur Signed HTTP Exchanges (SXG), vous pouvez envoyer des fichiers SXG au nom des créateurs de contenu original. Les navigateurs Web compatibles avec les échanges signés afficheront ces fichiers comme s'ils avaient été envoyés par les créateurs du contenu original. Cela vous permet d'implémenter le préchargement intersites sans porter atteinte à la confidentialité. Ce guide vous explique comment distribuer correctement les échanges signés.

Compatibilité multi-navigateur

Chrome est actuellement le seul navigateur compatible avec les échanges signés. Voir le consensus et section "Standardization" de la page Échanges HTTP signés Origin-Signed (Échanges HTTP signés) pour obtenir des informations plus à jour.

Obtenir les fichiers SXG

Dans l'en-tête de requête Accept, indiquez que le serveur doit renvoyer un fichier SXG avec la requête:

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

Ce guide suppose que vous placez vos fichiers SXG dans /var/www/sxg.

Livrer un fichier SXG simple

Joignez les en-têtes suivants pour distribuer un fichier SXG unique:

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

Configurez 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;
    }
    ...

Chargez la nouvelle configuration dans nginx:

sudo systemctl restart nginx.service

nginx commencera à diffuser les fichiers SXG. Lorsque Chrome accède à votre serveur, l'adresse de l'éditeur de contenu original s'affiche dans la barre.

Précharger les sous-ressources

La plupart des pages Web sont composées de plusieurs sous-ressources, telles que CSS, JavaScript, des polices et des images. Le contenu d'un échange signé ne peut pas être modifié sans la clé privée du créateur du contenu. Cela entraîne des problèmes lorsque le navigateur tente de résoudre des sous-ressources.

Par exemple, supposons que index.html.sxg de https://website.test/index.html comporte un lien vers https://website.test/app.js. Lorsque le navigateur d'un utilisateur reçoit le fichier SXG de https://distributor.test/example.com/index.html.sxg, il trouve le lien vers https://website.test/app.js. Le navigateur peut récupérer https://website.test/app.js directement lors de l'accès réel, mais cela ne doit pas être fait pendant la phase de préchargement pour préserver la confidentialité. Si la ressource a été récupérée pendant la phase de préchargement, le créateur de contenu (website.test) peut détecter quel distributeur de contenu (distributor.test) demande cette ressource.

Le lien vers app.js dans distributor.test/index.html.sxg pointe vers website.test/app.js.

Si le distributeur souhaite diffuser des app.js.sxg à partir de son propre service et tente de modifier https://website.test/app.js pour qu'il corresponde à la version du distributeur de cette sous-ressource (par exemple, https://distributor.test/website.test/app.js.sxg), cela entraînera une incohérence au niveau de la signature et l'échange signé ne sera pas valide.

Toute tentative d'association de la référence à app.js dans distributor.test/index.html.sxg vers distributor.test/app.js entraîne une incohérence au niveau de la signature.

Pour résoudre ce problème, il existe désormais une fonctionnalité expérimentale de préchargement des sous-ressources SXG dans Chrome. Vous pouvez l'activer à l'adresse suivante: about://flags/#enable-sxg-subresource-prefetching. Pour utiliser le préchargement des sous-ressources, les conditions suivantes doivent être remplies:

  • L'éditeur doit intégrer une entrée d'en-tête de réponse dans l'échange signé, par exemple: link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk=". Ce champ spécifie la sous-ressource qui peut être remplacée par le hachage d'intégrité spécifique du SXG.
  • Le distributeur doit joindre un en-tête de réponse lors de la diffusion de l'échange signé, tel que: link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js". Cela spécifie le chemin d'accès à app.js et correspond à la sous-ressource.

anchor

Le premier est relativement simple, car nginx-sxg-module peut calculer des hachages d'intégrité et les intégrer dans des en-têtes de liens à partir des réponses en amont. Mais la seconde est plus difficile, car le distributeur de contenu doit connaître les sous-ressources spécifiées dans l'échange signé.

S'il n'existe aucune autre sous-ressource que https://website.test/app.js, il vous suffit d'ajouter les éléments suivants dans votre configuration nginx:

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

Mais ces cas sont rares, car les sites Web classiques comportent de nombreuses sous-ressources. En outre, le distributeur doit joindre l'en-tête de lien d'ancrage approprié lors de la diffusion d'un fichier SXG. Il n'existe actuellement aucun moyen simple de résoudre ce problème. Nous vous communiquerons prochainement plus d'informations à ce sujet.

Envoyer des commentaires

Les ingénieurs Chromium sont ravis de connaître votre avis sur la distribution des échanges signés à l'adresse webpackage-dev@chromium.org. Vous pouvez également participer à la discussion sur les spécifications ou signaler un bug à l'équipe. Vos commentaires nous aideront à améliorer le processus de normalisation et à résoudre les problèmes d'implémentation. Merci !