📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 38편
이전 글: 37. Traceroute의 동작 원리 · 다음 글: 39. UDP란 무엇인가
TCP(Transmission Control Protocol)는 전송 계층 프로토콜로, IP 헤더의 Protocol 번호 6을 사용합니다. 현재 기준 명세는 RFC 9293(2022)이며, 이는 오랫동안 쓰인 RFC 793을 대체했습니다.
IP는 패킷을 "최선을 다해(Best Effort)" 보낼 뿐, 유실·중복·순서 뒤바뀜을 책임지지 않습니다. TCP는 그 위에서 양 끝 호스트끼리 약속을 맺어 애플리케이션에게 "빠짐없이, 순서대로 도착하는 바이트 흐름"을 제공합니다.
| TCP가 제공하는 것 | 한 줄 설명 | 자세히 다루는 글 |
|---|---|---|
| 연결 지향 | 데이터 전에 연결을 수립하고, 끝나면 해제 | 41. TCP 3-Way Handshake — 연결이 성립했다는 증거, 42. TCP 상태 전이 — LISTEN부터 TIME_WAIT까지 |
| 신뢰성 | 받은 만큼 ACK, 못 받으면 재전송 | 46. 시퀀스 번호·ACK·윈도우 — TCP가 데이터를 빠짐없이 전달하는 방법 |
| 순서 보장 | 시퀀스 번호로 재정렬 | 46편 |
| 흐름 제어 | 수신 측 윈도우만큼만 전송 | 46편 |
| 혼잡 제어 | 네트워크가 막히면 전송 속도를 스스로 줄임 | (이 글에서 개념만) |
| 전이중(Full Duplex) | 한 연결에서 양방향 동시 전송 | — |
헤더 필드와 UDP와의 구조 비교는 40. TCP와 UDP 헤더 비교 — 신뢰성과 속도의 차이에서 다룹니다. 이 글은 "TCP가 어떤 약속을 하는 프로토콜인가"라는 큰 그림에 집중합니다.
TCP 연결의 생애는 세 구간으로 나뉩니다.
클라이언트 (192.168.10.10:51000) 서버 (192.168.10.20:22)
│ │ LISTEN
│ ──────────── ① 연결 수립 (SYN, SYN/ACK, ACK) ────→ │
│ ESTABLISHED │ ESTABLISHED
│ │
│ ── 데이터(seq) ─────────────────────────────────→ │
│ ←───────────────────────────── ACK(다음 받을 번호) │ ② 데이터 전송
│ ←──────────────────────────────────── 데이터(seq) │ - 유실 시 재전송
│ ── ACK ─────────────────────────────────────────→ │ - 윈도우로 속도 조절
│ │
│ ──────────── ③ 연결 해제 (FIN/ACK 교환 또는 RST) ─→ │
↓ ↓
이 과정에서 중요한 성질이 있습니다.
출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트의 조합이 같으면 같은 연결입니다. 여기에 프로토콜(TCP)을 더한 것이 로그에서 자주 쓰는 5-tuple입니다.신뢰성의 대가는 추가 패킷과 지연입니다. 연결 수립에 1번의 왕복(RTT)이 들고, 데이터마다 ACK가 오가며, 손실이 나면 재전송을 기다려야 합니다. 그래서 TCP는 "빠른 것"보다 "정확한 것"이 중요한 서비스에 쓰입니다.
| 대표 서비스 | 포트 | TCP를 쓰는 이유 |
|---|---|---|
| HTTP / HTTPS | 80 / 443 | 웹 페이지·파일이 한 바이트도 빠지면 안 됨 |
| SSH | 22 | 명령·응답 순서가 중요 |
| SMTP / IMAP | 25 / 143 | 메일 본문 무결성 |
| SMB | 445 | 파일 공유 |
| RDP | 3389 | 세션 제어 (환경에 따라 UDP도 병행) |
| DB (MySQL 등) | 3306 등 | 질의·결과 정확성 |
포트별 서비스 분석은 02. 포트 · 프로토콜 분석 영역에서 다룹니다. 혼잡 제어는 네트워크 상태를 보고 한 번에 보낼 양(혼잡 윈도우)을 늘리거나 줄이는 기능으로, 수신 측이 정하는 흐름 제어 윈도우와는 별개입니다.
TCP의 성질은 보안 관점에서 양면성을 갖습니다.
| 성질 | 방어에 유리한 점 | 악용·부담이 되는 점 |
|---|---|---|
| 연결 수립 필요 | 출발지 IP를 위조하면 응답을 받지 못해 연결을 완성하기 어려움 | 수립 단계의 자원(대기열)을 노리는 SYN Flood |
| 상태 유지 | 방화벽이 "성립된 연결의 응답"만 통과시키는 상태 기반 정책 가능 | 상태 테이블이 가득 차는 자원 고갈 |
| 명확한 시작·끝 | 세션 단위로 바이트·지속 시간을 기록할 수 있음 | 장시간 유지되는 세션이 C2 통신에 쓰일 수 있음 |
실습 예시 — 본인 소유 Linux VM(Rocky/Ubuntu 공통, ss는 iproute2에 포함)에서 TCP 연결을 4-tuple 단위로 확인합니다.
# LISTEN 중인 TCP 소켓 (-t TCP, -l LISTEN, -n 숫자 표시)
ss -tln
# 현재 성립된 TCP 연결 (4-tuple 확인)
ss -tn state established
# 연결별 내부 정보(RTT, 혼잡 윈도우 등) 함께 보기
ss -tni state established
출력 형식 예시(값은 환경마다 다름):
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 192.168.10.20:22 192.168.10.10:51000
0 0 192.168.10.20:22 192.168.10.10:51002
cubic wscale:7,7 rto:204 rtt:0.52/0.2 cwnd:10 ...
| 출력 요소 | 읽는 법 |
|---|---|
192.168.10.20:22 ↔ 192.168.10.10:51000 | 하나의 4-tuple = 하나의 연결 |
| 같은 서버 포트, 다른 클라이언트 포트 | 같은 클라이언트의 별개 연결 2개 |
cubic | 사용 중인 혼잡 제어 알고리즘 (Linux 기본값인 경우가 많음) |
rtt, cwnd | 측정된 왕복 시간, 혼잡 윈도우 크기 |
TCP는 연결 단위로 시작과 끝이 있어 세션 요약 로그를 만들기 좋습니다.
| 흔적 위치 | 확인할 수 있는 것 |
|---|---|
| 방화벽 세션 로그 | 5-tuple, 시작·종료 시각, 송수신 바이트, 종료 사유 |
NetFlow·Zeek conn.log 등 | 세션별 누적 플래그 또는 conn_state(예: S0 응답 없음, REJ 거부, SF 정상 성립·종료) |
호스트 (ss, netstat) | 현재 연결과 프로세스 매핑 (휘발성) |
| IDS/IPS | 재조립된 TCP 스트림 기준의 시그니처 탐지 |
관제자가 확인할 질문
오탐 주의: 방화벽 allow 로그는 연결 성립을 보장하지 않으며, 짧고 바이트가 적은 세션은 헬스체크·포트 모니터링일 수 있습니다. 장시간 세션도 DB 연결 풀, VPN, 메시지 큐처럼 정상인 경우가 많으므로 목적지와 프로세스를 함께 확인합니다.