📚 네트워크 · 패킷 분석 › 03. Wireshark 패킷 분석 — 132편
이전 글: 131. TCP Retransmission · 다음 글: 133. TCP Stream
Duplicate ACK(Dup ACK)는 수신 측이 같은 ACK 번호를 반복해서 보내는 것입니다. 수신 측이 기대한 seq보다 뒤쪽 세그먼트를 받았을 때 "아직 이 번호가 필요하다"고 알리는 신호이며, 3개가 쌓이면 송신 측이 빠른 재전송을 시작하는 계기가 됩니다(원리는 46. 시퀀스 번호·ACK·윈도우 — TCP가 데이터를 빠짐없이 전달하는 방법). 이 글은 Wireshark에서 Dup ACK를 식별하고 빠진 구간을 읽는 방법만 다룹니다.
| 필드 | 의미 |
|---|---|
tcp.analysis.duplicate_ack | Dup ACK로 판정된 패킷 |
tcp.analysis.duplicate_ack_num | 몇 번째 중복인지 (1, 2, 3…) |
tcp.analysis.duplicate_ack_frame | 원래 ACK가 있던 프레임 번호 |
tcp.options.sack_le, tcp.options.sack_re | SACK 블록의 왼쪽·오른쪽 경계 (수신 완료 구간) |
tcp.options.sack_perm | SYN에서 SACK 사용 가능을 알림 |
Wireshark가 ACK 하나를 Dup ACK로 판정하는 조건(요약)입니다.
ACK 세그먼트 도착
↓
페이로드 길이 0 ? ─ 아니오 → 일반 데이터
↓ 예
SYN·FIN·RST 없음 ? ─ 아니오 → 해당 플래그 패킷
↓ 예
ACK 번호가 이 방향 직전 ACK와 같음 ? ─ 아니오 → 일반 ACK
↓ 예
윈도우 크기가 직전과 같음(0이 아님) ? ─ 아니오 → Window Update 등
↓ 예
[TCP Dup ACK <원래 프레임>#<순번>]
[TCP Dup ACK 57#3]은 "프레임 57의 ACK와 같은 값을 세 번째로 반복"이라는 뜻입니다.ACK 번호 ~ SACK 왼쪽 경계 사이가 빠진 구간입니다.Dup ACK와 헷갈리는 표시
| Info 표시 | 공통점 | 차이점 |
|---|---|---|
[TCP Dup ACK] | ACK 번호 반복, 데이터 없음 | 윈도우 동일 |
[TCP Window Update] | ACK 번호 반복, 데이터 없음 | 윈도우 값만 변경 (정상 흐름 제어) |
[TCP Keep-Alive ACK] | 데이터 없음 | Keep-Alive 탐침에 대한 응답 (tcp.analysis.keep_alive_ack) |
[TCP ZeroWindowProbeAck] | 데이터 없음 | 윈도우 0 상태에서 탐침 응답 |
Dup ACK 뒤에 무엇이 오는가
| 이어지는 패킷 | 의미 |
|---|---|
| 몇 개 뒤 Fast Retransmission | 손실 1건을 빠르게 회복 (정상적인 회복 동작) |
| 재전송 없이 Dup ACK만 수십~수백 개 | 송신 측이 재전송을 못 하거나, 캡처 쪽 누락, 비정상 상태 |
| Dup ACK 1~2개 후 원래 순서 세그먼트 도착 | 단순 순서 뒤바뀜 (tcp.analysis.out_of_order) |
실습 예시 — 본인 소유 VM에서 손실을 인위적으로 만든 파일 다운로드 캡처(손실 설정은 46. 시퀀스 번호·ACK·윈도우 — TCP가 데이터를 빠짐없이 전달하는 방법 4-5 참고)를 분석합니다. 명령과 출력은 예시(값은 환경마다 다름)입니다.
# Dup ACK와 원래 프레임, 순번, SACK 경계
tshark -r /tmp/dupack.pcapng -Y 'tcp.analysis.duplicate_ack' -T fields -E header=y \
-e frame.number -e tcp.stream -e ip.src -e tcp.ack \
-e tcp.analysis.duplicate_ack_frame -e tcp.analysis.duplicate_ack_num \
-e tcp.options.sack_le -e tcp.options.sack_re
# 스트림별 최대 Dup ACK 순번 (한 번에 얼마나 쌓였나)
tshark -r /tmp/dupack.pcapng -Y 'tcp.analysis.duplicate_ack' -T fields \
-e tcp.stream -e tcp.analysis.duplicate_ack_num \
| awk '$2 > m[$1] {m[$1] = $2} END {for (s in m) print s, m[s]}' | sort -n
# SACK 사용 협상 여부 (SYN 기준)
tshark -r /tmp/dupack.pcapng -Y 'tcp.flags.syn == 1' -T fields -e tcp.stream -e ip.src -e tcp.options.sack_perm
형식 예시입니다.
frame.number tcp.stream ip.src tcp.ack dup_ack_frame dup_ack_num sack_le sack_re
412 0 192.168.10.20 289601 409 1 291049 292497
414 0 192.168.10.20 289601 409 2 291049 293945
416 0 192.168.10.20 289601 409 3 291049 295393
417 0 192.168.10.10 ... (Fast Retransmission, seq 289601)
| 확인 포인트 | 읽는 법 |
|---|---|
| ack 289601 반복 | 이 번호부터의 세그먼트가 아직 도착하지 않음 |
| SACK 291049~ | 289601~291048 구간(1448바이트, 세그먼트 1개)이 빠짐 |
| 3번째 Dup ACK 직후 프레임 417 | 송신 측이 빠진 seq를 빠르게 재전송 |
📷 [실습 화면 삽입 위치]
tcp.analysis.duplicate_ack || tcp.analysis.fast_retransmission필터 결과 — Dup ACK #1~#3 다음에 Fast Retransmission이 이어지는 Packet List 화면
📷 [실습 화면 삽입 위치] Dup ACK 패킷 Details의 Options에서 SACK 블록(left edge, right edge)을 펼친 화면
| 관찰 | 가능한 해석 | 확인할 것 |
|---|---|---|
| 재전송 없이 양쪽이 ACK를 끝없이 주고받음 | 세션 하이재킹으로 양측 seq가 어긋날 때 이론적으로 알려진 ACK storm 형태 | 제3의 출처 패킷(TTL·MAC 불일치) 존재 여부 |
| 특정 세그먼트 이후 Dup ACK만 계속되다 연결 종료 | 중간 장비가 특정 페이로드만 버림(인라인 차단) | 빠진 seq 구간의 내용, IPS 이벤트 |
| 한 호스트의 거의 모든 연결에서 Dup ACK 다발 | 호스트 NIC·드라이버, 경로 장비 문제 | 다른 호스트와 비교 |
| 흔적 위치 | 확인할 수 있는 것 |
|---|---|
| 패킷 캡처 | Dup ACK 순번, 빠진 구간(SACK) |
| IPS 로그 | 차단 이벤트의 세션·시각 (빠진 구간과 대조) |
| 네트워크 장비 | 인터페이스 드롭·에러 카운터 |
관제자가 확인할 질문
lost_segment 동반 여부)오탐 주의: 대용량 전송에서 Dup ACK 몇 개는 정상 혼잡 제어의 일부입니다. 특히 수신 측이 SACK를 쓰면 손실 1건에도 Dup ACK가 여러 개 생깁니다. "Dup ACK 수"가 아니라 회복 여부와 반복 위치로 판단하며, 경로 품질 문제는 네트워크 운영 부서와 협업 대상입니다.
[TCP Dup ACK 57#3]은 프레임 57의 ACK를 세 번째로 반복했다는 뜻이며, duplicate_ack_frame·duplicate_ack_num 필드로 추출합니다.ACK 번호 ~ sack_le 사이가 빠진 구간입니다.