nginx를 사용하여 서명된 HTTP 교환 (SXG)을 설정하는 방법

SXG 확장 프로그램으로 TLS 인증서를 생성하고, SXG 파일 생성을 위한 도구를 설치하며, SXG 파일을 제공하도록 nginx를 구성하는 방법을 알아봅니다.

Hiroki Kumazaki
Hiroki Kumazaki

서명된 HTTP 교환 (SXG)은 사용자가 콘텐츠 제작자와 콘텐츠 배급사를 더 쉽게 구분할 수 있게 해주는 새로운 웹 기술입니다. 이 가이드에서는 SXG를 설정하는 방법을 보여줍니다.

교차 브라우저 지원

Google Chrome, Samsung Internet, Microsoft Edge 등 일부 Chromium 기반 브라우저에서 SXG를 지원합니다. 자세한 내용은 출처 서명 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 파일이 필요하므로 다음 명령어를 사용하여 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를 직접 빌드할 수 있습니다. 전제 조건으로 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.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 인증서는 사용할 수 없으므로 두 개의 인증서가 필요합니다. 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) 서버로 작동하는 한 애플리케이션의 업스트림 지시문을 사용하여 임의의 웹 애플리케이션 백엔드(예: Ruby on 레일즈, 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를 통해 여러분의 의견을 기다리고 있습니다. 사양 토론에 참여하거나 팀에 버그를 신고할 수도 있습니다. 보내주신 의견은 표준화 프로세스와 구현 문제 해결에 큰 도움이 됩니다. 감사합니다