📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 48편
이전 글: 47. DNS 이름 해석 흐름 — 도메인이 IP가 되기까지 · 다음 글: 49. 사설 IP · 공인 IP와 NAT — 로그의 IP가 서로 다른 이유
참고(리눅스 시스템 기초): ss와 ip 명령어 — 인터페이스에 붙은 IP 확인 방법
보안관제에서 가장 자주 받는 질문 중 하나는 "이 IP는 누구 PC인가?" 입니다. 방화벽·IDS·프록시 로그에는 대부분 IP만 남습니다. 그런데 사내 PC 대부분은 IP를 고정으로 쓰지 않고 DHCP로 임대(lease) 받습니다. 즉 같은 192.168.10.57이라도 어제와 오늘의 주인이 다를 수 있습니다.
그래서 IP → 장비(MAC, 호스트명) → 사용자로 이어지는 연결 고리의 첫 단추가 DHCP 할당 기록입니다. 이 기록을 이해하려면 DHCP가 어떤 포트로, 어떤 순서로, 어떤 정보를 주고받는지 알아야 합니다.
| 관제 질문 | DHCP가 주는 답 |
|---|---|
| 이 IP를 그 시각에 쓰던 장비는? | 임대 기록의 MAC 주소·호스트명·임대 시각 |
| 새로 보이는 IP가 정상 단말인가? | 할당 서버 로그에 기록이 있는지 |
| 단말이 어떤 DNS·게이트웨이를 받았나? | Offer/ACK의 옵션(3번 Router, 6번 DNS) |
| 모르는 DHCP 서버가 응답하고 있나? | Offer의 Server Identifier(옵션 54) — 다음 글에서 다룸 |
DHCP(Dynamic Host Configuration Protocol)는 UDP 기반입니다. 서버와 클라이언트가 쓰는 포트가 고정되어 있다는 점이 특징입니다.
| 구분 | 포트 | 설명 |
|---|---|---|
| DHCP 서버 | UDP 67 | 요청을 받고 Offer/ACK를 보냄 |
| DHCP 클라이언트 | UDP 68 | 응답을 받는 쪽 |
| DHCPv6 (참고) | UDP 546(클라이언트) / 547(서버) | IPv6 환경, 이번 글에서는 다루지 않음 |
클라이언트 포트까지 고정(68)인 이유는, 아직 IP가 없는 클라이언트에게 서버가 브로드캐스트로 응답해야 할 때가 있기 때문입니다. 임시 포트를 쓰면 같은 LAN의 다른 단말이 그 응답을 구분할 수 없습니다.
| 단계 | 메시지 | 방향 | 주요 내용 |
|---|---|---|---|
| D | DHCPDISCOVER | 클라이언트 → 브로드캐스트 | "DHCP 서버 있나요?" (출발지 IP 0.0.0.0) |
| O | DHCPOFFER | 서버 → 클라이언트 | "이 IP 쓸래요?" (제안 IP, 임대 시간, 옵션) |
| R | DHCPREQUEST | 클라이언트 → 브로드캐스트 | "그 서버의 그 IP로 하겠습니다" |
| A | DHCPACK | 서버 → 클라이언트 | "확정합니다" (이때부터 IP 사용) |
Request가 여전히 브로드캐스트인 이유는, Offer를 여러 서버에서 받았을 수 있으므로 선택하지 않은 서버에게도 "당신 것은 안 받는다"는 사실을 알리기 위해서입니다. Request 안의 옵션 54(Server Identifier) 가 선택한 서버를 가리킵니다.
| 메시지 | 의미 | 관제 시 의미 |
|---|---|---|
| DHCPNAK | 서버가 요청 거부 | 다른 네트워크로 옮긴 단말, 설정 오류, 서버 간 충돌 |
| DHCPDECLINE | 클라이언트가 받은 IP 거부 | 해당 IP가 이미 사용 중(IP 충돌) |
| DHCPRELEASE | 클라이언트가 IP 반납 | 정상 종료, 임대 기록 종료 시점 |
| DHCPINFORM | IP는 있고 옵션만 요청 | 고정 IP 단말의 설정 조회 |
| 옵션 번호 | 이름 | 내용 |
|---|---|---|
| 1 | Subnet Mask | 서브넷 마스크 |
| 3 | Router | 기본 게이트웨이 |
| 6 | Domain Name Server | DNS 서버 |
| 12 | Host Name | 클라이언트 호스트명 |
| 50 | Requested IP Address | 클라이언트가 원하는 IP |
| 51 | IP Address Lease Time | 임대 시간(초) |
| 53 | DHCP Message Type | Discover/Offer/Request/ACK 등 구분 |
| 54 | Server Identifier | 응답한(선택된) DHCP 서버 IP |
| 55 | Parameter Request List | 클라이언트가 원하는 옵션 목록 |

