📚 네트워크 · 패킷 분석 › 02. 포트 · 프로토콜 분석 — 79편
이전 글: 78. NTP와 로그 시간 동기화 · 다음 글: 80. ARP
ICMP(Internet Control Message Protocol)는 IP 통신의 오류 보고와 진단을 담당합니다. Type·Code 표, ping과 traceroute의 원리는 01 영역에서 다뤘습니다.
이 글은 02 영역의 질문, 즉 "ICMP는 어떤 포트를 쓰는가"에 답합니다. 답은 "포트가 없다"입니다. 그래서 방화벽 정책, 로그, NAT, 세션 테이블이 ICMP를 TCP·UDP와 다른 방식으로 다룹니다.
| 항목 | TCP / UDP | ICMP |
|---|---|---|
| IP 헤더의 Protocol 번호 | 6 / 17 | 1 (ICMPv6는 58) |
| 포트 필드 | 있음 (출발지·목적지 16비트) | 없음 |
| 서비스 구분 기준 | 포트 번호 | Type과 Code |
| 요청·응답 짝 맞추기 | 포트 + 순서 번호 | Echo의 Identifier + Sequence |
| LISTEN 소켓 | 서비스가 포트를 열어야 응답 | 커널(OS)이 직접 응답 |
ICMP 메시지는 IP 헤더 바로 뒤에 붙습니다. TCP·UDP 헤더가 들어갈 자리에 Type·Code·Checksum이 옵니다.
TCP/UDP 패킷: [IP 헤더 proto=6/17] [출발지 포트│목적지 포트│...] [데이터]
ICMP 패킷: [IP 헤더 proto=1] [Type│Code│Checksum│나머지 4바이트] [데이터]
└ Echo: Identifier + Sequence
└ 오류 메시지: 원래 패킷의 일부 ↓
UDP 192.168.10.10:53012 → 192.168.10.20:9999 (닫힌 포트)
↓
ICMP Type 3 Code 3 (Port Unreachable) 192.168.10.20 → 192.168.10.10
본문: [원래 IP 헤더] [원래 UDP 헤더 앞 8바이트 = 53012 → 9999 포함]
↓
받는 쪽 커널: 본문의 포트로 "어느 소켓의 오류인지" 찾아 전달
도구와 로그가 "포트 칸"에 ICMP를 어떻게 표시하는지는 제품마다 다릅니다. 대표적인 방식입니다.
| 위치 | ICMP 표시 방식 |
|---|---|
| iptables/nftables LOG | PROTO=ICMP TYPE=8 CODE=0 ID=… SEQ=… (SPT/DPT 없음) |
| conntrack(Linux 세션 테이블) | icmp … type=8 code=0 id=… |
| Zeek conn.log | 포트 칸에 Type(출발지 쪽)·Code(응답 쪽)를 넣어 표시 |
| 방화벽 장비 로그 | 포트 0 또는 빈 칸, Type/Code 별도 필드 (제품별 상이) |
ss, netstat | ICMP LISTEN 항목 없음 (커널 처리) |
방화벽 정책도 포트 대신 Type 단위로 씁니다.
| 정책 예 | 효과 | 주의 |
|---|---|---|
| Echo Request(8) 인바운드 차단 | 외부 ping 응답 숨김 | 호스트 발견을 완전히 막지는 못함 |
| Type 3 Code 4(Fragmentation Needed) 허용 | Path MTU 탐색 정상 동작 | 막으면 큰 패킷 통신 장애 |
| Time Exceeded(11) 허용 | traceroute 결과 확인 가능 | 내부 경로 정보 노출 가능 |
| ICMPv6 일괄 차단 | — | 이웃 탐색(NDP) 등이 깨져 IPv6 통신 불가 |
실습 예시 — 본인 소유 VM 두 대(192.168.10.10 → 192.168.10.20), 인터페이스 ens33은 예시입니다.
# 대상: ICMP만 캡처, 오류 메시지 본문의 원래 포트까지 표시(-v)
sudo tcpdump -nn -v -i ens33 icmp
# 출발지: ping 3회, 닫힌 UDP 포트로 1회 전송
ping -c 3 192.168.10.20
echo test > /dev/udp/192.168.10.20/9999 # bash 기능, 배포판 공통
# 출발지: 세션 테이블에서 ICMP 항목 (conntrack 패키지 필요)
sudo conntrack -L -p icmp
| 항목 | Rocky Linux | Ubuntu |
|---|---|---|
| conntrack 설치 | sudo dnf install conntrack-tools | sudo apt install conntrack |
| ICMP Type 차단 설정 | firewall-cmd --add-icmp-block=echo-request | /etc/ufw/before.rules의 ICMP 규칙 |
tcpdump 출력 형식 예시(값은 환경마다 다름, 일부 생략):
IP 192.168.10.10 > 192.168.10.20: ICMP echo request, id 4121, seq 1, length 64
IP 192.168.10.20 > 192.168.10.10: ICMP echo reply, id 4121, seq 1, length 64
IP 192.168.10.20 > 192.168.10.10: ICMP 192.168.10.20 udp port 9999 unreachable, length 41
IP 192.168.10.10.53012 > 192.168.10.20.9999: UDP, length 5
마지막 두 줄이 핵심입니다. ICMP 자체에는 포트가 없지만, 본문에 들어 있는 원래 UDP 패킷의 53012 → 9999가 그대로 해석됩니다.
| 흔적 위치 | 확인할 수 있는 것 |
|---|---|
| 방화벽 로그 | 프로토콜 1, Type·Code, 허용·차단 |
| NSM(Zeek 등) | ICMP 세션, 포트 칸의 Type·Code, 바이트 수 |
| IDS/IPS | 비정상 크기·빈도의 Echo, 대량 Unreachable |
| 패킷 캡처 | 오류 메시지 본문 속 원래 IP·포트 |
관제자가 확인할 질문
오탐 주의: DNS 서버 교체, 서비스 재시작 직후에는 정상적으로 Port Unreachable이 몰릴 수 있습니다. 모니터링 서버의 주기적 ping도 대량 Echo를 만듭니다.