50. 웹 요청 하나의 전체 경로 — 01 시리즈 종합

changseop lee·6일 전

📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 50편
이전 글: 49. 사설 IP · 공인 IP와 NAT — 로그의 IP가 서로 다른 이유 · 다음 글: 51. 포트 번호 체계 — Well-known·Registered·임시 포트
참고(리눅스 시스템 기초): Socket 이해 — 애플리케이션이 소켓으로 통신을 요청하는 구조

1. 왜 알아야 하는가

  1. TCP/IP 네트워크 구조 이해 시리즈에서는 계층, MAC과 ARP, IP와 서브넷, 라우팅, NAT, ICMP, TCP·UDP, 연결 수립과 종료, 상태 전이, 시퀀스와 윈도우, MTU, IPv6, DNS를 하나씩 살펴봤습니다. 각각은 따로 배웠지만 실제 통신에서는 한 번의 웹 요청 안에서 모두 순서대로 일어납니다.

관제에서 하나의 이벤트를 분석할 때도 마찬가지입니다. "사용자 PC가 외부 사이트에 접속했다"는 한 문장 뒤에는 DNS 질의, ARP, 라우팅, NAT 변환, TCP 연결, HTTP 요청이 있고, 각 단계는 서로 다른 장비와 로그에 흔적을 남깁니다. 어느 단계의 증거가 어디에 있는지 알아야 여러 로그를 시간 순으로 엮어 하나의 사건으로 재구성할 수 있습니다.

이 글은 새로운 개념을 추가하지 않고, 01 시리즈 전체를 "웹 요청 하나의 타임라인"과 "단계별 증거 맵" 으로 묶어 정리합니다.


2. 핵심 개념

2-1. 시나리오

항목값 (예시)
클라이언트192.168.10.20/24, 인터페이스 ens33
기본 게이트웨이192.168.10.1
사내 DNS 리졸버192.168.10.53
방화벽 NAT 공인 IP198.51.100.7
웹 서버www.example.com → 203.0.113.80, TCP 80
요청http://www.example.com/index.html

설명을 단순하게 하려고 평문 HTTP(80)를 기준으로 하고, HTTPS는 달라지는 지점만 짚습니다.

2-2. 단계와 01 시리즈 대응

단계일어나는 일관련 글
0URL 해석, 계층별 캡슐화 준비01. OSI 7계층과 TCP/IP 4계층
1도메인 → IP 이름 해석14. DNS 이름 해석 흐름
2목적지가 같은 서브넷인지 판단03. IPv4 주소와 서브넷(CIDR)
3게이트웨이로 보내기로 결정04. 게이트웨이와 라우팅 기초
4게이트웨이 MAC 확인02. Ethernet 프레임과 MAC 주소 · ARP
5경계에서 사설 → 공인 주소 변환05. 사설 IP · 공인 IP와 NAT
6TCP 연결 수립07. TCP와 UDP 헤더, 08. TCP 3-Way Handshake
7HTTP 요청·응답 데이터 전달11. 시퀀스 번호·ACK·윈도우, 12. MTU와 IP 단편화
8연결 종료와 상태 정리09. TCP 연결 종료, 10. TCP 상태 전이
예외경로 오류·도달 불가 통보06. ICMP와 ping
변형DNS가 AAAA를 돌려주면 IPv6 경로 사용13. IPv6 기초

3. 동작 원리

웹 요청 경로
그림 1. 한 번의 웹 요청이 거치는 단계와 각 단계에서 확인할 수 있는 증거

[0] 브라우저: http://www.example.com/index.html
        → 스킴 http, 호스트 www.example.com, 포트 80(기본), 경로 /index.html
        ↓
[1] 이름 해석: /etc/hosts → 로컬 캐시 → 리졸버 192.168.10.53 (UDP 53)
        → A 203.0.113.80  (AAAA도 함께 질의될 수 있음)
        ↓
[2] 서브넷 판단: 203.0.113.80 은 192.168.10.0/24 밖 → 직접 전달 불가
        ↓
[3] 라우팅: 라우팅 테이블 default via 192.168.10.1 선택
        ↓
[4] ARP: "192.168.10.1 의 MAC?" → 캐시에 없으면 브로드캐스트 요청
        → 프레임 목적지 MAC = 게이트웨이 MAC, IP 목적지 = 203.0.113.80 (IP는 그대로)
        ↓
