如何使用 nginx 設定 Signed HTTP Exchange (SXG)

如何利用 SXG 擴充功能產生 TLS 憑證、安裝用來產生 SXG 檔案的工具,以及設定 nginx 提供 SXG 檔案。

Hiroki Kumazaki
Hiroki Kumazaki

Signed HTTP Exchange (SXG) 是一種新型態的網頁技術,可讓使用者更容易區分內容創作者和內容發布者。本指南說明如何設定 SXG。

多個以 Chromium 為基礎的瀏覽器都支援 SXG,包括 Google Chrome、Samsung Internet 和 Microsoft Edge。如需最新資訊,請參閱「原點簽署的 HTTP 交換機制」一文的「共識和標準化」一節。

如要在網站上實作 SXG,您必須:

  • 掌控網域,包括 DNS 項目。
  • 取得憑證。SXG 需要核發專屬憑證。特別是,您無法重複使用 TLS 金鑰或憑證。
  • 使用可透過 HTTPS 產生及放送 SXG 的 HTTP 伺服器。

假設

本指南假設您已:

  • 具備 OpenSSL 1.1.1 環境。本指南是使用 amd64 ISA 上的 Ubuntu 18.04 LTS 編寫。
  • 可執行 sudo 來安裝可執行檔。
  • 使用 nginx 做為 HTTP 伺服器。
  • 使用 DigiCert 產生包含 SXG 相關擴充功能的憑證,因為目前 DigiCert 似乎是唯一支援這些擴充功能的供應商。

此外,本文中的指令範例假設您的網域是 website.test,因此您必須以實際網域取代 website.test

步驟 1:取得 SXG 憑證

如要產生 SXG,您需要具備 CanSignHttpExchanges 副檔名的 TLS 憑證,以及特定金鑰類型。DigiCert 提供這類擴充功能的憑證。您需要 CSR 檔案才能核發憑證,因此請使用下列指令產生此檔案:

openssl ecparam -genkey -name prime256v1 -out mySxg.key
openssl req -new -key mySxg.key -nodes -out mySxg.csr -subj "/O=Test/C=US/CN=website.test"

您會收到 CSR 檔案,如下所示:

-----BEGIN CERTIFICATE REQUEST-----
MIHuMIGVAgEAMDMxDTALBgNVBAoMBFRlc3QxCzAJBgNVBAYTAlVTMRUwEwYDVQQD
DAx3ZWJzaXRlLnRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7IVaeMvid
S5UO7BspzSe5eqT5Qk6X6dCggUiV/vyqQaFDjA/ALyTofgXpbCaksorPaDhdA+f9
APdHWkTbbdv1oAAwCgYIKoZIzj0EAwIDSAAwRQIhAIb7n7Kcc6Y6pU3vFr8SDNkB
kEadlVKNA24SVZ/hn3fjAiAS2tWXhYdJX6xjf2+DL/smB36MKbXg7VWy0K1tWmFi
Sg==
-----END CERTIFICATE REQUEST-----

請確認下列項目:

  • 有效期不超過 90 天。
  • 啟用「在憑證中加入 CanSignHttpExchanges 擴充功能」核取方塊,可在「其他憑證選項」下方找到。
勾選「在憑證中加入 CanSignHttpExchanges 擴充功能」核取方塊。

如果憑證不符合這些條件,瀏覽器和發布商會基於安全性考量拒絕您的 SXG。本指南假設您從 DigiCert 取得的憑證檔案名稱為 mySxg.pem

步驟 2:安裝 libsxg

SXG 格式相當複雜,如果沒有工具,很難產生。您可以使用下列任一選項產生 SXG:

本指南使用 libsxg

選項 1:從 Debian 套件安裝 libsxg

只要 OpenSSL (libssl-dev) 版本相符,您就可以透過一般的 Debian 方式安裝套件。

sudo apt install -y libssl-dev
wget https://github.com/google/libsxg/releases/download/v0.2/libsxg0_0.2-1_amd64.deb
wget https://github.com/google/libsxg/releases/download/v0.2/libsxg-dev_0.2-1_amd64.deb
sudo dpkg -i libsxg0_0.2-1_amd64.deb
sudo dpkg -i libsxg-dev_0.2-1_amd64.deb

方法 2:手動建構 libsxg

如果您使用的環境與 .deb 檔案不相容,可以自行建構 libsxg。根據先決條件,您必須安裝 gitcmakeopensslgcc

git clone https://github.com/google/libsxg
mkdir libsxg/build
cd libsxg/build
cmake .. -DRUN_TEST=false -DCMAKE_BUILD_TYPE=Release
make
sudo make install

步驟 3:安裝 nginx 外掛程式

nginx 外掛程式可讓您動態產生 SXG,而非在服務前以靜態方式產生。

方法 1:從 Debian 套件安裝外掛程式

nginx 的 SXG 模組已在 GitHub 上發布。在以 Debian 為基礎的系統上,您可以將其安裝為二進位檔套件:

sudo apt install -y nginx=1.15.9-0
wget https://github.com/google/nginx-sxg-module/releases/download/v0.1/libnginx-mod-http-sxg-filter_1.15.9-0ubuntu1.1_amd64.deb
sudo dpkg -i libnginx-mod-http-sxg-filter_1.15.9-0ubuntu1.1_amd64.deb

方法 2:手動建構外掛程式

建構 nginx 模組需要 nginx 原始碼。您可以使用下列指令取得 tarball,並與 SXG 動態模組一併建構:

git clone https://github.com/google/nginx-sxg-module
wget https://nginx.org/download/nginx-1.17.5.tar.gz
tar xvf nginx-1.17.5.tar.gz
cd nginx-1.17.5
./configure --prefix=/opt/nginx --add-dynamic-module=../nginx-sxg-module --without-http_rewrite_module --with-http_ssl_module
make
sudo make install

nginx 設定具有極高的彈性。在系統的任一位置安裝 nginx,然後指定 module/config/log/pidfile 的相對路徑。本指南假設您已將其安裝至 /opt/nginx

步驟 4:設定 nginx 外掛程式以搭配使用 SXG

方法 1:設定從 Debian 安裝的 nginx 模組

如果您先前使用步驟 3 的選項 1,請按照以下操作說明操作。

傳送 SXG 內容時必須使用 HTTPS。您可以透過 DigiCert、Let's Encrypt 和其他服務取得 SSL/TLS 憑證。請注意,您「不能」將 SXG 憑證用於 SSL,反之亦然,因此您會需要兩個憑證。假設您使用 /path/to/ssl/ 中的 SSL 金鑰/憑證組合和 SXG 金鑰/憑證組合 /path/to/sxg/ 中的 SXG 金鑰/憑證組合,/etc/nginx/nginx.conf 中的設定檔應該大致如下所示:

user www-data;
include /etc/nginx/modules-enabled/*.conf;

events {
     worker_connections 768;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    add_header  X-Content-Type-Options nosniff;

    server {
        listen 443 ssl;
        ssl_certificate     /path/to/ssl/fullchain.pem;
        ssl_certificate_key /path/to/ssl/privkey.pem;
        server_name  website.test;

        sxg on;
        sxg_certificate     /path/to/sxg/mySxg.pem;
        sxg_certificate_key /path/to/sxg/mySxg.key;
        sxg_cert_url        https://website.test/certs/cert.cbor;
        sxg_validity_url    https://website.test/validity/resource.msg;
        sxg_cert_path       /certs/cert.cbor;

        root /var/www/html;
    }
}
  • sxg_cert_url 必須找到憑證鏈結,因此瀏覽器才能正確載入 SXG。憑證鏈結包含採用 cbor 格式的憑證和 OCSP 簽署資訊。請注意,您不必從相同來源提供 cert.cbor 檔案。只要支援 HTTPS,您就可以透過任何 CDN 或其他靜態檔案服務提供檔案。
  • sxg_validitiy_url 預計會提供 SXG 簽名標頭相關資訊。如果網頁自上次 SXG 檢索後未經過任何修改,從技術層面來說,就不需要下載整個 SXG 檔案。因此,只需更新簽章標頭資訊就能減少網路流量。但詳細資料尚未實作。

啟動 nginx,即可放送 SXG!

sudo systemctl start nginx.service
curl -H"Accept: application/signed-exchange;v=b3" https://website.test/ > index.html.sxg
cat index.html.sxg
sxg1-b3...https://website.test/...(omit)

選項 2:設定從原始碼建構的 nginx 模組

如果您先前使用步驟 3 的選項 2,請按照以下操作說明進行。

請將 /opt/nginx 下安裝的 nginx 系統設定為類似下列範例的樣式:

load_module "/opt/nginx/modules/ngx_http_sxg_filter_module.so";

events {
    worker_connections 768;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    add_header X-Content-Type-Options nosniff;

    server {
        listen 443 ssl;
        ssl_certificate     /path/to/ssl/fullchain.pem;
        ssl_certificate_key /path/to/ssl/privkey.pem;
        server_name  example.com;

        sxg on;
        sxg_certificate     /path/to/sxg/mySxg.pem;
        sxg_certificate_key /path/to/sxg/mySxg.key;
        sxg_cert_url        https://website.test/certs/cert.cbor;
        sxg_validity_url    https://website.test/validity/resource.msg;
        sxg_cert_path       /certs/cert.cbor;

        root /opt/nginx/html;
    }
}

然後啟動 nginx。你現在可以取得 SXG!

cd /opt/nginx/sbin
sudo ./nginx
curl -H "Accept: application/signed-exchange;v=b3" https://website.test/ > index.html.sxg
less index.html.sxg
sxg1-b3...https://website.test/...(omit)

步驟 5:提供應用程式後端

在上述範例中,nginx 會提供根目錄中的靜態檔案,但只要 nginx 可做為前端 HTTP (S) 伺服器,您就可以為應用程式使用上游指示詞,為任意網路應用程式後端(例如 Ruby on Rails、Django 或 Express) 製作 SXG。

upstream app {
    server 127.0.0.1:8080;
}

server {
    location / {
        proxy_pass http://app;
    }
}

步驟 6:測試

使用dump-signedexchange 工具測試所提供的 SXG 是否正確,確保系統不會回報錯誤,並驗證標頭和主體是否符合預期。

go get -u github.com/WICG/webpackage/go/signedexchange/cmd/dump-signedexchange
export PATH=$PATH:~/go/bin
dump-signedexchange -verify -uri https://website.test/ | less

提供意見

負責 SXG 的 Chromium 工程師非常樂意聽取您的意見,請寄至 webpackage-dev@chromium.org。您也可以加入規格討論,或向團隊回報錯誤。您的意見回饋將大大有助於標準化程序,並協助解決實作問題。感謝您!