Skip to content

네트워크 기초 Part 2 — 전송 계층과 TLS ​

마지막 업데이트: 2026년 9월 11일

4부작 시리즈입니다

Part 1: 계층 모델과 링크·라우팅 · Part 2: 전송 계층과 TLS (현재 문서) · Part 3: 애플리케이션 프로토콜 · Part 4: 요청의 여정과 클라우드

Part 1이 패킷을 목적지 호스트까지 보냈다면, 이 파트는 신뢰성 있는 스트림(TCP·QUIC)과 UDP 데이터그램을 비교하고 TLS의 통신 보호를 설명합니다. UDP 자체에는 신뢰성이나 TLS가 내장되어 있지 않습니다. 애플리케이션은 DTLS 같은 적절한 보안 프로토콜을 선택하거나 TLS 1.3을 통합한 QUIC 같은 전송 프로토콜을 사용합니다.

먼저 이 파트의 핵심을 그림 하나로 요약하면 이렇습니다.

일반적인 새 연결에서 TCP와 TLS 1.3 전체 핸드셰이크는 첫 요청까지 약 2 RTT, QUIC은 약 1 RTT가 걸린다. 조건을 충족하는 재개에서는 핸드셰이크 완료 전에 0-RTT 조기 데이터를 전송할 수 있다.

일반적인 새 연결에서 TCP와 TLS 1.3 전체 핸드셰이크는 첫 요청까지 약 2 RTT, QUIC은 약 1 RTT가 걸린다. 조건을 충족하는 재개에서는 핸드셰이크 완료 전에 0-RTT 조기 데이터를 전송할 수 있다.전체 화면으로 열기 ↗

3. 전송 계층 — 종단 간 전달 ​

여기서부터는 "네트워크"가 아니라 "프로세스"가 대화 상대입니다. 포트 번호가 등장하는 이유입니다.

TCP ​

정의: 신뢰성 있는 순차적 바이트 스트림을 제공하는 연결 지향 전송 프로토콜.

동작: 3-way 핸드셰이크(SYN → SYN+ACK → ACK)로 연결을 수립합니다. 시퀀스 번호로 순서를 보장하고, ACK와 재전송으로 손실을 복구하며, 슬라이딩 윈도우로 흐름을 제어하고, 혼잡 제어 알고리즘으로 네트워크 부하에 적응합니다. 애플리케이션에게는 "빈틈없이 이어지는 바이트 흐름"이라는 깔끔한 추상화를 제공합니다.

실무 포인트: 순서대로 전달하기 때문에 HOL(Head-of-Line) 블로킹이 발생합니다. TCP 세그먼트가 누락되면 빈 구간 뒤의 바이트를 전달할 수 없습니다. HTTP/2에서는 같은 연결의 여러 스트림 전달이 지연될 수 있지만, 이미 전달된 데이터와 독립적인 애플리케이션 작업까지 모두 멈추는 것은 아닙니다. QUIC은 이처럼 스트림 간에 공유하는 전송 계층의 순서 의존성을 제거합니다.

최적화를 사용하지 않는 일반적인 새 연결은 TCP 수립에 약 1 RTT, 이어서 TLS 1.3 전체 핸드셰이크에 1 RTT(TLS 1.2는 보통 2 RTT)가 필요합니다. 연결 재사용, 세션 재개, 조기 데이터, TCP Fast Open에 따라 달라지고 재시도는 지연을 추가할 수 있습니다. 실제 워크로드를 기준으로 커넥션 풀을 평가해야 합니다.

혼잡 제어의 계보: 혼잡 제어는 대역폭·지연·버퍼·애플리케이션 동작과 함께 처리량에 영향을 줍니다. 고전 Reno는 손실 시 혼잡 윈도를 줄입니다. 리눅스에서 흔히 기본값으로 사용하는 CUBIC은 3차 함수 기반 윈도 증가로 고대역폭 경로의 확장성을 개선합니다. BBR은 병목 대역폭과 전파 RTT를 모델링해 전송을 조절하며, 손실·ECN을 사용하는 방식은 구현과 버전에 따라 다릅니다. 장거리·모바일 경로에서 항상 더 높은 처리량을 보장하지는 않습니다. sysctl net.ipv4.tcp_congestion_control은 설정된 기본값을 조회하는 명령입니다. 기본값 변경은 새 연결에 적용되며 별도의 설정과 측정이 필요합니다.

