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

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

Hiroki Kumazaki
Hiroki Kumazaki

Signed HTTP Exchanges (SXG) 是一項新的網路技術,能讓使用者輕鬆分辨內容創作者與內容發布商。本指南說明如何設定 SXG。

跨瀏覽器支援

有好幾個以 Chromium 為基礎的瀏覽器都支援 SXG,包括 Google Chrome、Samsung 網際網路和 Microsoft Edge詳情請參閱 來源簽署的 HTTP 廣告交易平台 查看最新資訊

必要條件

如要在網站上導入 SXG,請務必完成下列事項:

  • 可以控管您的網域,包括 DNS 項目。
  • 取得憑證。SXG 需要核發專屬憑證。具體來說,您無法重複使用 TLS 金鑰或憑證。
  • 擁有可透過 HTTPS 產生及提供 SXG 的 HTTP 伺服器。

假設

本指南假設您已:

  • 擁有 OpenSSL 1.1.1 環境。本指南是以 Ubuntu 18.04 LTS 編寫於 amd64 ISA。
  • 能夠執行 sudo 安裝執行檔。
  • nginx 做為 HTTP 伺服器。
  • 目前使用的是只有 SXG 相關擴充功能的供應商,因此正在使用 DigiCert 產生包含 SXG 相關擴充功能的憑證。

此外,本文中的指令範例假設您的網域是 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 動態模組建構 tarball:

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:設定與 SXG 搭配使用的 nginx 外掛程式

選項 1:設定 install-from-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,請按照下列指示操作。

設定如以下範例所示的 nginx 系統 (安裝在 /opt/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 提供根目錄中的靜態檔案,但您可以為應用程式使用上游指令,建立任何網路應用程式後端 (例如 Ruby on Rails、Django 或 Express),只要 nginx 可做為前端 HTTP(S) 伺服器即可。

upstream app {
    server 127.0.0.1:8080;
}

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

步驟 6:測試

使用傾印簽署交換工具 來測試提供的 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

提供意見

希望透過 webpackage-dev@chromium.org 提供意見,聆聽 SXG 團隊的 Chromium 工程師提供寶貴意見。 你也可以參與規格討論回報錯誤。 您的意見不但有助於標準化程序,也有助於解決導入問題。 感謝您!