nginx에서 HTTP/3 설정하기

시작하며

HTTP/1.1에서 HTTP/2로 가는데는 약 16년이 소요되었지만 HTTP/3이 나오는데는 약 7년 정도 소요되었다. 이는 인터넷이 더욱 급격하게 변한다는 반증이기도 하다.

HTTP/1.1에서 HTTP/2로 갈 때에는 TCP 통신에서 발생되는 순차 전송, 오버헤드 등의 문제로 인해서 이를 병렬로 전송함으로서 이를 개선한 버전이다. 그런데 벌써 3이 나왔다니... 이 배경에는 최근의 컨텐츠 시장을 봐야한다.

HTTP/2가 제시된 2015년까지만 하더라도 텍스트와 사진을 중심으로 컨텐츠의 전송이 이루어졌다. 당시에 Facebook이 크게 유행했기 때문이다. 그런데, 최근으로 오면서 YouTube, Netfilx 등 대용량 동영상 통신으로 컨텐츠의 주류가 이동하게 된다. 그러면서 고해상도, HDR, 고 프레임 영상, 360도 영상 등 여러 영상이 뜨게 되면서 트래픽에 대한 부담은 증가한다.

영상 제공 서비스들은 영상을 쪼개서 보관한다. 큰 동영상 전체를 다운로드 받아야만 볼 수 있다면 소비자들은 싫어하기 때문이다. 동영상이 재미 없어서 중간에 끊기라도 한다면 회사 입장에서도 불필요한 트래픽을 발생시킨 것이다.

그런데, 쪼개서 영상을 전송하면 HTTP/2라고 하더라도 TCP의 오버헤드가 발생한다. 이는 큰 데이터를 주고 받는 서비스에서 상대적으로 크게 작용할 수 밖에 없다. 또한 하나의 블록에 문제가 생기면 전체를 다시 받아야하기에 위험이 크다.

하지만 이에 만족할 순 없다. TCP와 UDP의 장점을 합친 QUIC 방식을 이용한 HTTP/3가 나왔다. 이는 TCP로 통신을 하지 않고 UDP만을 이용해 통신하게 된다. 옛날에는 신뢰도가 없다고 사장될 뻔한 UDP인데 화려하게 부활한 것이다.

HTTP/3를 통해서 통신하게 되면, UDP의 Connection ID 단위로 고유성을 구분하며, 한 번의 핸드쉐이크 만으로 데이터를 병렬로 빠르게 전송한다. TCP 특유의 순서 구분 없이 받아오기 때문에 지연이 발생하지 않는다는 장점이 있다.

준비물

  • Nginx 1.25+
  • SSL 인증서
  • 443 TCP, UDP 연결

HTTP/3 부터는 암호화된 통신이 필수이다. SSL 인증서 없이는 진행할 수 없다.

Nginx를 Docker 내부에서 구동하고 있다면, 443/udp를 꼭 활성화해줘야한다. 그냥 "443:443"으로 설정할 경우 TCP만 활성화된다.

Nginx 지원 여부 확인 방법

본인의 Nginx에서 지원하는지 확인하는 방법이다.

nginx -V 2>&1 | grep http_v3_module

상기 명령어를 입력했을 때, 결과 값이 나와야한다. 만일, 나오지 않는다면 별도로 module을 설치해줘야한다.

Nginx 적용 방법

server {
    # UDP 443 포트에서 quic 요청을 받는다.
    # reuseport는 커널 레벨에서 소켓 분산 처리 기능을 활성화한다.
    # reuseport는 하나의 server 블록에서만 사용할 수 있다.
    listen 443 quic reuseport;
    # HTTP/3을 지원하지 않는다면, HTTP/2로 요청을 수락한다.
    listen 443 ssl;
    # 하기는 IPv6의 동일 설정이다.
    listen [::]:443 quic reuseport;
    listen [::]:443 ssl;

    # HTTP/3을 사용하겠다고 활성화한다.
    http3 on;
    # HTTP/2를 사용하겠다고 활성화한다.
    http2 on;

    # Alt-Svc 헤더를 추가하여 Client에 HTTP/3 지원을 알린다.
    add_header Alt-Svc 'h3=":443"; ma=86400' always;
    
    # TLS 1.3의 0-RTT(Zero Round Trip Time) 기능 활성화
    # 접속한 적 있는 서버라면, TLS 핸드셰이크 완료 전에도 데이터를 전송할 수 있게 한다.
    ssl_early_data on;
    # QUIC의 주소 검증 활성화 (DoS 공격 방지)
    quic_retry on;
  }

위의 설정을 추가하면 된다. 정말 간단하다. 설명도 간단하게 주석으로 달았다.

그 다음 nginx -t 명령어로 config를 테스트하고, nginx -s reload 명령을 수행하면 된다.

적용 확인 방법

HTTP/3 Check
Is my site using HTTP3? Check HTTP3 service on any URL. Test QUIC service, too.

여기에서 확인하면 된다.

예제로 구글로 확인했을 때 제대로 지원하고 있음을 알 수 있다.

naver.com은 지원하지 않는 모습을 볼 수 있다.

주의할 점

  • 웹 서버보다 앞단에 무엇인가 설정되어 있다면, HTTP/3이 작동되지 않을 수도 있다.
  • 제일 첫 연결은 HTTP/2로 이루어진 뒤, Header를 읽고 HTTP/3으로 전환되는 경우도 있다.
  • Client에서 광고 차단 VPN 사용 등 네트워크가 특수한 경우에는 HTTP/3으로 통신이 되지 않을 수 있다.
  • Wordpress 등 일부 Web App에서는 문제가 발생할 수 있다.