[5] 경계 방화벽: 정책 허용 확인 → SNAT 192.168.10.20:51544 → 198.51.100.7:40123
        → 라우터마다 TTL 1 감소, 구간마다 MAC 교체
        ↓
[6] TCP Handshake: SYN → SYN/ACK → ACK  (MSS·Window Scale·SACK 협상)
        ↓
[7] HTTP: GET /index.html (seq 전진) → 서버 응답 200 + 본문 (여러 세그먼트, ACK 누적)
        ↓        ※ HTTPS라면 [6] 이후 TLS Handshake가 먼저, [7] 내용은 암호화
[8] 종료: FIN/ACK 교환 → 먼저 닫은 쪽 TIME_WAIT, 또는 RST로 즉시 종료
        → 방화벽 세션 테이블 항목 삭제, 세션 로그(바이트·지속 시간) 기록

단계별로 짚을 점은 다음과 같습니다.

  • [1]이 없는 요청도 있습니다. hosts 파일, 캐시, IP 직접 입력이면 DNS 흔적이 없습니다.
  • [4]의 목적지 MAC은 웹 서버가 아니라 게이트웨이입니다. 외부 서버의 MAC은 클라이언트 쪽 캡처에 절대 나오지 않습니다.
  • [5] 이후 외부에서 보이는 출발지는 198.51.100.7입니다. 웹 서버 로그만으로는 내부 단말을 알 수 없고, 방화벽 NAT 로그가 연결 고리입니다.
  • [6]에서 SYN만 반복되고 끝나면 연결은 성립하지 않았습니다. 이후 단계의 증거가 없는 것이 정상입니다.
  • [7]에서 큰 응답만 멈추면 MTU·PMTUD 문제(12편)를, 재전송이 많으면 seq/ack 흐름(11편)을 봅니다.
  • HTTPS에서는 [7]의 URL 경로·헤더·본문이 암호화되어 네트워크 장비에서 보이지 않습니다. 대신 TLS Handshake의 SNI(서버 이름) 등 일부 정보만 볼 수 있으며, 자세한 내용은 02. 포트 · 프로토콜 분석 시리즈 06. HTTPS와 TLS Handshake에서 다룹니다.

4. 실제 명령어 / 실습

실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu), 인터페이스 이름은 ens33 예시입니다. 대상은 예시용으로 예약된 도메인 example.com을 사용합니다.

4-1. 도구 설치

# Rocky Linux
sudo dnf install -y curl tcpdump bind-utils iproute

# Ubuntu
sudo apt update && sudo apt install -y curl tcpdump dnsutils iproute2

4-2. 요청 전 상태 기록

ip -4 addr show dev ens33            # [2] 내 주소·서브넷
ip route get 203.0.113.80            # [3] 이 목적지는 어느 게이트웨이로? (실습 시 실제 IP로)
ip neigh show dev ens33              # [4] 현재 ARP 캐시
grep '^hosts' /etc/nsswitch.conf     # [1] 조회 순서

4-3. 전 과정 캡처

# 터미널 1: ARP·DNS·HTTP를 한 파일로 캡처
sudo tcpdump -i ens33 -nn -w web_path.pcap 'arp or port 53 or port 80'

# 터미널 2: 처음부터 보이도록 캐시를 비운 뒤 요청 (본인 VM에서만)
sudo ip neigh flush dev ens33                    # ARP 캐시 비우기 → [4] 재발생
sudo resolvectl flush-caches 2>/dev/null         # Ubuntu 로컬 DNS 캐시 비우기
curl -s -o /dev/null http://www.example.com/

ip neigh flush는 잠깐 동안 SSH 등 기존 연결에 지연을 줄 수 있으니 콘솔에서 실행하는 것이 안전합니다.

4-4. 단계별 소요 시간 측정

curl -w의 시간 변수는 단계 경계와 그대로 대응됩니다.

curl -s -o /dev/null -w \
'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
http://www.example.com/

# HTTPS와 비교 (tls 값이 0이 아니게 됨)
curl -s -o /dev/null -w \
'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
https://www.example.com/

4-5. 캡처 파일 단계별 읽기

sudo tcpdump -nn -e -r web_path.pcap arp                          # [4]
sudo tcpdump -nn -r web_path.pcap port 53                         # [1]
sudo tcpdump -nn -r web_path.pcap 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'   # [6][8]
sudo tcpdump -nn -A -r web_path.pcap 'tcp port 80 and tcp[tcpflags] & tcp-push != 0' | head -40   # [7]

