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

nginx를 사용하여 SXG 파일을 가져오고 제공하는 방법과 하위 리소스 미리 로드의 문제점

Hiroki Kumazaki
Hiroki Kumazaki

서명된 HTTP 교환 (SXG) 배급자는 원본 콘텐츠 크리에이터를 대신하여 SXG 파일을 전송할 수 있습니다. SXG를 지원하는 웹브라우저는 이러한 SXG 파일을 원본 콘텐츠 크리에이터가 전송한 것처럼 표시합니다. 이렇게 하면 개인 정보를 침해하지 않고 크로스 사이트 미리 로드를 구현할 수 있습니다. 이 가이드에서는 SXG를 올바르게 배포하는 방법을 설명합니다.

교차 브라우저 지원

현재 Chrome만 SXG를 지원하는 브라우저입니다. 최신 정보는 출처 서명 HTTP 교환의 합의 및 표준화 섹션을 참고하세요.

SXG 파일 가져오기

Accept 요청 헤더에서 서버가 요청과 함께 SXG 파일을 반환하도록 지정합니다.

Accept: application/signed-exchange;v=b3,*/*;q=0.8

이 가이드에서는 SXG 파일을 /var/www/sxg에 배치한다고 가정합니다.

간단한 SXG 파일 제공

다음 헤더를 연결하여 단일 SXG 파일을 배포합니다.

Content-Type: application/signed-exchange;v=v3
X-Content-Type-Options: nosniff

nginx을 구성합니다.

http {
    ...
    types {
        application/signed-exchange;v=b3  sxg;
    }
    add_header X-Content-Type-Options nosniff;

    location / {
        more_set_headers "Content-Type: application/signed-exchange;v=b3";
        alias /var/www/sxg/;
        try_files $uri.sxg $uri =404;
        autoindex off;
    }
    ...

새 구성을 nginx에 로드합니다.

sudo systemctl restart nginx.service

nginx에서 SXG 파일을 게재하기 시작합니다. Chrome이 서버에 액세스하면 원래 콘텐츠 게시자의 주소가 바에 표시됩니다.

하위 리소스 미리 가져오기

대부분의 웹페이지는 CSS, JavaScript, 글꼴, 이미지와 같은 여러 하위 리소스로 구성됩니다. 콘텐츠 크리에이터의 비공개 키가 없으면 SXG의 콘텐츠를 변경할 수 없습니다. 이로 인해 브라우저가 하위 리소스를 확인하려고 할 때 문제가 발생합니다.

예를 들어 https://website.test/index.htmlindex.html.sxghttps://website.test/app.js 링크가 있다고 가정해 보겠습니다. 사용자의 브라우저가 https://distributor.test/example.com/index.html.sxg에서 SXG 파일을 수신하면 https://website.test/app.js 링크를 찾습니다. 브라우저는 실제 액세스 시 https://website.test/app.js를 직접 가져올 수 있지만 개인 정보를 보호하기 위해 미리 로드 단계에서 가져와서는 안 됩니다. 리소스가 미리 로드 단계에서 가져온 경우 콘텐츠 크리에이터 (website.test)는 리소스를 요청하는 콘텐츠 배급자 (distributor.test)를 감지할 수 있습니다.

distributor.test/index.html.sxg의 app.js 링크가 website.test/app.js를 가리킵니다.

배급자가 자체 서비스에서 app.js.sxg를 게재하려고 하며 https://website.test/app.js를 배급자의 해당 하위 리소스 버전 (예: https://distributor.test/website.test/app.js.sxg)으로 수정하려고 하면 서명 불일치가 발생하여 SXG가 무효화됩니다.

distributor.test/index.html.sxg의 app.js 참조를 distributor.test/app.js에 연결하려고 하면 서명 불일치가 발생합니다.

이 문제를 해결하기 위해 Chrome에는 실험용 SXG 하위 리소스 미리 로드 기능이 있습니다. about://flags/#enable-sxg-subresource-prefetching에서 사용 설정할 수 있습니다. 하위 리소스 미리 로드를 사용하려면 다음 조건을 충족해야 합니다.

  • 게시자는 SXG에 응답 헤더 항목(예: link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk=")을 삽입해야 합니다. SXG의 특정 무결성 해시로 대체할 수 있는 하위 리소스를 지정합니다.
  • 배포자는 SXG를 게재할 때 link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js"와 같은 응답 헤더를 첨부해야 합니다. 이는 app.js의 경로를 지정하며 하위 리소스에 해당합니다.

앵커

첫 번째 방법은 nginx-sxg-module가 무결성 해시를 계산하고 업스트림 응답의 링크 헤더에 삽입할 수 있으므로 비교적 쉽습니다. 하지만 두 번째 방법은 콘텐츠 배급자가 SXG에서 지정된 하위 리소스를 인식해야 하므로 더 어렵습니다.

https://website.test/app.js 외의 하위 리소스가 없는 경우 nginx 구성에 추가해야 하는 항목은 다음과 같습니다.

add_header link <https://distributor.test/website.test/app.js.sxg>;rel="alter...

하지만 일반적인 웹사이트는 많은 하위 리소스로 구성되어 있으므로 이러한 경우는 드뭅니다. 또한 배급자는 SXG 파일을 게재할 때 적절한 앵커 링크 헤더를 연결해야 합니다. 현재 이 문제를 해결할 수 있는 쉬운 방법은 없으므로 업데이트를 기다려 주세요.

의견 보내기

Chromium 엔지니어는 webpackage-dev@chromium.org에서 SXG 배포에 관한 의견을 기다리고 있습니다. 사양 토론에 참여하거나 팀에 버그를 신고할 수도 있습니다. 보내주신 의견은 표준화 프로세스와 구현 문제를 해결하는 데 큰 도움이 됩니다. 감사합니다.