그림 1. Discover → Offer → Request → ACK 4단계
클라이언트 (IP 없음, MAC 00:0c:29:aa:bb:cc) DHCP 서버 192.168.10.1
│ │
│ ① DISCOVER 0.0.0.0:68 → 255.255.255.255:67 │
│───────────────────────────────────────────────────→│
│ │ 풀에서 IP 선택
│ ② OFFER 192.168.10.1:67 → (브로드캐스트/유니캐스트):68
│←───────────────────────────────────────────────────│ yiaddr=192.168.10.57
│ │
│ ③ REQUEST 0.0.0.0:68 → 255.255.255.255:67 │
│ (옵션 50=192.168.10.57, 옵션 54=192.168.10.1) │
│───────────────────────────────────────────────────→│
│ │ 임대 기록 저장
│ ④ ACK 192.168.10.1:67 → :68 │
│←───────────────────────────────────────────────────│ lease 86400초 등
↓
IP 설정 완료 → 보통 ARP로 중복 여부 확인 후 사용
yiaddr(your IP address) 필드에 담깁니다. 필드 단위 해석은 (03 Wireshark 시리즈에서 다룸)IP는 영구 소유가 아니라 임대입니다. 클라이언트는 임대 시간이 끝나기 전에 갱신을 시도합니다.
임대 시작 ─────── T1(임대 시간의 50%) ─────── T2(87.5%) ─────── 만료
│ │ │
↓ ↓ ↓
원래 서버에 유니캐스트 REQUEST 아무 서버에나 브로드캐스트 IP 사용 중단,
(Renewing) REQUEST (Rebinding) DISCOVER부터 다시
T1/T2 값은 서버가 옵션으로 따로 줄 수도 있으며, 위 비율은 기본값입니다. 관제 관점에서 중요한 점은, 갱신이 계속 성공하면 같은 단말이 같은 IP를 오래 유지하지만 갱신 기록 자체는 계속 남는다는 것입니다.
브로드캐스트는 라우터를 넘지 못합니다(04편 게이트웨이 글 참고: 04. 게이트웨이와 라우팅 기초). 그래서 기업망에서는 각 VLAN의 게이트웨이(L3 스위치/라우터)가 Relay Agent 역할을 하여 브로드캐스트를 받아 중앙 DHCP 서버로 유니캐스트 전달합니다.
giaddr(relay agent IP) 필드에 게이트웨이 주소가 들어가고, 서버는 이를 보고 어느 서브넷의 풀에서 IP를 줄지 결정합니다.via 192.168.20.1 처럼 Relay 주소가 찍히는 이유가 이것입니다.실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu), VMware NAT 네트워크(VMware가 DHCP 제공). 인터페이스 이름은 ens33을 예시로 사용하며, 본인 환경에서는 ip -br addr로 먼저 확인합니다.
목표는 DHCP 서버를 새로 띄우지 않고, VM이 IP를 다시 받는 과정을 관찰하는 것입니다. (실습망에 DHCP 서버를 하나 더 띄우면 그 자체가 다음 글의 "비인가 DHCP 서버"가 될 수 있으므로 주의합니다.)
# 인터페이스 요약
ip -br addr show ens33
# dynamic 표시 + valid_lft(남은 임대 시간) 확인
ip addr show ens33
inet 192.168.10.57/24 ... dynamic ens33 처럼 dynamic이 보이면 DHCP로 받은 주소이고, valid_lft가 남은 임대 시간(초)입니다.
# Rocky Linux / Ubuntu Desktop (NetworkManager 사용 시)
nmcli -f DHCP4 device show ens33
# Ubuntu Server (netplan + systemd-networkd 사용 시)
networkctl status ens33
터미널 두 개를 엽니다. VM 콘솔(VMware 화면)에서 직접 작업합니다. SSH로 접속한 상태에서 인터페이스를 내리면 접속이 끊깁니다.
# 터미널 1: DHCP 포트만 캡처 (tcpdump 미설치 시 설치)
# Rocky: sudo dnf install -y tcpdump
# Ubuntu: sudo apt install -y tcpdump
sudo tcpdump -i ens33 -n -e -v 'udp port 67 or udp port 68'
# 터미널 2: 연결을 내렸다 올려 DHCP 재요청 유도
# Rocky / NetworkManager 환경 (연결 이름은 nmcli con show 로 확인)
nmcli con show
sudo nmcli con down "ens33" && sudo nmcli con up "ens33"
# Ubuntu Server / systemd-networkd 환경
sudo networkctl reconfigure ens33
📷 [실습 화면 삽입] tcpdump에 DHCP Discover → Offer → Request → ACK 4개 패킷이 순서대로 찍힌 화면
# Rocky / NetworkManager
sudo journalctl -u NetworkManager --since "10 min ago" | grep -i dhcp
# Ubuntu Server / systemd-networkd
sudo journalctl -u systemd-networkd --since "10 min ago" | grep -i dhcp
📷 [실습 화면 삽입]
nmcli -f DHCP4 device show ens33결과에서 routers, domain_name_servers, dhcp_lease_time 항목
tcpdump 출력 (형식 예시(값은 환경마다 다름))
10:02:11.101 00:0c:29:aa:bb:cc > ff:ff:ff:ff:ff:ff ... 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:0c:29:aa:bb:cc
DHCP-Message (53), length 1: Discover
10:02:11.103 00:50:56:11:22:33 > 00:0c:29:aa:bb:cc ... 192.168.10.254.67 > 192.168.10.57.68: BOOTP/DHCP, Reply
Your-IP 192.168.10.57
DHCP-Message (53), length 1: Offer
Server-ID (54), length 4: 192.168.10.254
10:02:11.104 ... 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request
DHCP-Message (53), length 1: Request
Requested-IP (50), length 4: 192.168.10.57
Server-ID (54), length 4: 192.168.10.254
10:02:11.106 ... 192.168.10.254.67 > 192.168.10.57.68: BOOTP/DHCP, Reply
DHCP-Message (53), length 1: ACK
Lease-Time (51), length 4: 1800
VMware NAT 네트워크에서는 VMware가 제공하는 DHCP 서비스가 응답하므로, 서버 IP가 게이트웨이와 다를 수 있습니다(위 예시의 .254). 이런 "우리 환경의 정상 DHCP 서버는 무엇인가" 를 미리 알아두는 것이 다음 글의 비인가 서버 탐지의 기준선이 됩니다.
점검 체크리스트
ip addr에서 dynamic과 valid_lft를 확인했다0.0.0.0:68, 목적지가 255.255.255.255:67인 것을 확인했다ip route, /etc/resolv.conf 등과 일치하는지 확인했다리눅스 ISC DHCP 서버(dhcpd)를 쓰는 환경에서는 syslog(Rocky: /var/log/messages, Ubuntu: /var/log/syslog)에 다음과 같은 형태로 남습니다. Windows DHCP 서버는 %windir%\System32\dhcp 아래 감사 로그(DhcpSrvLog-*.log)에 비슷한 정보를 남깁니다(참고).
# 형식 예시(값은 환경마다 다름)
dhcpd[1234]: DHCPDISCOVER from 00:0c:29:aa:bb:cc via ens33
dhcpd[1234]: DHCPOFFER on 192.168.10.57 to 00:0c:29:aa:bb:cc (pc-hr-07) via ens33
dhcpd[1234]: DHCPREQUEST for 192.168.10.57 (192.168.10.1) from 00:0c:29:aa:bb:cc (pc-hr-07) via ens33
dhcpd[1234]: DHCPACK on 192.168.10.57 to 00:0c:29:aa:bb:cc (pc-hr-07) via ens33
이 4줄만으로 시각 + IP + MAC + 호스트명 + 수신 경로가 한 번에 묶입니다. 관제에서 "10시 5분에 192.168.10.57이 악성 도메인 질의" 경보를 받았다면, 그 시각을 포함하는 ACK 기록을 찾아 MAC과 호스트명을 확인하는 식으로 사용합니다.
| 관찰 | 정상일 수 있는 경우 | 의심해야 하는 경우 |
|---|---|---|
| 같은 IP에 다른 MAC | 임대 만료 후 재할당, PC 교체 | 짧은 시간 내 반복, 같은 호스트명에 MAC만 변경 |
| 알 수 없는 호스트명 | 신규 입사자 PC, 모바일 기기 | 사내 명명 규칙과 다른 이름이 서버 VLAN에 등장 |
| DHCPNAK 다수 | 노트북이 다른 층·VLAN으로 이동 | 두 DHCP 서버의 범위가 겹치거나 비인가 서버 존재 |
| DHCPDECLINE | IP 충돌(고정 IP와 풀 중복) | 누군가 해당 IP를 무단 고정 사용 중 |
| 옵션 54의 서버 IP가 평소와 다름 | 서버 이중화(Failover) 환경 | 등록되지 않은 서버 → 다음 글에서 상세히 다룸 |
| 짧은 시간 수많은 DISCOVER | 대규모 재부팅, 정전 후 복구 | MAC이 계속 바뀌는 대량 요청 → 고갈 공격 징후 |
# 특정 MAC의 할당 이력 (ISC dhcpd 서버 기준)
sudo grep -i "00:0c:29:aa:bb:cc" /var/log/messages # Rocky
sudo grep -i "00:0c:29:aa:bb:cc" /var/log/syslog # Ubuntu
# 특정 IP를 누가 받았는지
sudo grep "DHCPACK on 192.168.10.57 " /var/log/messages
# 현재 임대 DB (ISC dhcpd)
sudo cat /var/lib/dhcpd/dhcpd.leases # Rocky
sudo cat /var/lib/dhcp/dhcpd.leases # Ubuntu
# 패킷 캡처에서 서버 응답만 보기
sudo tcpdump -i ens33 -n -v 'udp src port 67'
흔적이 남는 곳
| 위치 | 남는 정보 | 활용 |
|---|---|---|
| DHCP 서버 로그 | 시각, IP, MAC, 호스트명, Relay 경로 | IP ↔ 단말 매핑의 1차 근거 |
| 스위치 DHCP Snooping 바인딩 테이블 | IP, MAC, VLAN, 포트 | 물리 포트까지 추적 (04 장비 시리즈에서 다룸) |
| NAC / 자산관리 시스템 | MAC ↔ 사용자·자산 번호 | 최종 사용자 식별 |
| SIEM | 위 로그의 통합 | 경보 IP를 시각 기준으로 자동 매핑 (07 관제 통합 시리즈에서 다룸) |
한계와 오탐 주의