# 종료 후 클라이언트 쪽 TIME_WAIT 확인 [8]
ss -tan state time-wait '( dport = :80 )'

📷 [실습 화면 삽입] tcpdump로 읽은 web_path.pcap — ARP 요청/응답, DNS 질의/응답, SYN·SYN/ACK·ACK, GET, FIN이 시간 순으로 이어지는 구간

📷 [실습 화면 삽입] Wireshark Statistics > Flow Graph 로 본 동일 pcap 흐름 — 단계 번호를 주석으로 표시


5. 결과 확인

curl -w 출력 형식 예시(값은 환경마다 다름, 단위 초, 각 값은 요청 시작부터의 누적 시간):

dns:0.004 connect:0.041 tls:0.000 ttfb:0.083 total:0.084
dns:0.001 connect:0.038 tls:0.112 ttfb:0.151 total:0.152
curl 값끝난 단계해석 포인트
time_namelookup[1] 이름 해석두 번째 요청에서 짧아지면 캐시 효과
time_connect[6] TCP Handshakeconnect - dns ≒ 서버까지 왕복 시간
time_appconnectTLS HandshakeHTTP에서는 0
time_starttransfer[7] 첫 응답 바이트서버 처리 시간 포함
time_total전체

tcpdump 요약 형식 예시(값은 환경마다 다름):

ARP, Request who-has 192.168.10.1 tell 192.168.10.20, length 28
ARP, Reply 192.168.10.1 is-at 00:50:56:aa:bb:01, length 46
192.168.10.20.40331 > 192.168.10.53.53: 30211+ A? www.example.com. (33)
192.168.10.53.53 > 192.168.10.20.40331: 30211 1/0/1 A 203.0.113.80 (60)
192.168.10.20.51544 > 203.0.113.80.80: Flags [S], seq 2854113921, win 64240, options [mss 1460,...]
203.0.113.80.80 > 192.168.10.20.51544: Flags [S.], seq 1703928410, ack 2854113922, win 65160, ...
192.168.10.20.51544 > 203.0.113.80.80: Flags [P.], seq 1:80, ack 1, length 79: HTTP: GET / HTTP/1.1
192.168.10.20.51544 > 203.0.113.80.80: Flags [F.], seq 80, ack 1394, length 0
  • ARP 대상이 웹 서버가 아니라 게이트웨이 IP인 것을 확인했다
  • DNS 응답 IP와 SYN 목적지 IP가 같은 것을 확인했다
  • SYN의 seq(절대값)에 1을 더한 값이 SYN/ACK의 ack인 것, 이후 데이터는 상대 번호 1부터 표시되는 것을 확인했다
  • FIN을 먼저 보낸 쪽과 TIME_WAIT가 남은 쪽이 일치하는지 확인했다
  • curl -w 값으로 단계별 소요 시간을 설명할 수 있다

6. 패킷 / 로그 분석

6-1. 단계별 증거 맵

단계패킷(클라이언트 쪽 캡처)호스트 증거네트워크·보안 장비 로그
[1] DNSudp.port == 53 질의/응답hosts·resolv.conf, 로컬 캐시리졸버 질의 로그, NSM DNS 로그
[2]~[3] 라우팅 결정(직접 흔적 없음, 목적지 MAC으로 간접 확인)ip route—
[4] ARParp 요청/응답ip neigh스위치 MAC 테이블, (설정 시) ARP 감시 로그
[5] NAT·정책내부 캡처에는 변환 전 주소만—방화벽 허용/차단 로그, NAT 변환 로그
[6] TCP 연결SYN·SYN/ACK·ACKss -tan ESTAB방화벽 세션 시작, IDS 플로우 기록
[7] HTTP요청 라인·헤더(평문일 때)브라우저·애플리케이션 로그프록시 로그, 웹 서버 access log, IDS/WAF 이벤트
[8] 종료FIN 또는 RSTss TIME_WAIT방화벽 세션 종료(바이트 수·지속 시간·종료 사유)
예외ICMP 오류—라우터·방화벽 ICMP 로그

6-2. 단계가 끊긴 위치로 원인 좁히기

