라우팅의 기본 개념
IP 주소를 통해 목적지를 식별할 수 있다는 것을 배웠습니다. 하지만 어디로 보내야 하는지 아는 것과 실제로 어떤 경로로 보내는지는 다른 문제입니다.
서울에 있는 내 컴퓨터가 미국 버지니아의 AWS 서버에 패킷을 보낼 때, 그 패킷은 수십 개의 라우터를 거쳐야 합니다. 각 라우터에서 다음에는 어디로 보내지?라는 결정이 이루어지고, 이 결정들이 연쇄적으로 이어져 최종 목적지에 도달합니다.
이 과정이 라우팅(Routing)입니다.
서울 PC ──→ [R1] ───→ [R2] ───→ [R3] ──→ ... ──→ [Rn] ──→ AWS 버지니아
│ │ │ │
▼ ▼ ▼ ▼
"다음은 "다음은 "다음은 "직접
R2로" R3로" R4로" 연결됨"
각 라우터가 독립적으로 "다음 홉"을 결정하는 분산 의사결정라우팅이 없다면 모든 통신은 같은 네트워크 안에서만 가능합니다. 내 컴퓨터와 같은 공유기에 연결된 장치와만 통신할 수 있다면, 인터넷이라는 개념 자체가 성립하지 않습니다. 라우팅은 전 세계의 개별 네트워크를 하나로 연결하는 메커니즘입니다.
라우터의 역할
라우터(Router)는 서로 다른 네트워크를 연결하고, 패킷의 목적지 IP 주소를 보고 최적의 다음 경유지를 결정하는 장치입니다.
스위치가 MAC 주소를 기반으로 같은 네트워크 안에서 프레임을 전달하는 데 특화되어 있다면, 라우터는 IP 주소를 기반으로 네트워크 간의 패킷 전달을 담당합니다. 2계층(데이터 링크)과 3계층(네트워크)의 역할 차이가 여기서 명확히 드러납니다.
┌─────────────────────────────────────────────────────┐
│ 네트워크 A (192.168.1.0/24) │
│ PC1 ──┐ │
│ PC2 ──┤── [스위치] ──── eth0 [라우터] eth1 ──── │
│ PC3 ──┘ (MAC 기반) │ (IP 기반) │ │
│ 같은 네트워크 │ │ │
│ 안에서 전달 │ │ │
└────────────────────────────┼──────────────┼─────────┘
│ │
라우팅 테이블 참조 다른 네트워크로 전달
│ │
┌────────────────────────────┼──────────────┼──────────┐
│ 네트워크 B (10.0.0.0/24) │
│ [스위치] ── Server1 │
│ ── Server2 │
└──────────────────────────────────────────────────────┘라우터가 패킷을 받으면 다음 과정을 수행합니다. 패킷의 목적지 IP 주소를 확인하고, 자신의 라우팅 테이블을 참조하여 그 목적지로 가기 위해 패킷을 어디로 보내야 하는지 결정합니다. 그리고 해당 인터페이스로 패킷을 전달합니다. 이때 프레임의 MAC 주소는 다음 홉(Next Hop)의 MAC 주소로 다시 작성됩니다.
| 단계 | 라우터 동작 | 설명 |
|---|---|---|
| 1 | 프레임 수신 | 이더넷 프레임의 목적지 MAC이 자신이면 수신 |
| 2 | L2 헤더 제거 | 이더넷 헤더를 벗겨 IP 패킷 추출 |
| 3 | 라우팅 테이블 조회 | 목적지 IP로 다음 홉과 출력 인터페이스 결정 |
| 4 | TTL 감소 | TTL을 1 감소, 0이면 패킷 폐기 + ICMP 전송 |
| 5 | L2 헤더 재작성 | 다음 홉의 MAC 주소로 새 이더넷 헤더 생성 |
| 6 | 프레임 전송 | 결정된 인터페이스로 프레임 전달 |
핵심은 5단계입니다. IP 헤더의 출발지/목적지 IP는 변하지 않지만, 이더넷 헤더의 MAC 주소는 매 홉마다 변합니다. IP는 end-to-end 식별자이고, MAC은 hop-by-hop 식별자입니다.
라우팅 테이블 구조
라우팅 테이블은 "어떤 목적지 네트워크에 대해 어떤 경로로 보내야 하는가"를 기록한 표입니다. 라우팅의 핵심입니다.
┌──────────────────────────────────────────────────────────────────┐
│ 라우팅 테이블 │
├──────────────────┬──────────────┬───────────┬────────┬───────────┤
│ 목적지 네트워크 │ 다음 홉 │ 인터페이스│ 메트릭 │ 소스 │
├──────────────────┼──────────────┼───────────┼────────┼───────────┤
│ 192.168.1.0/24 │ directly │ eth0 │ 0 │ Connected │
│ 10.0.0.0/8 │ 192.168.1.2 │ eth0 │ 10 │ OSPF │
│ 172.16.0.0/16 │ 192.168.1.3 │ eth0 │ 20 │ OSPF │
│ 172.16.5.0/24 │ 192.168.1.4 │ eth1 │ 15 │ Static │
│ 0.0.0.0/0 │ 192.168.1.1 │ eth0 │ 100 │ Static │
└──────────────────┴──────────────┴───────────┴────────┴───────────┘라우팅 테이블의 각 항목은 주로 다음 정보를 담고 있습니다.
-
목적지 네트워크(Destination Network): 어떤 네트워크로 향하는 패킷인지를 나타냅니다. CIDR 표기로 작성됩니다(예: 10.0.0.0/8).
-
다음 홉(Next Hop): 해당 목적지로 가기 위해 패킷을 보내야 하는 다음 라우터의 IP 주소입니다. 직접 연결된 네트워크라면 directly connected로 표시됩니다.
-
인터페이스(Interface): 패킷을 내보내야 하는 라우터의 물리적/논리적 포트입니다.
-
메트릭(Metric): 경로의 비용을 나타내는 값입니다. 목적지까지 여러 경로가 있을 때, 메트릭이 가장 낮은 경로가 선택됩니다.
-
소스(Source): 이 경로가 어떻게 학습되었는지를 나타냅니다. Connected(직접 연결), Static(수동), OSPF/BGP(동적 프로토콜) 등이 있습니다.
최장 접두어 매칭(Longest Prefix Match)
라우터가 패킷의 목적지 IP에 대해 테이블을 조회할 때, 가장 구체적으로 일치하는 항목이 선택됩니다. 이것을 최장 접두어 매칭(Longest Prefix Match)이라고 합니다.
목적지 IP: 172.16.5.100
라우팅 테이블:
① 172.16.0.0/16 → 다음 홉: 192.168.1.3 (16비트 일치)
② 172.16.5.0/24 → 다음 홉: 192.168.1.4 (24비트 일치) ★ 선택
③ 0.0.0.0/0 → 다음 홉: 192.168.1.1 (0비트 일치)
/24가 /16보다 더 구체적이므로 ②번 경로를 선택왜 가장 긴 접두어를 선택할까요? 더 구체적인 경로가 더 정확한 경로일 가능성이 높기 때문입니다. /24는 256개의 IP만 포함하지만, /16은 65,536개를 포함합니다. 좁은 범위로 지정된 경로가 해당 네트워크에 대해 더 최적화된 경로일 것입니다.
이 원리를 프로그래밍 관점에서 보면 이렇습니다.
import ipaddress
def longest_prefix_match(dest_ip, routing_table):
"""라우팅 테이블에서 Longest Prefix Match 수행"""
dest = ipaddress.ip_address(dest_ip)
best_match = None
best_prefix_len = -1
for network_str, next_hop, interface in routing_table:
network = ipaddress.ip_network(network_str)
if dest in network and network.prefixlen > best_prefix_len:
best_match = (network_str, next_hop, interface)
best_prefix_len = network.prefixlen
return best_match
# 라우팅 테이블: (목적지 네트워크, 다음 홉, 인터페이스)
table = [
("192.168.1.0/24", "directly", "eth0"),
("10.0.0.0/8", "192.168.1.2", "eth0"),
("172.16.0.0/16", "192.168.1.3", "eth0"),
("172.16.5.0/24", "192.168.1.4", "eth1"),
("0.0.0.0/0", "192.168.1.1", "eth0"),
]
test_ips = ["172.16.5.100", "172.16.10.1", "8.8.8.8", "192.168.1.50"]
for ip in test_ips:
result = longest_prefix_match(ip, table)
if result:
print(f"{ip:20s} => {result[0]:20s} via {result[1]:15s} ({result[2]})")
else:
print(f"{ip:20s} => 경로 없음 (패킷 폐기)")
# 출력:
# 172.16.5.100 => 172.16.5.0/24 via 192.168.1.4 (eth1)
# 172.16.10.1 => 172.16.0.0/16 via 192.168.1.3 (eth0)
# 8.8.8.8 => 0.0.0.0/0 via 192.168.1.1 (eth0)
# 192.168.1.50 => 192.168.1.0/24 via directly (eth0)실제 라우터에서는 이 검색이 초당 수백만 패킷에 대해 수행되므로, 선형 검색이 아닌 Trie(트라이) 자료구조를 사용하여 O(32) — IP 주소 비트 길이 — 시간에 검색을 완료합니다.
정적 라우팅 vs 동적 라우팅
라우팅 테이블을 만드는 방법은 크게 두 가지입니다.
정적 라우팅
┌─────────────┐
│ 관리자가 │
│ 수동 설정 │
│ │
│ R1: 고정 │
│ R2: 고정 │
│ R3: 고정 │
│ │
│ 장애 시 │
│ 수동 변경 │
└─────────────┘
동적 라우팅
┌─────────────┐
│ 라우터들이 │
│ 자동 교환 │
│ │
│ R1 ⇄ R2 │
│ R2 ⇄ R3 │
│ R3 ⇄ R1 │
│ │
│ 장애 시 │
│ 자동 우회 │
└─────────────┘| 비교 항목 | 정적 라우팅 | 동적 라우팅 |
|---|---|---|
| 경로 설정 | 관리자 수동 입력 | 프로토콜이 자동 계산 |
| 장애 대응 | 수동 변경 필요 | 자동 우회 경로 탐색 |
| 리소스 소비 | 없음 | CPU, 메모리, 대역폭 사용 |
| 확장성 | 소규모만 적합 | 대규모 네트워크 지원 |
| 보안 | 외부 경로 정보 수신 없음 | 경로 위변조 가능성 존재 |
| 적용 환경 | 스텁 네트워크, 소규모 사무실 | ISP, 데이터센터, 인터넷 |
| 설정 난이도 | 낮음 | 높음 |
정적 라우팅(Static Routing)은 관리자가 목적지와 경로를 수동으로 설정하는 방식입니다. 네트워크 구성이 단순하고 변경이 드문 환경에 적합합니다. 장점은 설정이 직관적이고, 라우팅 프로토콜의 오버헤드가 없다는 것입니다. 단점은 네트워크 변경 시 수동으로 갱신해야 하고, 장애 발생 시 자동 우회가 불가능하다는 것입니다.
동적 라우팅(Dynamic Routing)은 라우터들이 라우팅 프로토콜을 통해 서로 경로 정보를 교환하고, 최적 경로를 자동으로 계산하는 방식입니다. 네트워크 규모가 크고 변경이 빈번한 환경, 즉 인터넷에서 사용됩니다. 경로에 장애가 발생하면 자동으로 대체 경로를 찾습니다. 다만 라우팅 프로토콜이 CPU와 대역폭을 소비하고, 설정이 복잡합니다.
실무에서는 두 가지를 함께 사용합니다. 핵심 네트워크 간에는 OSPF 같은 동적 프로토콜을 사용하고, 특정 목적지에 대해 정적 경로를 추가하여 동적 경로보다 우선하게 만드는 식입니다. 이런 정적 경로를 플로팅 스태틱 라우트(Floating Static Route)라고 부르기도 합니다. 동적 경로가 사라졌을 때 백업으로 작동하도록, 메트릭을 높게 설정한 정적 경로입니다.
디폴트 라우트
라우팅 테이블에 목적지 네트워크에 정확히 일치하는 항목이 없을 때, 마지막 수단으로 사용되는 경로가 디폴트 라우트(Default Route)입니다. 0.0.0.0/0으로 표기하며, 다른 모든 목적지에 해당하지 않는 패킷은 여기로 보내라는 의미입니다.
패킷 도착 (목적지: 8.8.8.8)
│
▼
┌─────────────────────┐
│ 192.168.1.0/24? │──── 불일치
│ 10.0.0.0/8? │──── 불일치
│ 172.16.0.0/16? │──── 불일치
│ 172.16.5.0/24? │──── 불일치
│ 0.0.0.0/0? ★ │──── 일치! → 게이트웨이 192.168.1.1로 전달
└─────────────────────┘
0.0.0.0/0은 프리픽스 길이가 0이므로 모든 IP에 매칭
= "나머지 전부" 라는 의미가정의 컴퓨터가 가진 라우팅 테이블을 보면, 대부분의 트래픽이 디폴트 라우트를 통해 공유기(게이트웨이)로 전달됩니다. 컴퓨터 입장에서는 인터넷에 있는 모든 목적지를 알 필요 없이, 일단 게이트웨이에 보내면 게이트웨이가 알아서 해준다는 것입니다.
이것은 조직 네트워크에서도 마찬가지입니다. 내부 네트워크의 경로만 구체적으로 설정하고, 나머지는 디폴트 라우트로 상위 라우터에 위임합니다. 상위 라우터는 또 자신의 테이블을 참조하고, 이 과정이 반복되어 최종적으로 목적지 네트워크에 도달합니다.
라우팅 테이블 확인 실습
직접 자신의 시스템에서 라우팅 테이블을 확인해 봅시다.
#!/bin/bash
# === 라우팅 테이블 확인 ===
echo "=== 현재 라우팅 테이블 ==="
# Linux
ip route show
# 또는 전통적인 명령
# route -n
echo ""
echo "=== 기본 게이트웨이 확인 ==="
ip route show default
echo ""
echo "=== 특정 목적지의 경로 확인 ==="
# 8.8.8.8로 가는 경로 추적
ip route get 8.8.8.8
echo ""
echo "=== 인터페이스별 라우팅 ==="
ip route show dev eth0
echo ""
echo "=== Windows에서 확인 (참고) ==="
# route print
# netstat -rn
echo ""
echo "=== 정적 경로 추가/삭제 예시 ==="
# 추가: 10.10.0.0/16 네트워크를 192.168.1.2 경유로 설정
# sudo ip route add 10.10.0.0/16 via 192.168.1.2 dev eth0
# 삭제:
# sudo ip route del 10.10.0.0/16
# 디폴트 라우트 변경:
# sudo ip route replace default via 192.168.1.254 dev eth0===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 25
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
192.168.1.0 255.255.255.0 On-link 192.168.1.100 281
192.168.1.100 255.255.255.255 On-link 192.168.1.100 281
192.168.1.255 255.255.255.255 On-link 192.168.1.100 281
224.0.0.0 240.0.0.0 On-link 192.168.1.100 281
===========================================================================Windows의 On-link는 Linux의 directly connected와 같은 의미입니다. 해당 네트워크가 인터페이스에 직접 연결되어 있어서 게이트웨이를 거치지 않고 직접 전달한다는 뜻입니다.
라우팅 과정 전체 흐름
패킷이 출발지에서 목적지까지 실제로 어떻게 전달되는지, 단계별로 추적해 봅시다.
PC-A R1 R2 Server
192.168.1.10 eth0: 192.168.1.1 eth0: 10.0.1.1 10.0.2.50
eth1: 10.0.1.2 eth1: 10.0.2.1
Step 1: PC-A → R1
┌──────────────────────────────────────┐
│ Ethernet: dst=R1-eth0-MAC │
│ IP: src=192.168.1.10 │
│ dst=10.0.2.50 │
│ Data: HTTP GET /index.html │
└──────────────────────────────────────┘
PC-A의 라우팅 테이블: 0.0.0.0/0 via 192.168.1.1
→ 목적지가 같은 서브넷이 아니므로 게이트웨이로 전달
Step 2: R1에서 처리
R1 라우팅 테이블: 10.0.2.0/24 via 10.0.1.1 dev eth1
→ TTL 64→63, MAC 재작성 (src=R1-eth1-MAC, dst=R2-eth0-MAC)
Step 3: R1 → R2
┌──────────────────────────────────────┐
│ Ethernet: dst=R2-eth0-MAC ← 변경됨 │
│ IP: src=192.168.1.10 ← 동일 │
│ dst=10.0.2.50 ← 동일 │
│ TTL=63 ← 감소 │
│ Data: HTTP GET /index.html │
└──────────────────────────────────────┘
Step 4: R2에서 처리
R2 라우팅 테이블: 10.0.2.0/24 directly connected on eth1
→ TTL 63→62, MAC 재작성 (dst=Server-MAC)
→ ARP로 10.0.2.50의 MAC 주소 확인 후 직접 전달이 과정에서 핵심 원칙 두 가지를 확인할 수 있습니다. 첫째, IP 주소(L3)는 출발지에서 목적지까지 변하지 않습니다(NAT 제외). 둘째, MAC 주소(L2)는 매 홉마다 변합니다. 이 L2/L3 분리 원칙이 인터넷 라우팅의 근간입니다.
Administrative Distance
하나의 라우터에서 같은 목적지에 대해 여러 소스(정적, OSPF, BGP 등)로부터 경로를 학습할 수 있습니다. 이때 어느 소스를 더 신뢰할지 결정하는 값이 Administrative Distance(AD)입니다.
| 경로 소스 | AD 값 | 설명 |
|---|---|---|
| Connected | 0 | 직접 연결된 네트워크, 가장 신뢰 |
| Static | 1 | 관리자가 수동 설정, 의도적 경로 |
| EIGRP Summary | 5 | EIGRP 요약 경로 |
| eBGP | 20 | 외부 BGP, AS 간 학습 |
| OSPF | 110 | 링크 상태 기반 내부 라우팅 |
| RIP | 120 | 거리 벡터 기반 내부 라우팅 |
| iBGP | 200 | 내부 BGP, AS 내 학습 |
| Unknown | 255 | 신뢰할 수 없음, 사용 불가 |
AD 값이 낮을수록 우선순위가 높습니다. 같은 목적지에 대해 OSPF(AD=110)와 RIP(AD=120)이 모두 경로를 알려준다면, OSPF 경로가 선택됩니다. AD가 같으면 그 다음으로 메트릭을 비교합니다.
이 개념은 라우팅 프로토콜 간의 신뢰도 순위입니다. Connected가 0인 이유는 직접 연결된 네트워크는 의심할 여지가 없기 때문이고, Static이 1인 이유는 관리자가 의도적으로 설정한 경로이므로 자동 학습보다 우선해야 하기 때문입니다.
다음 절에서는 동적 라우팅의 핵심인 라우팅 프로토콜, 특히 RIP, OSPF, BGP를 살펴보겠습니다.