라우팅 실습과 진단
traceroute·ping·MTR과 라우팅 테이블로 홉·지연·손실·비대칭 경로를 확인하고 장애 구간을 진단합니다.
라우팅의 이론을 배웠으니, 이제 실제로 패킷이 어떤 경로를 따라 이동하는지 직접 확인해 보겠습니다.
라우팅 경로를 확인하면 네트워크 지연, 우회 경로, 중간 구간 장애를 진단하는 데 도움이 됩니다.
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 출력에서 문제를 진단하는 방법을 알아봅시다.
핵심 원칙: traceroute의 각 RTT는 “그 홉까지의 순수 링크 지연”이 아니라 probe의 왕복 경로, 되돌아오는 경로, 장비의 진단 응답 생성 시간이 섞인 값입니다.
지연이 특정 홉에서만 높고 이후에 정상이면 그 장비가 진단 응답을 낮은 우선순위로 처리했을 가능성이 큽니다.
지연이나 손실이 특정 홉부터 이후 홉과 목적지까지 누적되면 그 구간을 우선 의심합니다.
probe 방식도 결과에 영향을 줍니다.
UDP traceroute, ICMP tracert, TCP 443 traceroute는 방화벽, ACL, 로드밸런서, ECMP 경로 선택에서 서로 다르게 취급될 수 있으므로, 의심 구간은 방식과 시간대를 바꿔 재측정하는 것이 좋습니다.
라우팅 테이블 읽는 법
자신의 컴퓨터에서도 라우팅 테이블을 확인할 수 있습니다.
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이 목록은 필드 해석용 예시입니다. 마지막 경로가 사용하는 eth1의 연결 경로는 생략되어 있으므로 이 표만으로 다음 홉 도달성을 확인할 수는 없습니다.
| 필드 | 의미와 예 |
|---|---|
| default | 0.0.0.0/0 · 더 구체적인 경로가 없을 때 사용 |
| via | 다음 홉 IP · 192.168.1.1 |
| dev | 출력 인터페이스 · eth0, eth1, wlan0 |
| proto | 경로의 출처 · kernel, dhcp, static, ospf 등 |
| scope link | 같은 링크에서 직접 도달하는 범위 |
| src | 선호 출발지 IP · 192.168.1.100 |
| metric | 비교 가능한 경로의 우선순위 값 · 일반적으로 낮은 값 선호; 최장 접두어보다 앞서 적용하지 않음 |
첫 번째 줄은 디폴트 라우트입니다.
특별히 일치하는 경로가 없는 모든 패킷은 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, 방화벽, 되돌아오는 경로 문제 때문에 이 응답이 보이지 않을 수 있습니다.
| 초기 TTL 예 | 흔히 쓰는 환경 |
|---|---|
| 64 | Linux·macOS |
| 128 | Windows |
| 255 | 일부 네트워크 장비·Solaris 구성 |
위 값은 변경 가능한 설정의 예입니다. 수신 TTL만으로 송신 운영체제나 초기 TTL을 확정할 수 없습니다.
예를 들어 ping 응답의 TTL이 118이면, 원래 128에서 시작해 약 10개의 라우터를 거쳤을 가능성을 생각할 수 있습니다.
다만 운영체제 설정, NAT, 방화벽, 로드 밸런서가 TTL을 바꾸거나 숨길 수 있으므로 확정 근거로 쓰면 안 됩니다.
ICMP(Internet Control Message Protocol)는 IP 네트워크에서 제어 메시지와 오류 메시지를 전달하는 프로토콜입니다.
| IPv4 ICMP | 역할 |
|---|---|
| 0 · Echo Reply | ping 응답 |
| 3 · Destination Unreachable | 도달 불가 · 세부 원인은 코드로 구분 |
| 5 · Redirect | 더 적합한 다음 홉 안내 |
| 8 · Echo Request | ping 요청 |
| 11 · Time Exceeded | TTL 만료 등 · traceroute의 기반 |
| 30 · 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 IPv4: -4, -M do (Don't Fragment), -s (페이로드 크기)
# 1472 = 1500(MTU) - 20(IP헤더) - 8(ICMP헤더)
ping -4 -c 1 -M do -s 1472 google.com
# 성공하면 이 IPv4 probe의 전송 경로에서 1500바이트를 전달함
# "Frag needed" 오류 → 해당 경로의 더 작은 MTU 단서; 무응답만으로는 확정 불가
echo ""
echo "=== 응답 시간 통계 ==="
ping -c 20 google.com | tail -3
# rtt min/avg/max/mdev = 2.123/3.456/15.789/2.345 ms
# mdev가 크면 → 이 RTT 표본의 분산이 큼; 기준선·경로·부하와 비교
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 -4 -l 1472 -f google.com (IPv4 MTU 확인, -f = Don't Fragment)64 bytes from 142.250.196.110: icmp_seq=1 ttl=118 time=3.45 ms
해석
64 bytes : ICMP 헤더 8바이트 + 기본 데이터 56바이트
icmp_seq=1 : 1번째 패킷 (연속 번호)
ttl=118 : 초기값이 128이었다면 약 10홉 감소; OS 확정 불가
time=3.45 ms : 왕복 시간 (RTT)
통계
min = 2.1ms : 수집한 표본의 최소 RTT
avg = 3.5ms : 수집한 표본의 평균 RTT
max = 15.8ms : 수집한 표본의 최대 RTT; 원인은 별도 조사
mdev = 2.3ms : iputils RTT 표본의 모집단 표준편차
packet loss
0% = 이 검사에서 누락 응답 없음; 다른 트래픽 품질까지 보장하지 않음
1-5% = 누락 응답 관측; 서비스 요구와 평소 기준선에 비교
>5% = 같은 기준으로 조사; 모든 환경의 공통 장애 임계값은 아님비대칭 라우팅 문제
네트워크에서 종종 발생하는 비직관적인 상황 하나를 짚어 두겠습니다.
A에서 B로 가는 경로와 B에서 A로 돌아오는 경로가 다를 수 있습니다.
이것을 비대칭 라우팅(Asymmetric Routing)이라고 합니다.
비대칭 라우팅 자체는 문제가 아닙니다.
인터넷에서는 매우 흔한 현상입니다.
서로 다른 상태 기반 방화벽(Stateful Firewall)을 거치고 세션 상태를 공유하지 않는다면, 반환 경로의 정책에 의해 응답이 차단될 수 있습니다.
요청은 방화벽 A를 지나고 응답은 방화벽 B로 돌아오는 예시입니다. A와 B가 상태를 공유하지 않고 B의 정책이 기존 세션을 요구하면 응답이 차단될 수 있습니다. 비대칭 경로 자체가 항상 장애라는 뜻은 아닙니다.
이 조건이 확인되면 방화벽 간 세션 동기화나 대칭 경로 구성 등을 검토합니다.
클라우드 환경에서 다중 가용 영역(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보다 유용한 이유는 시간에 따른 변화를 볼 수 있기 때문입니다.
시간대와 표본 수를 바꿔 일시적 현상과 반복되는 현상을 비교할 수 있습니다.
단, 중간 홉 하나에서만 손실률이 높고 이후 홉은 정상이라면, 그 장비가 진단 응답만 제한하는 것일 수 있습니다.
손실이나 지연 증가가 이후 홉과 목적지에서도 보이면 경로 품질 문제를 조사합니다. 모든 지표가 동시에 나빠져야 하는 것은 아니며, 서로 다른 probe 경로와 ICMP 제한 때문에 특정 링크의 장애를 바로 확정할 수도 없습니다.
다음은 기존 예시 숫자를 두 관측 패턴으로 나누어 읽은 것으로 실제 측정 결과가 아닙니다.
두 행은 서로 다른 설명용 데이터입니다. 각 홉의 Loss는 그 홉을 겨냥한 probe 응답 통계이므로 링크별 전달 손실을 직접 누적한 값이 아닙니다.
| 예시 | 누락 응답 패턴 | 판단 범위 |
|---|---|---|
| 중간 수치와 목적지가 다름 | 중간 홉 40% → 다음 홉 0% → 목적지 12% | 40%가 그대로 누적된 것은 아님. 목적지 12%는 별도로 조사하며 홉 2의 장애로 단정하지 않음 |
| 뒤쪽에도 비슷한 손실 | transit 15% → 목적지 15% | 경로 품질 문제를 조사할 단서. ICMP 제한·반환 경로·다른 probe 흐름도 대조해야 위치를 좁힐 수 있음 |
- 중간 수치와 목적지가 다름
- 누락 응답 패턴: 중간 홉 40% → 다음 홉 0% → 목적지 12%판단 범위: 40%가 그대로 누적된 것은 아님. 목적지 12%는 별도로 조사하며 홉 2의 장애로 단정하지 않음
- 뒤쪽에도 비슷한 손실
- 누락 응답 패턴: transit 15% → 목적지 15%판단 범위: 경로 품질 문제를 조사할 단서. ICMP 제한·반환 경로·다른 probe 흐름도 대조해야 위치를 좁힐 수 있음
따라서 “중간 홉 Loss 60%” 같은 숫자만 보지 말고, 목적지 Loss가 함께 증가하는지 확인해야 합니다.
고정 임계값 하나로 판단하기보다 평소 기준선 대비 증가했는지, 여러 번 재현되는지, 실제 애플리케이션 응답 지연과도 맞물리는지를 함께 봅니다.
네트워크 경로 진단 종합 가이드
다음 원문은 간단한 파싱 실습이며 완성된 진단기는 아닙니다. 영어 출력 패턴만 찾고 Windows 손실 문구를 처리하지 않아 손실률이 0으로 남을 수 있습니다. RTT를 파싱하지 못한 경우도 unreachable로 표시하므로 네트워크 도달 실패와 구분해야 합니다. 명령 없음·시간 초과 예외도 처리하지 않습니다.
jitter 변수는 Python의 표본 표준편차이며 iputils의 mdev나 표준 패킷 지연 변동 지표와 같지 않습니다. 상태 임계값과 조치 문구도 연습용 휴리스틱입니다.
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와 애플리케이션 기준선 비교; 비효율 경로가 원인이면 정책 검토 |
| 비대칭 경로 차단 | 양방향 경로·방화벽 세션·정책 비교; 필요하면 상태 동기화 검토 |
| 루프 의심 | 반복 IP만으로 확정하지 말고 라우팅 상태·수렴 확인 |
| MTU 의심 | IPv4 ping -4 -M do -s 1472와 오류 메시지 확인; PMTUD·캡슐화·MSS 조건 검토 |
traceroute 결과는 TTL 만료, RTT, 손실, 비대칭 경로를 각각 분리해 해석합니다.
다음 장에서는 네트워크 계층 위에서 프로세스 간의 안정적인 통신을 보장하는 TCP를 자세히 살펴보겠습니다.