관찰된 마지막 단계정상일 수 있는 경우의심해야 하는 경우
DNS 질의만 있고 연결 없음prefetch, 사용자가 접속 취소차단된 도메인 질의 → 그 단말의 다른 활동 확인
DNS 없이 바로 SYNIP 직접 접속, 캐시·hosts 사용외부 IP로 DNS 없이 반복 연결 → 하드코딩된 목적지 여부 확인
SYN 반복 후 종료서버 다운, 경로 장애방화벽 차단(로그 확인), 다수 목적지로 SYN만 발생 → 05. 네트워크 스캔 · 공격 징후 분석 시리즈에서 다룸
Handshake 후 즉시 RST서비스 거부 설정, 포트 닫힘IPS 차단 응답 여부 확인(06. 방화벽 · IDS/IPS 분석 시리즈에서 다룸)
큰 응답만 멈춤—PMTUD 블랙홀, 중간 장비 드롭
정상 완료, 응답 바이트가 요청 대비 매우 큼/작음파일 다운로드, 캐시 응답업로드 방향 바이트가 비정상적으로 큼 → 유출 여부를 프록시·세션 로그로 확인
# 한 pcap에서 대화(세션)별 요약: 어느 단계까지 갔는지 빠르게 파악
tshark -r web_path.pcap -q -z conv,tcp
tshark -r web_path.pcap -q -z conv,udp

7. 보안관제 관점

여러 로그를 하나의 사건으로 엮는 기준

  1. 시간: 모든 장비의 시각이 맞아야 단계 순서를 재구성할 수 있습니다. 시간 동기화는 02. 포트 · 프로토콜 분석 시리즈 17. NTP와 로그 시간 동기화에서 다룹니다.
  2. 주소 변환: 내부 로그(사설 IP)와 외부 로그(공인 IP)는 NAT 로그의 포트 매핑으로만 연결됩니다. 05편에서 본 것처럼 NAT 로그가 없으면 내부 단말 특정이 어렵습니다.
  3. 리졸버 대리 질의: 외부에서 본 DNS 출발지는 리졸버입니다. 단말을 특정하려면 리졸버 로그가 필요합니다(14편).
  4. 세션 식별자: 5-tuple(출발지·목적지 IP, 포트, 프로토콜)과 시간 범위를 기준으로 방화벽·IDS·프록시 이벤트를 묶습니다.

단계별로 넘기는 주제

  • 포트·서비스 식별, HTTP 구조·상태 코드, TLS, DNS 레코드와 악용 → 02. 포트 · 프로토콜 분석 시리즈
  • 각 단계 패킷의 필드 단위 해석 → 03. Wireshark 패킷 분석 시리즈
  • 방화벽·IDS가 어느 단계에서 무엇을 보고 차단하는지 → 06. 방화벽 · IDS/IPS 분석 시리즈
  • 여러 로그를 SIEM에서 자동으로 엮는 방법 → 07. 네트워크 보안관제 통합 분석 시리즈

한계와 오탐 주의

  • 한 지점의 증거로 전체 단계를 단정하지 않습니다. 예를 들어 방화벽 허용 로그는 [6] 연결 시도가 있었다는 증거일 뿐, [7] 데이터 전달이 있었다는 증거는 아닙니다. 바이트 수와 종료 사유를 함께 봅니다.
  • HTTPS·DoH·VPN이 쓰이면 [1]과 [7]의 가시성이 크게 줄어듭니다. 이때는 호스트·프록시 쪽 증거의 비중이 커집니다.
  • 이 글의 흐름은 전형적인 경우입니다. 프록시를 거치는 환경에서는 [1]의 이름 해석을 프록시가 대신하는 등 순서와 주체가 달라질 수 있습니다.

8. 핵심 정리

  • 웹 요청 하나는 이름 해석 → 서브넷 판단·라우팅 → ARP → NAT → TCP Handshake → HTTP 데이터 → 종료 순서로 진행되며, 01~14편 내용이 모두 등장합니다.
  • 클라이언트 캡처의 목적지 MAC은 게이트웨이이고, 외부에서 보이는 출발지는 NAT 공인 IP라는 점이 단계 간 주소가 바뀌는 핵심입니다.
  • 단계마다 증거 위치가 다르므로(리졸버 로그, ARP 캐시, NAT 로그, 세션 로그, 프록시·웹 로그) 증거 맵을 기준으로 필요한 로그를 찾습니다.
  • 통신이 끊긴 마지막 단계를 찾으면 원인 후보(차단, 장애, 스캔, MTU 문제)를 빠르게 좁힐 수 있습니다.
  • 여러 로그는 시간 동기화, NAT 매핑, 리졸버 로그, 5-tuple을 기준으로 엮어야 하나의 사건으로 재구성됩니다.

다음 글: 01. 포트 번호 체계 — Well-known·Registered·임시 포트

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글