Ubuntu를 사용하는 NGINX 웹 서버에 HTTP/3 설정하기

Explanation

얼마 전에 네트워크 관련해서 이런저런 공부를 하다가 알게 된 사실인데요.
맙소사.. HTTP/2 버전을 적용한 게 엊그제 같은데, 이제 모던 웹 브라우저들이 HTTP/3 버전을 기본적으로 지원한다고 하더라고요.

그래서 조금 알아보니까 웹 서버도 Apache는 아직 지원하지 않지만, Ubuntu v22.04에서 NGINX는 v1.25.1 메인 라인 버전부터 지원한다고 하더라고요.

절대 안해볼 수 없죠?!

때마침 얼마전에 ubuntu도 22.04버전으로 업데이트 했었는데, 간단하게 NGINX만 업데이트하고 설정 해주면 될 거 같아요! (아마도..)

[참조]
https://www.f5.com/company/blog/nginx/binary-packages-for-preview-nginx-quic-http3-implementation

1. HTTP/3

HTTP/3 버전에 대한 설명을 이야기하려고 했던 것은 아니지만, 간단하게 큰 특징만 알아보자면!

우선, 가장 큰 특징으로 보이는 건, HTTP/3는 이전까지의 TCP 기반이 아닌 UDP 기반의 QUIC 프로토콜을 사용한다고 해요. (QUIC는 구글에서 개발하였다고 해요. 생각해보면 HTTP/2 버전도 구글의 SPDY 구조를 기반으로 표준이 된 걸 생각하면 뭔가 구글이 새삼 더 대단하게 느껴지네요.)

위 이야기와 이어서 TCP를 사용하지 않기 때문에 TCP의 커낵션 과정(3-Way Handshake)가 생략되고, 뿐만 아니라 TCP에서는 HTTPS 통신에서 TCP 커낵션 후에 TLS Hadnshake 과정이 추가로 진행이 되는데 QUIC는 TLS도 v1.3을 기본으로 QUIC Handshake와 TLS Handshake가 동시에 진행을 해서 더 빠르게 진행이 된다고 합니다!

점점 이야기가 새는 느낌인데..

[TLS v1.2 Handshake]
클라이언트(브라우저)가 서버로부터 인증서와 공개 키를 받은 후, 인증서가 신뢰할 수 있는 인증 기관에서 발급한 것인지 검증합니다. 이후 클라이언트는 공개 키를 사용해 세션 키를 암호화하여 서버에 전달하고, 서버는 자신의 개인 키로 세션 키를 복호화합니다. 이후 통신은 이 세션 키를 사용하여 데이터를 암호화하여 주고 받습니다.

[TLS v1.3 Handshake]
클라이언트와 서버는 디피-헬만 키 교환(Diffie–Hellman key exchange)을 사용해 각각 비밀 키와 공개 키를 생성한 후, 서로의 공개 키를 교환합니다. 양측은 전달받은 공개 키와 자신의 비밀 키를 사용하여 세션 키를 생성하고, 이후 통신에서는 이 세션 키를 사용하여 데이터를 암호화하여 주고 받습니다.

요약하면, v1.3 버전은 조금 더 안전하고 절차가 간소화되어 조금이지만 성능이 향상되었습니다.

다시 돌아와서, HTTP/2는 멀티플렉싱으로 여러개의 요청을 동시에 처리할 수 있지만, 기본적으로 TCP 기반이기 때문에 패킷 전송에 손실이 생겼을때 모든 동작을 멈추고 기다려야하는 문제가 있는데(Head of Line Blocking), HTTP/3는 모든 스트림이 독립적으로 동작하기 때문에 다른 스트림에 영향을 주지 않고 빠르게 로딩할 수 있다고 합니다!

HTTP/3 에 대한 이야기는 여기까지만 하고,

2. NGINX 업데이트하기

저는 얼마전에 Ubuntu를 업데이트해서 v22.04를 사용하고 있기 때문에 NGINX를 업데이트 해줄거에요.
우선 기본 패키지 목록에서는 NGINX를 1.25.1 버전 이상으로 설치할 수 없어서 NGINX의 공식 저장소를 추가해줘야합니다.

“/etc/apt/sources.list.d” 디렉토리 안에 “nginx.list” 파일을 만들고 공식 리포지토리 내용을 추가합니다.

다음 아래 커맨드를 입력해서, NGINX 패키지 인증을 위해 GPG 키를 추가합니다.

