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

nginx를 사용하여 SXG 파일을 가져오고 제공하는 방법과 하위 리소스 미리 가져오기의 문제를 알아봅니다.

쿠마자키 히로키
히로키 쿠마자키

서명된 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, 자바스크립트, 글꼴, 이미지와 같은 여러 하위 리소스로 구성됩니다. 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)를 감지할 수 있습니다.

Distribution.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가 무효화됩니다.

Distribution.test/index.html.sxg에 있는 app.js에 대한 참조를 Distribution.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 배포에 관한 의견을 기다리고 있습니다. 사양 토론에 참여하거나 팀에 버그를 신고할 수도 있습니다. 보내주신 의견은 표준화 프로세스와 구현 문제 해결에 큰 도움이 됩니다. 감사합니다.