웹 취약점 공격 방법인 XSS, CSRF에 대하여 간단하게 알아보기
Ubuntu를 사용하는 NGINX 웹 서버에 HTTP/3 설정하기
2024-09-27
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
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 에 대한 이야기는 여기까지만 하고,
저는 얼마전에 Ubuntu를 업데이트해서 v22.04를 사용하고 있기 때문에 NGINX를 업데이트 해줄거에요.
우선 기본 패키지 목록에서는 NGINX를 1.25.1 버전 이상으로 설치할 수 없어서 NGINX의 공식 저장소를 추가해줘야합니다.
1 |
$ vi /etc/apt/sources.list.d/nginx.list |
“/etc/apt/sources.list.d” 디렉토리 안에 “nginx.list” 파일을 만들고 공식 리포지토리 내용을 추가합니다.
1 2 |
deb http://nginx.org/packages/ubuntu/ jammy nginx deb-src http://nginx.org/packages/ubuntu/ jammy nginx |
다음 아래 커맨드를 입력해서, NGINX 패키지 인증을 위해 GPG 키를 추가합니다.
1 |
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo tee /etc/apt/trusted.gpg.d/nginx_signing.asc |
이제 패키지 목록을 업데이트하고 NGINX를 설치해주면 최신 버전으로 NGINX가 설치됩니다!
1 2 3 4 5 |
$ sudo apt update $ sudo apt install nginx $ nginx -v # nginx version: nginx/1.26.2 |
사실 어느정도 예상은 하고 있었지만, 역시나…
nginx를 실행 했지만 가상 호스트로 등록한 사이트가 하나도 들어기지지 않았습니다..
그렇게 한참을 해맨 후..
NGINX를 업데이트 하면서 기본 설정에 “include /etc/nginx/sites-enabled/*;”가 사라져서 안된다는 사실을 알았답니다..
1 |
$ vi /etc/nginx/nginx.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; #추가한 내용 } |
NGINX를 정말 너무 오랜만에 설치하긴 했지만..
“include /etc/nginx/sites-enabled/*;” 이 구문이 기본값이 아니였다니…
그리고 추가로 이 블로그는 php 기반이기 때문에 “PHP-FPM”를 사용하는데요. 그러면 NGINX의 user 값을 www-data로 바꿔주어야 합니다.
1 |
$ vi /etc/nginx/nginx.conf |
1 2 |
user www-data; # 초기값은 nginx 였습니다. ... |
이렇게 무사히 첫번째 고비를 넘기고..
생각보다 HTTP/3 설정은 간단했어요.
가상 호스트 설정으로 가서
1 |
$ vi /etc/nginx/sites-available/falsy |
가상 호스트에 대한 설명이나 싱크 내용은 생략합니다!
https://falsy.me/ubuntu-환경에-nginxphp7mysql-설치하고-wordpress-이사하기/
위 문서에서 “6. nginx 가상호스트 설정” 부분을 참고해주세요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
server { server_name falsy.me; ... listen 443 ssl; http2 on; # 여기부터 아래로 새로 추가된 내용입니다. listen 443 quic reuseport; # HTTP/3 settings add_header Alt-Svc 'h3-23=":443"; ma=86400'; # HTTP/3-23 (Draft) add_header Alt-Svc 'h3-29=":443"; ma=86400'; # HTTP/3-29 (Latest Draft) add_header Alt-Svc 'h3="443"; ma=86400'; # signal whether we are using QUIC+HTTP/3 add_header X-protocol $server_protocol always; # QUIC and HTTP/3 configuration ssl_protocols TLSv1.3; } |
끝이에요 간단하죠?!
이제 nginx를 재시작해주고 브라우저로 가서 개발자 도구를 통해 확인을 해보면!
1 |
$ sudo systemctl restart nginx |
역시, 세상엔 쉬운일이 없습니다.. (아래에 h3은 구글 폰트의 통신입니다.)
이렇게, 저렇게, 많은 삽질 후..
https://log.somni.one/working-with-nginx-http3/
문제의 해답을 찾았습니다.
바보처럼 지금까지 그렇게 HTTP/3 버전은 UDP 기반의 QUIC 프로토콜을 사용하는 것이 가장 큰 특징이라고 말해 놓고 방화벽을 TCP만 열어놔서 안됐던 거 였어요..
저는 AWS를 사용하기 때문에 보안 그룹에 가서 UDP의 443포트를 열어줬어요.
다시 브라우저의 개발자 도구로 확인해보면!!
짠!
이제 이 블로그는 채신기술 HTTP/3를 사용합니다.
인줄 알았으나..
[내용 추가]
잘 동작하는 줄 알았는데, 웬걸…
블로그가 전면 페이지(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 버전을 적용한다면!
1 |
$ vi /etc/nginx/sites-available/falsy |
가상 호스트 설정에서
1 2 3 4 5 6 7 8 9 10 |
server { server_name falsy.me; ... location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_param HTTP_HOST $host; # 추가한 부분 fastcgi_pass unix:/run/php/php7.4-fpm.sock; } |
주석으로 표시한 부분을 추가하면 모든 페이지에서 정상적으로 HTTP/3 통신이 되는 것을 확인할 수 있었어요.
추가로 HTTP/3 통신을 테스트할 수 있는 사이트도 있더라고요.
https://http3check.net/
짠!