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 liés au préchargement des sous-ressources.

Hiroki Kumazaki
Hiroki Kumazaki

En tant que distributeur d'échanges HTTP signés (SXG), vous pouvez fournir des fichiers SXG au nom des créateurs de contenu d'origine. Les navigateurs Web compatibles avec les échanges signés affichent ces fichiers comme s'ils avaient été fournis par les créateurs de contenu d'origine. Cela vous permet d'implémenter un préchargement intersite sans porter atteinte à la confidentialité. Ce guide vous explique comment distribuer correctement les échanges signés.

Compatibilité multinavigateur

Chrome est actuellement le seul navigateur compatible avec les échanges signés. Pour obtenir les informations les plus récentes, consultez la section "Consensus et standardisation" de la page Échanges HTTP signés à l'origine.

Obtenir les fichiers SXG

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

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

Dans ce guide, nous partons du principe que vous devez placer vos fichiers SXG dans /var/www/sxg.

Diffuser un fichier SXG simple

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

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 du contenu d'origine s'affiche dans la barre.

Précharger les sous-ressources

La plupart des pages Web se composent de plusieurs sous-ressources, telles que CSS, JavaScript, les polices et les 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 les sous-ressources.

Par exemple, supposons que index.html.sxg de https://website.test/index.html ait 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 cette opération ne doit pas être effectuée lors de la phase de préchargement pour des raisons de 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 le distributeur de contenu (distributor.test) qui demande la ressource.

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

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

Toute tentative d'association de la référence à app.js dans distributor.test/index.html.sxg à distributor.test/app.js entraîne une non-concordance de la signature.

Pour résoudre ce problème, Chrome propose désormais une fonctionnalité expérimentale de préchargement des sous-ressources SXG. Vous pouvez l'activer à l'adresse suivante: about://flags/#enable-sxg-subresource-prefetching. Pour utiliser le préchargement de 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 indique la sous-ressource pouvant être remplacée par le hachage d'intégrité spécifique de l'échange signé.
  • 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". Ce champ spécifie le chemin d'accès de app.js et correspond à la sous-ressource.

anchor

La première est relativement simple, car nginx-sxg-module peut calculer les hachages d'intégrité et les intégrer dans les en-têtes de liens 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 sous-ressource en dehors de https://website.test/app.js, il vous suffit d'ajouter à votre configuration nginx la commande suivante:

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

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

Envoyer des commentaires

Les ingénieurs de Chromium souhaitent connaître vos commentaires 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 dans une démarche de normalisation et à résoudre les problèmes de mise en œuvre. Merci !