📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 44편
이전 글: 43. TCP Flag · 다음 글: 45. TCP 연결 종료 — FIN과 RST의 차이
TCP 연결은 SYN → SYN/ACK → ACK 세 패킷으로 수립됩니다. 세 단계가 무엇을 약속하는지, 서버의 대기열과 응답 유형은 41. TCP 3-Way Handshake — 연결이 성립했다는 증거에서 다뤘습니다.
이 글은 세 패킷을 한 장씩 떼어 놓고 봅니다. 관제에서는 센서 위치, 방화벽 정책, 스캔 여부에 따라 SYN만, SYN/ACK만 보이기도 하므로, 각 패킷의 특징을 알아야 일부만 보여도 상황을 추정할 수 있습니다.
| 패킷 | Flag 값 | 보내는 쪽 | 한 줄 요약 |
|---|---|---|---|
| SYN | 0x02 | 클라이언트 | "연결하자. 내 시작 번호는 x" |
| SYN/ACK | 0x12 | 서버 | "좋다. x+1을 기다리고, 내 시작 번호는 y" |
| ACK | 0x10 | 클라이언트 | "y+1을 기다린다" → 수립 완료 |
각 패킷이 만들어지고 응답이 없을 때 무엇이 일어나는지 흐름으로 보면 다음과 같습니다.
클라이언트 192.168.10.10 서버 192.168.10.20:443
│ 임시 포트 선택 (예: 51000), ISN x 생성
│
│ ── SYN (seq=x, ack 필드 미사용, 옵션 다수) ──────────→ │ LISTEN
│ 응답 없으면: 같은 seq·같은 포트로 SYN 재전송, │
│ 간격을 늘려 가며 반복 (tcp_syn_retries) │ ISN y 생성
│ │ SYN 대기열 등록
│ ←────────── SYN/ACK (seq=y, ack=x+1, 옵션 응답) ────── │
│ ACK가 안 오면: SYN/ACK 재전송 │
│ (tcp_synack_retries) 후 포기 │
│ │
│ ── ACK (seq=x+1, ack=y+1, 옵션 최소) ─────────────────→ │
↓ ESTABLISHED ↓ ESTABLISHED
(accept 대기열로 이동)
tcp_syn_retries, tcp_synack_retries 설정으로 정해집니다(41. TCP 3-Way Handshake — 연결이 성립했다는 증거 참고).세 패킷의 필드를 나란히 비교합니다.
| 항목 | SYN | SYN/ACK | ACK (세 번째) |
|---|---|---|---|
| seq | 클라이언트 ISN (무작위에 가까움) | 서버 ISN | x+1 |
| ack 번호 | 사용 안 함 (보통 0) | x+1 | y+1 |
| TCP 옵션 | 가장 많음: MSS, SACK 허용, Timestamps, Window Scale 등 | 클라이언트가 제안한 것 중 지원하는 것만 응답 | 대개 Timestamps 정도 |
| 페이로드 | 보통 0 (TCP Fast Open 사용 시 예외) | 보통 0 | 보통 0 (구현에 따라 데이터와 함께 갈 수 있음) |
| 출발지 포트 | 임시(Ephemeral) 포트 | 서비스 포트 | 임시 포트 |
| IP 헤더 TTL | 클라이언트 OS 초기값 기준 | 서버 OS 초기값 기준 | 클라이언트 기준 |
임시 포트 범위는 Linux가 일반적으로 32768~60999(net.ipv4.ip_local_port_range), 최신 Windows가 49152~65535입니다. SYN의 출발지 포트가 고정값이거나 규칙적으로 증가하면 도구가 만든 패킷일 가능성을 검토합니다.
옵션이 전혀 없거나 매우 단순한 SYN은 스캔 도구가 만든 패킷에서 자주 보입니다(옵션과 OS 식별은 40. TCP와 UDP 헤더 비교 — 신뢰성과 속도의 차이 참고).
세 패킷 중 일부만 관찰될 때의 해석입니다(센서가 양방향을 모두 본다는 전제).
| 관찰된 것 | 가능한 해석 | 추가 확인 |
|---|---|---|
| SYN만 (재전송 반복) | 대상 다운, 방화벽 drop, 경로 문제 | 방화벽 차단 로그, 대상 상태 |
| SYN → RST/ACK | 포트 닫힘 (41편) | — |
| SYN → SYN/ACK → RST (ACK 대신) | 클라이언트가 수립을 끝내지 않음. SYN 스캔의 전형적 흔적 | 같은 출발지의 다른 포트 시도 |
| SYN → SYN/ACK, 이후 없음 | 클라이언트 쪽 차단·위조 출발지, 또는 SYN Flood | 서버 SYN-RECV 수 |
| SYN/ACK만 (요청 없음) | 비대칭 경로, 또는 누군가 우리 IP를 위조해 보낸 SYN의 응답(Backscatter) | 센서 위치, 출발지 분포 |
| ACK만 (연결 없음) | 세션 타임아웃 후 늦은 패킷, 또는 ACK 스캔 | 대상의 RST 응답 여부 |
실습 예시 — 본인 소유 VM 두 대에서 세 패킷을 각각 필터링해 옵션까지 확인합니다(Rocky/Ubuntu 공통, -v로 옵션·TTL 표시). 인터페이스 ens33은 예시입니다.
# SYN만 (0x02)
sudo tcpdump -nn -v -i ens33 'tcp[13] == 0x02'
# SYN/ACK만 (0x12)
sudo tcpdump -nn -v -i ens33 'tcp[13] == 0x12'
# 임시 포트 범위 확인 (Linux)
sysctl net.ipv4.ip_local_port_range
# 클라이언트에서 연결 발생
curl -s -o /dev/null http://192.168.10.20/
세 번째 ACK는 Flag가 데이터 전송 중의 ACK와 같아(0x10), SYN/ACK 직후 ack = 서버 ISN+1인 패킷으로 찾습니다.
tcpdump 출력 형식 예시(값은 환경마다 다름, -v 출력 일부 생략):
IP (ttl 64, ... length 60) 192.168.10.10.51000 > 192.168.10.20.80: Flags [S], seq 3055000100, win 64240,
options [mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 7], length 0
IP (ttl 64, ... length 60) 192.168.10.20.80 > 192.168.10.10.51000: Flags [S.], seq 4012000200, ack 3055000101, win 65160,
options [mss 1460,sackOK,TS val 200 ecr 100,nop,wscale 7], length 0
IP (ttl 64, ... length 52) 192.168.10.10.51000 > 192.168.10.20.80: Flags [.], ack 1, win 502,
options [nop,nop,TS val 101 ecr 200], length 0
| 줄 | 확인 포인트 |
|---|---|
| SYN | ecr 0 — 받은 Timestamp가 아직 없음. 옵션 5종 |
| SYN/ACK | ack 3055000101 = SYN seq + 1. 클라이언트가 제안한 옵션에 응답 |
| ACK | IP 길이 52 = IP 20 + TCP 32(Timestamps 옵션 포함). tcpdump가 상대 번호로 바꿔 ack 1로 표시 |
각 패킷을 Wireshark로 필드 단위 분석하는 방법은 03. Wireshark 패킷 분석 영역 123. SYN Packet 분석, 124. SYN/ACK Packet 분석, 125. ACK Packet 분석에서 다룹니다.
| 흔적 위치 | 확인할 수 있는 것 |
|---|---|
| 패킷 캡처 | 세 패킷의 존재 여부, 옵션, TTL, 출발지 포트 |
| 방화벽 로그 | SYN에 대한 허용·차단, 수립 실패 세션(패킷 1~2개, 바이트 적음) |
| IDS/IPS | SYN Flood·스캔 관련 임계치 탐지, 연결 없는 ACK·SYN/ACK 이벤트 |
| 서버 | SYN-RECV 상태 수, SYN 쿠키 카운터 |
관제자가 확인할 질문
오탐 주의: 센서가 한 방향만 보면(비대칭 라우팅, 미러링 누락) 정상 연결도 "SYN만"으로 보입니다. 헬스체크도 SYN → SYN/ACK → RST 패턴을 만들 수 있으므로 출발지 자산과 반복 주기를 먼저 확인합니다.