如何使用 nginx 设置 Signed HTTP Exchange (SXG)

如何生成具有 SXG 扩展名的 TLS 证书、安装用于生成 SXG 文件的工具,以及配置 nginx 以提供 SXG 文件。

Hiroki Kumazaki
Hiroki Kumazaki

Signed HTTP Exchange (SXG) 是一项新的网络技术,可让用户更轻松地区分内容创作者和内容分发商。本指南介绍了如何设置 SXG。

跨浏览器支持

一些基于 Chromium 的浏览器支持 SXG,包括 Google Chrome 浏览器、三星浏览器 互联网和 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 相关扩展程序的证书,因为它是目前唯一支持这些扩展程序的提供商。

此外,本文中的示例命令假定您的域名是 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 扩展程序复选框处于选中状态。 “其他证书选项”下找到此选项。
。 <ph type="x-smartling-placeholder">
</ph>
在证书中添加 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 软件包安装插件

GitHub 上分发了 nginx 的 SXG 模块。 在基于 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 源代码。 您可以获取此 tar 压缩文件,并使用以下命令将其与 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,反之亦然,因此您需要两个证书。假设您将 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 至关重要,因为它可以定位证书链。证书链包含 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) 服务器,您就可以为应用使用上游指令为任意 Web 应用后端(例如 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 听取您的反馈。 您还可以参与规范讨论,或向相关团队报告 bug。 您的反馈将极大地帮助标准化流程,并有助于解决实施问题。 谢谢!