[잡담] 0-RTT 때문에 오히려 느려질 수 있다? (nginx의 ssl_early_data 설정)
HTTPS로 내용을 암호화하는 웹 통신을 하는 때에는 처음 연결할 때에 보안 인증서를 건네고 무결성을 검증하는 '주고받기(handshake)' 협상 과정을 거친다.
TLS 1.2까지는 첫 연결에 이 협상 과정을 적어도 2-RTT(2 Round Trip Time, 2회 왕복)는 거친다.
- 그림 가저온 곳 : https://commons.wikimedia.org/wiki/File:Tcp-vs-quic-handshake.svg
- 지은이 : Sedrubal
- 저작권 : Creative Commons Attribution-Share Alike 4.0 International
- 그림 가져온 곳 : https://www.keycdn.com/blog/tls-1-3-support
TLS 1.3에서는 이 협상 과정을 1-RTT로 줄였다. 서버와 클라이언트가 이미 TLS 1.3 연결을 맺은 적이 있다면, 다시 연결할 때의 협상 과정을 이른바 0-RTT까지 줄일 수 있다고 한다.
TLS 1.3의 '0-RTT 연결 재시작'은 QUIC 기반 UDP 통신 방식인 HTTP/3(HTTP 3.0)을 쓰는 때에 속도를 더욱 빠르게 하는 기능으로 소개되곤 한다. 아래의 글들에 0-RTT에 관한 설명이 있다.
- QUIC 0-RTT 재시작으로 더 빨리 연결하기 (클라우드플레어 블로그)
- 알아두면 쓸데없는 신비한 TLS 1.3 (Luavis' Dev Story) (마이크로소프트웨어 394호에 실린 글)
0-RTT(Zero Round Trip Time) 연결은 주고받기(핸드셰이크) 과정을 너무 줄인 것에 따르는 보안 문제가 있다. 통신 내용(패킷)을 가로 챈 해커가 암호를 풀지 못해 통신 내용을 알아내지 못하더라도 그 통신 내용을 서버에 그대로 전달하여 같은 처리를 거듭하게 할 수는 있다고 한다.
nginx 서버로 0-RTT 연결을 하려면 서버 설정(nginx.conf)에서 ssl_early_data 설정을 켜야 한다.
ssl_early_data on;
nginx의 ssl_early_data는 기본 설정값이 off여서 이 항목을 따로 넣지 않으면 기능이 꺼진 상태가 된다. (위 항목을 #를 붙여 주석문으로 바꾸어도 ssl_early_data를 끈 상태가 된다.)
막힘 없이 잘 된다면 0-RTT로 웹 연결이 조금이라도 더 빨라져야 맞지만, 실제로 쓸 때에는 다른 요인과 부딪혀 웹 연결 시작이 오히려 늦어지는 경우도 있는 것 같다. 글쓴이가 겪은 경우에는 nginx로 HTTP/3 연결을 가장 단순하게 구성하면 별다른 문제가 없었는데, SELinux를 적용하고 캐시 기능을 붙인 다음에 HTTP/3 첫 연결 시작이 늦는 것을 겪었다. keep-alive 시간 안에 이어지는 연결에서는 문제가 없었지만, keep-alive 시간을 넘어 다시 연결할 때에는 받는 쪽에서 1~3초쯤 전송이 늦게 시작하는 일이 일어났다.
이 문제에 걸리는 때에는 HTTP/3을 쓰는 보람이 없다 싶을 만큼 연결 시작이 오래 걸렸다. SELinux나 캐시 기능을 끄는 것으로는 이 문제를 풀 수 없었고, nginx에서 HTTP/3(HTTP 3.0) 연결을 쓰지 않거나 ssl_early_data를 끄면 전송 시작이 늦는 문제가 사라졌다. 정확한 까닭은 아직 모르지만, keep-alive 상태가 풀린 뒤에 서버 프로그램 요소들 어딘가가 꼬여서 전송을 빨리 시작하지 못하는 것 같다. 젼송이 시작되는 때만 늦고 그 뒤의 과정은 막히거나 늦춰지는 데가 없는 것 같다.
이 문제가 왜 생기는지 궁금하지만, 글쓴이는 0-RTT를 일단 포기했다. 공공 장소에서 와이파이를 쓰는 때처럼 통신이 불안정하거나 끊어지기 쉬운 환경을 생각하면 0-RTT가 탐나는 기능이지만, TLS 1.3의 1-RTT만으로도 개선된 면은 있다. 1-RTT도 효과를 느끼기가 쉽지 않은데, 0-RTT의 효과는 정말 눈꼽만큼일 수 있다. 보안 문제가 있는 것도 생각하면, 아직은 0-RTT에 매달릴 필요는 없는 것 같다.
덧글을 달아 주세요