1. Bibliotheek
  2. TCP와 UDP
  3. TCP 심층 분석

Bijgewerkt 1 maand geleden

처음 만나는 사람과는 악수를 먼저 합니다. TCP Fast Open은 이렇게 묻습니다: 어제 이미 만난 사람과 왜 또 악수를 해야 할까요?

모든 TCP 연결은 세 번의 핸드셰이크로 시작됩니다: SYN, SYN-ACK, ACK. 그 이후에야 클라이언트는 실제 요청을 보낼 수 있습니다. 이 핸드셰이크는 혼란을 막기 위해 존재합니다—양측이 시퀀스 번호에 합의하고 통신할 준비가 되었음을 확인하는 것입니다. 하지만 유용한 데이터가 오가기 전에 한 번의 왕복 시간(RTT)이 고스란히 소모됩니다.

뉴욕과 싱가포르 간의 연결이라면 250밀리초를 기다려야 합니다. 수십 번의 API 호출을 하는 모바일 사용자에게는 수천 번의 핸드셰이크에 서서히 지쳐가는 꼴입니다. 짧게 끝나는 연결이 가장 큰 피해를 입습니다: 전체 트랜잭션이 100ms밖에 걸리지 않는다면, 그 절반을 이런 형식에 쓴다는 건 낭비처럼 느껴집니다.

기억하는 쿠키

TCP Fast Open은 간단한 통찰로 이 문제를 해결합니다: 서버가 이 클라이언트를 이전에 본 적이 있고 신뢰한다면, 기다림을 건너뜁니다.

첫 번째 연결에서 클라이언트는 SYN 패킷에 특별한 옵션을 포함시켜 TFO 쿠키를 요청합니다. 서버는 클라이언트의 IP 주소에 연결된 암호화 토큰을 생성하여 SYN-ACK에 담아 반환합니다. 클라이언트는 이 쿠키를 캐시합니다.

이후 연결에서 클라이언트는 두 가지를 첨부하여 SYN 패킷을 보냅니다: 캐시된 쿠키와 실제로 전송하려는 데이터(보통 HTTP 요청)입니다. 서버는 쿠키를 검증하고—일치하면 즉시 데이터를 처리하여 SYN-ACK에 응답을 담아 보냅니다.

결과: 클라이언트는 전통적인 TCP보다 한 RTT 일찍 데이터를 받습니다. 뉴욕-싱가포르 연결이라면 250ms의 지연 시간을 통째로 없앤 셈입니다.

쿠키가 유효하지 않거나 서버가 TFO를 지원하지 않으면, 모든 것은 자연스럽게 표준 핸드셰이크로 돌아갑니다. 문제될 것이 없습니다.

보안이 복잡해지는 이유

SYN 패킷에 데이터를 허용하면 증폭 공격의 빌미가 생깁니다. 공격자는 피해자의 IP 주소를 위장하여 TFO가 활성화된 서버에 데이터가 담긴 SYN 패킷을 보냅니다. 서버들의 응답이 피해자에게 원하지도 않은 트래픽을 쏟아붓게 됩니다.

구현체들은 TFO 데이터 크기를 제한하여(RFC 7413은 기본값으로 IPv4에 536바이트, IPv6에 1220바이트를 명시합니다)1, 의심스러운 출처의 연결에 속도 제한을 걸고, 추적을 방지하기 위해 주기적으로 쿠키를 교체함으로써 이에 대응합니다. 애플리케이션도 멱등성을 보장해야 합니다—SYN 패킷이 재전송되더라도 같은 요청을 두 번 처리하는 것이 문제가 되지 않아야 합니다. 이는 POST가 아닌 GET 요청에만 TFO를 활성화해야 한다는 것을 의미합니다.

미들박스 문제

TCP Fast Open은 2014년부터 존재해 왔습니다. Linux, macOS, iOS, Windows 모두 지원합니다. nginx와 Apache 같은 주요 웹 서버도 지원합니다. 그러나 브라우저들은 TFO를 대부분 포기했습니다.

Chrome은 활성화했다가 비활성화했습니다. Firefox는 실험했다가 버전 87에서 지원을 완전히 제거했습니다2. 원인은 미들박스입니다.

방화벽, 로드 밸런서, 네트워크 어플라이언스가 클라이언트와 서버 사이에 자리 잡고 TCP 트래픽을 검사합니다. 이 장치들 중 상당수가 TFO가 등장하기 전에 만들어졌습니다. SYN 패킷에 데이터가 있는 것을 보면—전통적인 TCP에서는 절대 없는 일—혼란에 빠집니다. 어떤 것은 연결을 끊습니다. 어떤 것은 데이터를 제거합니다. 어떤 것은 패킷을 손상시킵니다.

완벽한 최적화를 구현했더라도, 2008년산 기업용 방화벽이 그것을 망가뜨린다면 사용자들은 방화벽이 아닌 브라우저를 탓합니다.

TFO가 실제로 도움이 되는 곳

