如何生成带有 SXG 扩展的 TLS 证书,安装用于生成 SXG 文件的工具,以及配置 nginx 以提供 SXG 文件。
签名 HTTP 交换 (SXG) 是一项新的 Web 技术,使用户更容易区分内容创建者和内容分发者。本指南向您展示如何设置 SXG。
跨浏览器支持
包括 Google Chrome、Samsung Internet 和 Microsoft Edge 在内的几款基于 Chromium 的浏览器都支持 SXG。有关最新信息,请参阅“Origin-Signed HTTP Exchanges”的“共识和标准化”部分。
先决条件
要在您的网站上实施 SXG,您必须
- 控制您的域名,包括 DNS 条目。
- 获取证书。SXG 需要颁发专用证书。特别是,您不能重用您的 TLS 密钥或证书。
- 拥有一个可以通过 HTTPS 生成和提供 SXG 的 HTTP 服务器。
假设
本指南假设您
- 拥有 OpenSSL 1.1.1 环境。本指南是使用 Ubuntu 18.04 LTS on amd64 ISA 编写的。
- 能够运行
sudo
来安装可执行文件。 - 使用
nginx
作为 HTTP 服务器。 - 正在使用 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 扩展”复选框,该复选框位于“其他证书选项”下。

如果您的证书不符合这些条件,出于安全原因,浏览器和分发商将拒绝您的 SXG。本指南假设您从 DigiCert 获取的证书的文件名为 mySxg.pem
。
步骤 2:安装 libsxg
SXG 格式很复杂,不使用工具很难生成。您可以使用以下选项之一来生成 SXG
- 用 Go 语言编写的 gen-signedexchange 工具。
- 用 C 语言编写的
libsxg
库。
本指南使用 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
。作为前提条件,您需要安装 git
、cmake
、openssl
和 gcc
。
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.ac.cn/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,反之亦然,因此您需要两个证书。假设您将 SSL 密钥/证书对放在 /path/to/ssl/
中,并将 SXG 密钥/证书对放在 /path/to/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 至关重要,因为它定位证书链。证书链包含证书和 OCSP Stapling 信息,采用 cbor 格式。请注意,您不必从同一来源提供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
提供根目录中的静态文件,但是您可以为您的应用程序使用 upstream 指令,以便为任意 Web 应用程序后端(例如 Ruby on Rails、Django 或 Express)制作 SXG,只要您的 nginx
用作前端 HTTP(S) 服务器。
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
发送反馈
Chromium 中从事 SXG 工作的工程师非常希望在 webpackage-dev@chromium.org 听到您的反馈。您也可以加入规范讨论,或向团队报告错误。您的反馈将极大地帮助标准化过程,并有助于解决实施问题。谢谢!