nginx を使用して Signed HTTP Exchange(SXG)を配布する方法

nginx を使用して SXG ファイルを取得して提供する方法と、サブリソース プリフェッチの課題。

Hiroki Kumazaki
Hiroki Kumazaki

Signed HTTP Exchange(SXG)配信者は、元のコンテンツ クリエイターの代わりに SXG ファイルを配信できます。SXG をサポートするウェブブラウザでは、このような SXG ファイルはオリジナルのコンテンツ作成者から配信されたかのように表示されます。これにより、プライバシーを侵害することなくクロスサイト プリロードを実装できます。このガイドでは、SXG を適切に配布する方法について説明します。

現在、SXG をサポートしているブラウザは Chrome のみです。最新の情報については、オリジン 署名付き HTTP エクスチェンジの「コンセンサスと標準化」セクションをご覧ください。

SXG ファイルを取得する

サーバーがリクエストとともに SXG ファイルを返すように、Accept リクエスト ヘッダーで指定します。

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

このガイドでは、SXG ファイルを /var/www/sxg に配置することを前提としています。

シンプルな SXG ファイルを提供する

単一の SXG ファイルを配布するには、次のヘッダーを添付します。

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

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

新しい構成を nginx に読み込みます。

sudo systemctl restart nginx.service

nginx は SXG ファイルの配信を開始します。Chrome がサーバーにアクセスすると、元のコンテンツ パブリッシャーのアドレスがバーに表示されます。

サブリソースをプリフェッチする

ほとんどのウェブページは、CSS、JavaScript、フォント、画像などの複数のサブリソースで構成されています。SXG のコンテンツは、コンテンツ クリエイターの秘密鍵がないと変更できません。これにより、ブラウザがサブリソースを解決しようとしたときに問題が発生します。

たとえば、https://website.test/index.htmlindex.html.sxghttps://website.test/app.js へのリンクがあるとします。ユーザーのブラウザが https://distributor.test/example.com/index.html.sxg から SXG ファイルを受信すると、https://website.test/app.js へのリンクが見つかります。ブラウザは実際のアクセス時に https://website.test/app.js を直接取得できますが、プライバシー保護のため、プリロード フェーズではこれを実行しないでください。リソースがプリロード フェーズ中に取得された場合、コンテンツ クリエイター(website.test)は、リソースをリクエストしているコンテンツ配信会社(distributor.test)を検出できます。

distributor.test/index.html.sxg の app.js へのリンクは、website.test/app.js を参照しています。

ディストリビューターが独自のサービスから app.js.sxg を提供する場合、https://website.test/app.js をそのサブリソースのディストリビューターのバージョン(https://distributor.test/website.test/app.js.sxg など)に変更しようとすると、署名の不一致が発生し、SXG が無効になります。

distributor.test/index.html.sxg の app.js への参照を distributor.test/app.js にリンクしようとすると、署名の不一致が発生します。

この問題を解決するために、Chrome に試験運用版の SXG サブリソース プリフェッチ機能が追加されました。 これは about://flags/#enable-sxg-subresource-prefetching で有効にできます。サブリソース プリフェッチを使用するには、次の条件を満たす必要があります。

  • ニュース メディアは、link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk=" のようなレスポンス ヘッダー エントリを SXG に埋め込む必要があります。SXG 固有の整合性ハッシュに置き換えることができるサブリソースを指定します。
  • 配信者は、SXG を配信するときにレスポンス ヘッダー(link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js" など)を添付する必要があります。これは app.js のパスを指定し、サブリソースに対応します。

アンカー

最初の方法は比較的簡単です。nginx-sxg-module は完全性ハッシュを計算し、アップストリーム レスポンスからのリンクヘッダーに埋め込むことができるためです。ただし、コンテンツ配信者は SXG で指定されたサブリソースを認識している必要があるため、後者はより困難です。

https://website.test/app.js 以外のサブリソースがない場合は、nginx 構成に追加する必要があるのは次の項目のみです。

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

ただし、一般的なウェブサイトは多くのサブリソースで構成されているため、このようなケースはまれです。また、配信会社は SXG ファイルを配信する際に、適切なアンカーリンク ヘッダーを添付する必要があります。現在のところ、この問題を簡単に解決する方法はありません。最新情報をお待ちください。

フィードバックを送信

Chromium のエンジニアは、SXG の配信について webpackage-dev@chromium.org でフィードバックを募集しています。仕様のディスカッションに参加したり、チームにバグを報告したりすることもできます。いただいたフィードバックは、標準化プロセスの推進と実装に関する問題の解決に役立てさせていただきます。 ありがとうございました