TIME_WAIT와 포트 고갈: 정상적인 순차 종료에서는 일반적으로 능동 종료 측이 TIME_WAIT에 들어가고, 동시 종료에서는 양쪽 모두 들어갈 수 있습니다. 짧은 연결을 대량 생성하면 구현과 목적지 패턴에 따라 연결 튜플·임시 포트·NAT 매핑 한도가 부족해질 수 있습니다. TIME_WAIT 항목 하나가 모든 원격 목적지에 대해 해당 포트를 항상 독점하는 것은 아닙니다. 실제 고갈 지점을 확인하고 커널 설정 변경 전에 연결 재사용을 검토하세요. TIME_WAIT는 이전 연결의 지연 패킷으로부터 새 연결을 보호하는 역할도 합니다.

UDP ​

정의: 연결 설정 없이 데이터그램을 보내는 최소 기능 전송 프로토콜.

동작: 헤더 8바이트에 출발지 포트, 목적지 포트, 길이, 체크섬만 있습니다. 핸드셰이크 없음, 재전송 없음, 순서 보장 없음, 혼잡 제어 없음. "IP에 포트 번호만 붙인 것"에 가깝습니다.

실무 포인트: 실시간 애플리케이션은 오래된 데이터를 재전송하기보다 제때 전달하는 것을 우선할 수 있고, DNS도 작은 교환에 UDP를 흔히 사용합니다. 필요한 신뢰성과 적절한 혼잡 제어는 애플리케이션이 구현하거나 QUIC처럼 이를 제공하는 프로토콜을 사용해야 합니다.

주의할 점은 상태가 없어서 스푸핑과 증폭 공격에 쓰이기 쉽다는 것입니다. UDP 기반 서비스를 외부에 노출할 때는 응답 크기 제한과 요청량 제어를 함께 고려해야 합니다.

QUIC ​

정의: UDP 위에 구현된, 보안이 내장된 다중화 전송 프로토콜.

동작: TCP+TLS가 하던 일을 UDP 위에서 처음부터 다시 설계했습니다. 핵심 특징 네 가지입니다.

  1. 스트림별 독립 전달 — 각 스트림에 별도의 바이트 순서가 있어 한 스트림의 손실이 다른 스트림의 도착한 데이터 전달을 반드시 막지는 않습니다. 패킷 복구와 혼잡 제어는 여전히 연결·경로에서 공유합니다. 각 스트림의 누락 바이트, 애플리케이션 의존성, HTTP/3 QPACK 의존성으로 인한 블로킹도 남습니다.
  2. 암호화 내장 — QUIC은 TLS 1.3 핸드셰이크를 통합하고 TLS 레코드 대신 자체 패킷 보호를 사용합니다. 일반적인 전체 핸드셰이크는 약 1 RTT입니다. 조건을 충족하고 서버가 수락한 재개에서는 0-RTT 조기 데이터를 보낼 수 있지만 핸드셰이크 완료는 그 이후입니다. Retry나 추가 핸드셰이크 교환은 지연을 늘릴 수 있습니다.
  3. 연결 ID — 경로 검증과 양 끝점의 지원을 통해 주소 변경 후 연결을 이어갈 수 있습니다. 마이그레이션 제한이나 경로 단절이 있으면 Wi-Fi에서 셀룰러로 전환할 때도 연결이 끊길 수 있으므로 무중단을 보장하지 않습니다.
  4. 구현의 유연성 — 사용자 공간 구현이 흔하므로 애플리케이션·라이브러리와 함께 전송 계층 개선을 배포할 수 있습니다. 사용자 공간에서 구현해야 한다는 프로토콜 요구사항은 아닙니다.

실무 포인트: HTTP/3은 보통 UDP 443을 사용합니다. 이 경로가 차단되면 HTTP 클라이언트가 서버 지원 여부에 따라 TCP 기반 HTTP/2 또는 HTTP/1.1을 시도할 수 있습니다. QUIC 자체가 TCP로 바뀌는 것은 아닙니다. 성능 차이를 QUIC 때문이라고 판단하기 전에 경로 도달성·협상된 프로토콜·구현과 오프로드 동작을 확인하세요. CPU 비용은 구현과 워크로드에 따라 달라집니다.