이제 패키지 목록을 업데이트하고 NGINX를 설치해주면 최신 버전으로 NGINX가 설치됩니다!

사실 어느정도 예상은 하고 있었지만, 역시나…
nginx를 실행 했지만 가상 호스트로 등록한 사이트가 하나도 들어기지지 않았습니다..
그렇게 한참을 해맨 후..

NGINX를 업데이트 하면서 기본 설정에 “include /etc/nginx/sites-enabled/*;”가 사라져서 안된다는 사실을 알았답니다..

NGINX를 정말 너무 오랜만에 설치하긴 했지만..
“include /etc/nginx/sites-enabled/*;” 이 구문이 기본값이 아니였다니…

그리고 추가로 이 블로그는 php 기반이기 때문에 “PHP-FPM”를 사용하는데요. 그러면 NGINX의 user 값을 www-data로 바꿔주어야 합니다.

이렇게 무사히 첫번째 고비를 넘기고..

3. HTTP/3 설정하기

생각보다 HTTP/3 설정은 간단했어요.
가상 호스트 설정으로 가서

가상 호스트에 대한 설명이나 싱크 내용은 생략합니다!
https://falsy.me/ubuntu-환경에-nginxphp7mysql-설치하고-wordpress-이사하기/
위 문서에서 “6. nginx 가상호스트 설정” 부분을 참고해주세요.

끝이에요 간단하죠?!
이제 nginx를 재시작해주고 브라우저로 가서 개발자 도구를 통해 확인을 해보면!

역시, 세상엔 쉬운일이 없습니다.. (아래에 h3은 구글 폰트의 통신입니다.)
이렇게, 저렇게, 많은 삽질 후..

https://log.somni.one/working-with-nginx-http3/

문제의 해답을 찾았습니다.
바보처럼 지금까지 그렇게 HTTP/3 버전은 UDP 기반의 QUIC 프로토콜을 사용하는 것이 가장 큰 특징이라고 말해 놓고 방화벽을 TCP만 열어놔서 안됐던 거 였어요..

저는 AWS를 사용하기 때문에 보안 그룹에 가서 UDP의 443포트를 열어줬어요.


다시 브라우저의 개발자 도구로 확인해보면!!

짠!
이제 이 블로그는 채신기술 HTTP/3를 사용합니다.

인줄 알았으나..

[내용 추가]

4. WordPress

잘 동작하는 줄 알았는데, 웬걸…
블로그가 전면 페이지(https://falsy.me)만 접속이 안되는 문제가 있었답니다.
(캐시 때문에 잘 동작하는 것으로 착각한 거 였어요..)

이게 막 다 안되는 것도 아니고, 블로그의 모든 페이지가 다 HTTP/3 통신에 문제가 하나도 없는데, 전면 페이지만 안되니까 정말 뭔가 문제를 파악하기가 힘들었네요..

이것, 저것 막 알아보다가 기본적으로 OpenSSL을 사용하고 있는데 OpenSSL이 아직 HTTP/3 버전을 완전히 지원하지 않는다는 이야기도 있어서 OpenSSL을 포크떠서 TLS을 지원하는 QuicTLS를 다운로드 받고 NGINX도 따로 패키지로 다운로드 받아서 OpenSSL과 연결된 부분을 QuciTLS로 변경하는 등…

잘 알지도 못하는데.. 하루 종일 삽질을 하다가.. 생각해보니 새로 설치한 NGINX 설정해야 하고 또 별도로 관리할 생각하니까 이게.. 이렇게까지 할 일은 아닌거 같아서, 다시 처음으로 돌아가서 기존의 구성에서 해결하기 위한 방법을 찾던 중!!

https://talk.plesk.com/threads/nginx-http3-cause-invalid-redirect-on-wordpress.374660/

NGINX – HTTP/3 – WordPress 환경에 리다이렉트 문제에 대한 이슈에 대한 글을 찾았답니다!!

만약 NGINX에서 워드프레스를 사용하는 서비스에 HTTP/3 버전을 적용한다면!

가상 호스트 설정에서

주석으로 표시한 부분을 추가하면 모든 페이지에서 정상적으로 HTTP/3 통신이 되는 것을 확인할 수 있었어요.

추가로 HTTP/3 통신을 테스트할 수 있는 사이트도 있더라고요.
https://http3check.net/


짠!

진짜 끝