라우팅 실습과 진단
라우팅의 이론을 배웠으니, 이제 실제로 패킷이 어떤 경로를 따라 이동하는지 직접 확인해 보겠습니다. 라우팅 경로를 눈으로 볼 수 있다는 것은 네트워크 문제를 진단할 때 매우 강력한 무기가 됩니다.
traceroute로 경로 추적
traceroute(Windows에서는 tracert)는 목적지까지 가는 경로에서 응답을 돌려준 홉을 순서대로 보여주는 도구입니다. 실제 경로의 모든 장비가 항상 보이는 것은 아니며, 장비 정책과 되돌아오는 경로의 영향을 함께 받습니다.
traceroute google.comtracert google.com실행하면 각 홉(라우터)의 IP 주소와 응답 시간이 출력됩니다.
1 192.168.1.1 1.234 ms 0.987 ms 1.102 ms ← 공유기
2 10.0.0.1 5.432 ms 4.987 ms 5.123 ms ← ISP 첫 번째 라우터
3 172.16.0.1 12.345 ms 11.987 ms 12.102 ms ← ISP 백본
4 72.14.204.68 35.678 ms 34.987 ms 35.234 ms ← 해외 라우터
5 142.250.196.110 36.789 ms 35.654 ms 36.123 ms ← Google 서버첫 번째 홉은 보통 자신의 게이트웨이(공유기)입니다. 이후 ISP의 라우터들을 거치고, 최종적으로 구글의 서버에 도달합니다. 각 홉에 세 개의 시간이 표시되는 것은 기본 설정에서 traceroute가 홉마다 여러 개의 probe를 보내기 때문입니다.
traceroute의 동작 원리
traceroute의 원리는 TTL(Time To Live)을 활용한 것입니다.
TTL이 1인 패킷을 보내면 첫 번째 라우터에서 만료되고, 그 라우터가 보통 TTL 초과 메시지(ICMP Time Exceeded)를 돌려보냅니다. TTL을 2로 보내면 두 번째 라우터에서 만료됩니다. 이 과정을 반복하면 응답을 허용한 홉을 하나씩 발견할 수 있습니다. Linux/macOS traceroute는 기본적으로 UDP probe를 쓰는 경우가 많고, Windows tracert는 ICMP Echo를 사용합니다. 옵션에 따라 ICMP, UDP, TCP 방식으로 바꿀 수 있습니다.
특정 홉에서 * * *가 표시되면 해당 probe에 대한 응답을 받지 못했다는 뜻입니다. ICMP 응답 차단, rate limit, 패킷 손실, 되돌아오는 경로 문제, probe 방식 차이 등 여러 원인이 있을 수 있습니다. 이것이 반드시 장애를 의미하는 것은 아닙니다.
traceroute 결과 분석
traceroute 출력에서 문제를 진단하는 방법을 알아봅시다.
핵심 원칙: 지연이 특정 홉에서만 높고 이후에 정상이면 그 장비가 진단 응답을 낮은 우선순위로 처리했을 가능성이 큽니다. 지연이나 손실이 특정 홉부터 이후 홉까지 누적되면 그 구간을 우선 의심합니다.
라우팅 테이블 읽는 법
자신의 컴퓨터에서도 라우팅 테이블을 확인할 수 있습니다.
route printip routedefault via 192.168.1.1 dev eth0 proto dhcp metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100
10.0.0.0/8 via 192.168.1.2 dev eth0 proto static metric 50
172.16.0.0/12 via 192.168.1.3 dev eth1 proto ospf metric 110각 필드의 의미를 해석해 봅시다.
| 필드 | 설명 | 예시 |
|---|---|---|
| default | 디폴트 라우트 (0.0.0.0/0) | 일치하는 경로가 없을 때 사용 |
| via | 다음 홉(Next Hop) IP | 192.168.1.1 |
| dev | 출력 인터페이스 | eth0, eth1, wlan0 |
| proto | 경로 학습 방법 | kernel(직접), dhcp, static, ospf |
| scope link | 직접 연결된 네트워크 | 게이트웨이 불필요 |
| src | 해당 경로 사용 시 출발지 IP | 192.168.1.100 |
| metric | 경로 우선순위 (낮을수록 우선) | 100 |
첫 번째 줄은 디폴트 라우트입니다. 특별히 일치하는 경로가 없는 모든 패킷은 192.168.1.1(게이트웨이)로 보내라는 의미입니다. DHCP로 자동 설정되었고 메트릭은 100입니다.
두 번째 줄은 192.168.1.0/24 네트워크에 대한 경로입니다. 이 네트워크는 eth0 인터페이스에 직접 연결되어 있으므로, 게이트웨이를 거치지 않고 직접 전달하라는 의미입니다.
TTL과 ICMP
TTL(Time To Live)은 IP 패킷 헤더에 포함된 값으로, 패킷이 네트워크에서 무한히 떠돌아다니는 것을 방지합니다.
패킷이 라우터를 하나 지날 때마다 TTL이 1씩 감소합니다. TTL이 0이 되면 해당 라우터는 패킷을 폐기하고, 보통 송신자에게 ICMP Time Exceeded 메시지를 보냅니다. 실제로는 장비 정책, rate limit, 방화벽, 되돌아오는 경로 문제 때문에 이 응답이 보이지 않을 수 있습니다.
| OS / 장비 | 기본 TTL | 용도 |
|---|---|---|
| Linux | 64 | 서버, 컨테이너 |
| Windows | 128 | 데스크톱, 서버 |
| macOS | 64 | 데스크톱, 개발 |
| Cisco 라우터 | 255 | 네트워크 장비 |
| Solaris | 255 | 엔터프라이즈 서버 |
이 차이를 이용하면 상대방의 운영체제를 대략 추측할 수도 있습니다. 예를 들어 ping 응답의 TTL이 118이면, 원래 128에서 시작해 약 10개의 라우터를 거쳤을 가능성을 생각할 수 있습니다. 다만 운영체제 설정, NAT, 방화벽, 로드 밸런서가 TTL을 바꾸거나 숨길 수 있으므로 확정 근거로 쓰면 안 됩니다.
ICMP(Internet Control Message Protocol)는 IP 네트워크에서 제어 메시지와 오류 메시지를 전달하는 프로토콜입니다.
| ICMP 타입 | 이름 | 용도 |
|---|---|---|
| Type 0 | Echo Reply | ping 응답 |
| Type 3 | Destination Unreachable | 목적지 도달 불가 (코드로 세분화) |
| Type 5 | Redirect | 더 좋은 경로 알림 |
| Type 8 | Echo Request | ping 요청 |
| Type 11 | Time Exceeded | TTL 만료 (traceroute 동작 기반) |
| Type 30 | Traceroute | 과거 확장 traceroute, 현재는 deprecated |
ICMP는 데이터 전송을 위한 프로토콜이 아니라 진단과 제어를 위한 프로토콜입니다. 하지만 네트워크 문제를 분석할 때 빠질 수 없는 존재입니다.
ping 심화 활용
단순히 ping google.com을 넘어, ping의 다양한 옵션을 활용한 진단법을 알아봅시다.
#!/bin/bash
# === ping 심화 진단 ===
echo "=== 기본 ping (4패킷) ==="
ping -c 4 google.com
echo ""
echo "=== MTU 확인 (Don't Fragment + 크기 지정) ==="
# Linux: -M do (Don't Fragment), -s (페이로드 크기)
# 1472 = 1500(MTU) - 20(IP헤더) - 8(ICMP헤더)
ping -c 1 -M do -s 1472 google.com
# 성공하면 MTU가 1500 이상
# "Frag needed" 오류 → 경로상 MTU가 1500 미만
echo ""
echo "=== 응답 시간 통계 ==="
ping -c 20 google.com | tail -3
# rtt min/avg/max/mdev = 2.123/3.456/15.789/2.345 ms
# mdev(표준편차)가 크면 → 네트워크 불안정 (jitter 높음)
echo ""
echo "=== 특정 인터페이스에서 ping ==="
ping -c 4 -I eth0 8.8.8.8
echo ""
echo "=== TTL 지정 ping ==="
# TTL을 5로 설정 → 5홉 이내에 도달하는지 확인
ping -c 4 -t 5 google.com
echo ""
echo "=== Windows에서 연속 ping ==="
# ping -t google.com (Ctrl+C로 중지)
# ping -l 1472 -f google.com (MTU 확인, -f = Don't Fragment)64 bytes from 142.250.196.110: icmp_seq=1 ttl=118 time=3.45 ms
해석
64 bytes : 응답 데이터 크기
icmp_seq=1 : 1번째 패킷 (연속 번호)
ttl=118 : 128 - 118 = 10홉 거침 (Windows 서버 추정)
time=3.45 ms : 왕복 시간 (RTT)
통계
min = 2.1ms : 최소 RTT (네트워크 최적 상태)
avg = 3.5ms : 평균 RTT (일반적 성능)
max = 15.8ms : 최대 RTT (일시적 혼잡)
mdev = 2.3ms : 편차 (jitter, 낮을수록 안정)
packet loss
0% = 정상
1-5% = 경미한 문제 (무선 네트워크에서 흔함)
>5% = 품질 문제 가능성 큼 (링크와 경로 확인 필요)비대칭 라우팅 문제
네트워크에서 종종 발생하는 비직관적인 상황 하나를 짚어 두겠습니다.
A에서 B로 가는 경로와 B에서 A로 돌아오는 경로가 다를 수 있습니다. 이것을 비대칭 라우팅(Asymmetric Routing)이라고 합니다.
비대칭 라우팅 자체는 문제가 아닙니다. 인터넷에서는 매우 흔한 현상입니다. 하지만 상태 기반 방화벽(Stateful Firewall)을 사용하는 환경에서는 문제가 됩니다.
이런 경우 방화벽 간에 세션 정보를 동기화하거나, 라우팅을 대칭적으로 조정해야 합니다. 클라우드 환경에서 다중 가용 영역(AZ)을 사용할 때 종종 마주치는 문제입니다.
MTR: traceroute + ping의 결합
MTR(My Traceroute)은 traceroute와 ping을 결합한 도구입니다. 각 홉에 대해 지속적으로 패킷을 보내며 실시간 통계를 수집합니다.
# 기본 사용
mtr google.com
# 리포트 모드 (100패킷 후 결과 출력)
mtr -r -c 100 google.com
# TCP 모드 (ICMP 차단 환경에서 유용)
mtr -T -P 443 google.com
# JSON 출력 (자동화용)
mtr -j -c 50 google.comMTR이 traceroute보다 유용한 이유는 시간에 따른 변화를 볼 수 있기 때문입니다. 일시적인 패킷 손실인지 지속적인 문제인지 구별할 수 있습니다. 단, 중간 홉 하나에서만 손실률이 높고 이후 홉은 정상이라면, 그 장비가 진단 응답만 제한하는 것일 수 있습니다. 실제 장애는 보통 특정 홉 이후의 모든 홉에서 손실이나 지연이 함께 누적될 때 의심합니다.
네트워크 경로 진단 종합 가이드
import subprocess
import re
import sys
import statistics
def run_ping(host, count=10):
"""ping 테스트 수행 및 결과 분석"""
cmd = ["ping", "-c", str(count), host]
if sys.platform == "win32":
cmd = ["ping", "-n", str(count), host]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
output = result.stdout
# RTT 시간 파싱
if sys.platform == "win32":
times = re.findall(r'time[=<](\d+)ms', output)
else:
times = re.findall(r'time=(\d+\.?\d*)', output)
times = [float(t) for t in times]
if not times:
return {"host": host, "status": "unreachable", "loss": 100}
# 패킷 손실률 계산
loss_match = re.search(r'(\d+)% packet loss', output)
loss = int(loss_match.group(1)) if loss_match else 0
return {
"host": host,
"status": "ok" if loss < 5 else "degraded" if loss < 20 else "critical",
"loss": loss,
"min_rtt": min(times),
"avg_rtt": statistics.mean(times),
"max_rtt": max(times),
"jitter": statistics.stdev(times) if len(times) > 1 else 0,
"samples": len(times),
}
def diagnose_path(host):
"""경로 진단 수행"""
print(f"=== {host} 경로 진단 ===\n")
# 1. ping 테스트
ping_result = run_ping(host)
print(f"[Ping] 상태: {ping_result['status']}")
if ping_result["status"] != "unreachable":
print(f" 손실률: {ping_result['loss']}%")
print(f" RTT: min={ping_result['min_rtt']:.1f}ms "
f"avg={ping_result['avg_rtt']:.1f}ms "
f"max={ping_result['max_rtt']:.1f}ms")
print(f" Jitter: {ping_result['jitter']:.1f}ms")
# 2. 진단 결과 해석
print(f"\n[진단]")
if ping_result["status"] == "unreachable":
print(" ✗ 호스트 도달 불가")
print(" → DNS 확인, 방화벽 확인, 라우팅 확인 필요")
elif ping_result["loss"] > 0:
print(f" △ 패킷 손실 {ping_result['loss']}% 감지")
print(" → MTR로 손실 구간 특정 권장")
elif ping_result["jitter"] > 10:
print(f" △ 높은 Jitter ({ping_result['jitter']:.1f}ms)")
print(" → 네트워크 혼잡 또는 무선 간섭 가능성")
else:
print(" ✓ 네트워크 상태 양호")
# 주요 목적지 진단
targets = ["8.8.8.8", "1.1.1.1"]
for target in targets:
diagnose_path(target)
print()실무 라우팅 문제 체크리스트
| 증상 | 가능한 원인 | 진단 도구 | 해결 방법 |
|---|---|---|---|
| 완전한 연결 불가 | 디폴트 라우트 누락 | ip route show | 디폴트 게이트웨이 설정 |
| 특정 대역만 불가 | 라우팅 테이블 누락 | ip route get [IP] | 정적 경로 추가 또는 동적 프로토콜 확인 |
| 간헐적 패킷 손실 | 링크 혼잡 / 장비 불안정 | mtr -r -c 200 | 대역폭 증설, 장비 교체 |
| 높은 지연 | 비효율적 경로 | traceroute | 라우팅 정책 조정 |
| 비대칭 경로 차단 | 방화벽 세션 불일치 | traceroute 양방향 | 방화벽 세션 동기화 |
| 라우팅 루프 | 경로 수렴 실패 | traceroute (IP 반복) | 라우팅 프로토콜 설정 확인 |
| MTU 관련 장애 | 경로상 MTU 불일치 | ping -M do -s 1472 | Path MTU Discovery 확인, MSS 조정 |
다음 장에서는 네트워크 계층 위에서 프로세스 간의 안정적인 통신을 보장하는 TCP를 자세히 살펴보겠습니다.