한 가지 보안 주의점: 0-RTT 데이터는 재생(replay)될 수 있습니다. 조기 데이터 교환을 재생하면 애플리케이션이 요청을 여러 번 처리할 수 있으며, 전송 계층의 패킷 중복 제거만으로 애플리케이션 재생 방지가 보장되지는 않습니다. 애플리케이션이 재생되어도 안전하다고 명시적으로 평가한 작업만 허용하세요. GET이라는 이름이나 멱등성 주장만으로 충분하지 않습니다. 서버는 조기 데이터를 거부할 수 있고, HTTP 서버는 425 Too Early로 응답해 클라이언트가 핸드셰이크 후 재시도하게 할 수 있습니다. 클라이언트·CDN·원본 서버에 걸쳐 정책을 맞추어야 합니다.


4. 보안 — TLS ​

TLS ​

정의: 전송 구간의 기밀성, 무결성, 인증을 제공하는 프로토콜.

동작: 핸드셰이크에서 암호 매개변수를 협상하고 키를 설정합니다. 인증서 기반 핸드셰이크는 인증서와 키 소유 증명을 통해 서버를 인증하지만, PSK 기반 핸드셰이크는 이전에 설정했거나 외부에서 제공한 키로 인증할 수도 있습니다. TLS 레코드는 애플리케이션 데이터를 보호합니다. TLS 1.3은 인증된 암호화(AEAD)로 기밀성과 무결성을 제공합니다.

일반적인 TLS 1.3 전체 핸드셰이크는 약 1 RTT이며, 재개 시에는 추가 조건하에서 조기 데이터를 선택적으로 사용할 수 있습니다. 정적 RSA 키 교환과 구형 암호 스위트는 제거됐지만 RSA 인증서 서명은 계속 지원합니다. 임시 (EC)DHE 키 교환은 PSK와 결합할 때도 전방 비밀성을 제공합니다. PSK 단독 키 교환과 0-RTT 데이터에는 동일한 전방 비밀성 보장이 없습니다.

실무 포인트: 세 가지가 반복적으로 문제가 됩니다.

  • 인증서 만료 — 갱신을 자동화하고 만료 시점과 실제 인증서 배포 성공 여부를 별도로 모니터링하세요.
  • SNI 노출 — TLS 1.3만으로는 ClientHello의 SNI가 숨겨지지 않습니다. 양 끝점에서 지원·설정한 ECH(Encrypted Client Hello, RFC 9849)는 내부 ClientHello를 보호할 수 있습니다. QUIC Initial 패킷의 키는 공개 정보로 유도할 수 있어 Initial 암호화만으로 SNI를 숨기지 못합니다. ECH도 목적지 IP나 모든 트래픽 메타데이터까지 숨기지는 않습니다.
  • 종료 지점 설계 — 클라이언트→로드밸런서, 로드밸런서→애플리케이션, 서비스 간 연결을 각각 명시하세요. TLS 종료가 다음 구간을 자동으로 암호화하지는 않습니다. 필요한 구간에는 TLS를 사용하고, 양쪽을 인증서로 인증해야 한다면 mTLS를 사용합니다. 서비스 메시로 자동화할 수 있지만 모든 설계에 필수인 것은 아닙니다.

인증서 체인과 OCSP 스테이플링: 일반적인 X.509 검증은 말단 인증서에서 필요한 중간 인증서를 거쳐 설정된 신뢰 앵커까지 경로를 구성합니다. 서버는 필요한 중간 인증서를 보내야 하고, 루트는 보통 클라이언트가 이미 신뢰합니다. 중간 인증서를 빠뜨리면 클라이언트에 따라 실패할 수 있지만 모든 유효한 체인에 중간 인증서가 있는 것은 아닙니다. 폐기 확인은 발급기관과 클라이언트에 따라 다릅니다. OCSP를 지원하면 서버가 서명된 상태 응답을 첨부하는 스테이플링으로 클라이언트의 직접 조회를 줄일 수 있습니다. 보편적인 필수 방식은 아닙니다. Let’s Encrypt는 2025년 8월 OCSP 서비스를 종료하고 CRL을 사용합니다. 실제 CA와 클라이언트에 맞춰 인증서·폐기 확인을 설정하세요.

📎 Istio가 이를 자동화하는 방식은 Istio mTLS 참고.

공식 참고 자료: TLS 1.3, QUIC transport, QUIC/TLS, HTTP early data, ECH, Linux TCP settings, Let’s Encrypt OCSP retirement. ​

다음: Part 3: 애플리케이션 프로토콜