배포 환경이 녹록지 않더라도, TFO는 통제된 환경에서 실질적인 가치를 발휘합니다:

모바일 API: 지연 시간이 높고, 짧은 요청이 많으며, 클라이언트와 서버를 모두 제어합니다. 핸드셰이크 오버헤드를 없애면 응답성이 눈에 띄게 향상됩니다.

지리적으로 분산된 서비스: RTT가 200ms 이상일 때, 그 왕복 하나를 아끼는 것이 중요합니다. 호주 사용자가 유럽 서버에 연결할 때 차이를 체감합니다.

내부 서비스: 자체 인프라 내에서는 미들박스의 간섭이 없도록 보장할 수 있습니다. 서비스 간 통신에서 TFO를 안전하게 활성화할 수 있습니다.

장기 연결은 이점이 거의 없습니다—핸드셰이크 비용을 한 번 지불하고 나면, 수 분에 걸쳐 메가바이트를 전송할 때 그 초기 비용은 무시할 만합니다. 커넥션 풀링과 HTTP/2의 멀티플렉싱은 다른 방법으로 비슷한 목표를 달성합니다.

더 큰 그림

TCP Fast Open은 인터넷 발전의 한 패턴을 보여줍니다: 기술적으로는 탄탄한 최적화지만 기존 설치 기반의 벽에 부딪히는 경우입니다. 프로토콜은 작동합니다. 수학도 맞습니다. 하지만 인터넷은 깨끗한 백지가 아닙니다—레거시 장치, 기업 정책, 예기치 않은 상호작용이 켜켜이 쌓인 구조입니다.

HTTP/3의 기반 프로토콜인 QUIC은 UDP 위에서 실행되며 자체적인 연결 수립을 처리함으로써 이 문제를 다르게 해결합니다. 미들박스 문제를 완전히 피하면서 제로-RTT 연결 재개를 달성합니다—대부분의 네트워크 장치는 UDP를 검사 없이 통과시킵니다. (하지만 QUIC의 0-RTT는 재생 공격에 대한 자체적인 우려가 있어, 같은 멱등성 보장이 필요합니다.)3

현재로서는 TFO가 제어 가능한 환경에서 여전히 가치 있습니다. 핸드셰이크 비용은 실재하며, 그것을 없애는 것은 중요합니다. TFO든, QUIC이든, 다음에 무엇이 오든, 목표는 하나입니다: 클라이언트가 말할 차례를 기다리게 하는 것, 이제는 그럴 이유가 없습니다.

TCP Fast Open에 대한 자주 묻는 질문

TCP Fast Open은 HTTPS와 함께 작동하나요?

네. TFO는 TLS 아래의 TCP 계층에서 작동합니다. 초기 SYN 패킷에 전송되는 데이터는 보통 암호화 핸드셰이크를 시작하는 TLS ClientHello입니다. TFO는 TCP 연결에서 한 RTT를 절약할 수 있지만, 그 이후에도 TLS 핸드셰이크가 필요합니다. TLS 1.3의 줄어든 왕복과 결합하면, 절약 효과가 더욱 배가됩니다.

브라우저는 왜 TCP Fast Open을 기본으로 활성화하지 않나요?

미들박스 간섭 때문입니다. 너무 많은 방화벽과 네트워크 어플라이언스가 TFO 패킷을 잘못 처리하여 연결 실패를 유발합니다. 브라우저는 성능보다 안정성을 우선시합니다—느리게 로드되는 페이지가 아예 로드되지 않는 것보다는 낫습니다. Firefox는 수년간의 호환성 문제 끝에 TFO 지원을 완전히 제거했습니다.

TCP Fast Open은 QUIC의 0-RTT와 어떻게 다른가요?

둘 다 재방문 클라이언트의 핸드셰이크 지연을 없애지만, 서로 다른 계층에서 작동합니다. TFO는 TCP의 핸드셰이크를 수정하는 반면, QUIC은 자체 연결 프로토콜을 갖춘 UDP 위에서 실행됩니다. QUIC의 접근 방식은 대부분의 장치가 UDP를 검사하지 않아 미들박스 문제를 피합니다. 하지만 QUIC의 0-RTT도 비슷한 재생 우려가 있습니다—RFC 9000은 "0-RTT는 재생 공격에 대한 보호를 제공하지 않는다"고 명시하며—같은 멱등성 보장이 필요합니다.

TCP Fast Open은 어떤 애플리케이션과도 사용할 수 있나요?

기술적으로는 가능하지만, 안전하게는 멱등성이 보장된 요청에만 사용해야 합니다. TFO 데이터는 패킷이 재전송될 경우 재생될 수 있으므로, 같은 요청을 여러 번 받아도 문제없이 처리할 수 있어야 합니다. 이 때문에 TFO는 읽기 작업(GET, HEAD)에는 적합하지만, 추가 안전장치 없이 상태를 변경하는 작업(POST, DELETE)에는 위험합니다.

출처

Was deze pagina nuttig?

😔
🤨
😃