Como configurar Signed HTTP Exchanges (SXG) usando nginx

Como gerar um certificado TLS com extensões SXG, instalar ferramentas para gerar arquivos SXG e configurar o nginx para exibir arquivos SXG.

Hiroki Kumazaki
Hiroki Kumazaki

Signed HTTP Exchanges (SXG) é uma nova tecnologia da Web que facilita a diferenciação dos criadores de conteúdo dos distribuidores pelos usuários. Neste guia, mostramos como configurar as SXG.

Suporte a vários navegadores

Vários navegadores baseados no Chromium são compatíveis com SXG, incluindo Google Chrome, Samsung Internet e Microsoft Edge. Consulte a seção de consenso e padronização Trocas HTTP assinadas pela origem para ver informações mais atualizadas.

Pré-requisitos

Para implementar as SXGs no seu site, você precisa:

  • Tenha controle sobre seu domínio, incluindo entradas DNS.
  • Receber certificados. As SXGs exigem a emissão de um certificado dedicado. Não é possível reutilizar a chave ou o certificado TLS.
  • Ter um servidor HTTP que possa gerar e exibir SXG por HTTPS.

Suposições

Para seguir este guia, você precisa:

  • Ter um ambiente OpenSSL 1.1.1. Este guia foi escrito com Ubuntu 18.04 LTS em amd64 ISA.
  • Saber executar sudo para instalar executáveis.
  • Use nginx como um servidor HTTP.
  • estão usando o DigiCert para gerar certificados que incluem extensões relacionadas a SXG, porque atualmente ele parece ser o único provedor que oferece suporte a essas extensões.

Além disso, os comandos de exemplo neste artigo presumem que seu domínio seja website.test. Portanto, você precisará substituir website.test pelo seu domínio real.

Etapa 1: acessar o certificado das SXG

Para gerar as SXGs, você precisa de um certificado TLS com a extensão CanSignHttpExchanges e de um tipo de chave específico. O DigiCert fornece certificados com essa extensão. Você precisa de um arquivo CSR para emitir um certificado, portanto, gere-o com os seguintes comandos:

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"

Você receberá um arquivo de CSR semelhante a este:

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

Confira se:

  • O período de validade não excede 90 dias.
  • a caixa de seleção Incluir a extensão CanSignHttpExchanges no certificado estiver marcada; que pode ser encontrado em "Outras opções de certificado".
.
A caixa de seleção Incluir a extensão CanSignHttpExchanges no certificado.

Se o certificado não corresponder a essas condições, os navegadores e distribuidores rejeitarão as SXG por motivos de segurança. Este guia presume que o nome de arquivo do certificado que você recebeu da DigiCert é mySxg.pem.

Etapa 2: instalar o libsxg

O formato SXG é complexo e difícil de gerar sem o uso de ferramentas. É possível usar uma das seguintes opções para gerar as SXG:

Este guia usa libsxg.

Opção 1: instalar libsxg usando um pacote Debian

É possível instalar o pacote do jeito normal do Debian, desde que a versão do OpenSSL (libssl-dev) seja correspondente.

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

Opção 2: criar libsxg manualmente

Se você não estiver usando um ambiente compatível com arquivos .deb, crie libsxg por conta própria. Como pré-condição, é necessário instalar git, cmake, openssl e 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

Etapa 3: instalar o plug-in nginx

O plug-in nginx permite que você gere SXG de forma dinâmica em vez de gerá-las estaticamente antes da veiculação.

Opção 1: instalar o plug-in a partir de um pacote Debian

O módulo SXG para nginx (link em inglês) é distribuído no GitHub. Em sistemas baseados em Debian, você pode instalá-lo como um pacote binário:

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

Opção 2: criar plug-in manualmente

A criação do módulo nginx requer o código-fonte nginx. É possível conseguir o tarball e criá-lo junto com o módulo dinâmico SXG usando os comandos abaixo:

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

A configuração de nginx tem grande flexibilidade. Instale o nginx em qualquer lugar do sistema e especifique um caminho respectivo de module/config/log/pidfile. Este guia pressupõe que você o tenha instalado no /opt/nginx.

Etapa 4: configurar o plug-in nginx para funcionar com SXG

Opção 1: configurar um módulo nginx instalado do Debian

Siga estas instruções se você usou a Etapa 3, Opção 1 anteriormente.

O envio de conteúdo SXG requer HTTPS. Você pode receber um certificado SSL/TLS da DigiCert, Let's Encrypt e de outros serviços. Observe que NÃO é possível usar um certificado SXG para SSL ou vice-versa. Portanto, serão necessários dois certificados. O arquivo de configuração em /etc/nginx/nginx.conf será semelhante ao seguinte, supondo que você coloque o par de chave/certificado SSL em /path/to/ssl/ e o par de chave/certificado SXG em /path/to/sxg/:

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;
    }
}
  • O sxg_cert_url é essencial para que os navegadores carreguem as SXG corretamente, porque localiza a cadeia de certificados. A cadeia de certificados contém informações de grampeamento de certificado e OCSP com formato cbor. Não é necessário exibir o arquivo cert.cbor da mesma origem. É possível exibi-lo usando CDNs ou outros serviços de exibição de arquivos estáticos, desde que ele seja compatível com HTTPS.
  • O plano sxg_validitiy_url vai disponibilizar informações relacionadas ao cabeçalho de assinatura SXG. Se uma página não tiver sido modificada desde a última SXG, tecnicamente não é necessário fazer o download do arquivo SXG inteiro. Portanto, apenas a atualização das informações do cabeçalho da assinatura pode reduzir o tráfego de rede. No entanto, os detalhes ainda não foram implementados.

Inicie nginx e tudo estará pronto para exibir as 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)

Opção 2: configurar um módulo nginx criado a partir da origem

Siga estas instruções se você usou a Etapa 3, Opção 2 anteriormente.

Configure o sistema nginx instalado em /opt/nginx para que seja semelhante ao exemplo a seguir:

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

Em seguida, inicie nginx. Agora você pode pegar suas 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)

Etapa 5: disponibilizar o back-end do aplicativo

Nos exemplos acima, nginx exibe arquivos estáticos no diretório raiz, mas é possível usar diretivas upstream para que seus aplicativos façam SXG para back-ends arbitrários de aplicativos da Web (como Ruby on Rails, Django ou Express), desde que seu nginx funcione como um servidor HTTP(S) frontal.

upstream app {
    server 127.0.0.1:8080;
}

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

Etapa 6: teste

Usar a ferramenta Dump-signed Exchange para testar se as SXGs exibidas estão corretas, garantir que nenhum erro seja relatado e verificar se os cabeçalhos e do corpo estão conforme o esperado.

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

Enviar feedback

Os engenheiros do Chromium que trabalham em SXG querem saber sua opinião em webpackage-dev@chromium.org. Você também pode participar da discussão sobre especificações ou informar um bug para a equipe. Seu feedback ajudará muito no processo de padronização e também a resolver problemas de implementação. Obrigada!