BGP
Border Gateway Protocol
인터넷 라우팅 프로토콜. AS 간 경로 교환.
Border Gateway Protocol
인터넷 라우팅 프로토콜. AS 간 경로 교환.
BGP(Border Gateway Protocol)는 인터넷을 구성하는 수만 개의 자율시스템(AS, Autonomous System) 간에 라우팅 정보를 교환하는 프로토콜입니다. 인터넷의 "우체국 시스템"이라 불리며, 전 세계 네트워크가 서로 통신할 수 있도록 최적의 경로를 결정합니다. DNS가 인터넷의 전화번호부라면, BGP는 실제 데이터가 이동하는 도로를 설계하는 역할을 합니다.
BGP는 크게 두 종류로 나뉩니다. eBGP(External BGP)는 서로 다른 AS 간에 라우팅 정보를 교환하며, 일반적으로 ISP와 기업, 또는 ISP 간의 피어링에 사용됩니다. iBGP(Internal BGP)는 같은 AS 내부에서 외부로부터 학습한 경로를 전파하는 데 사용됩니다. AS 번호(ASN)는 IANA에서 할당하며, 2바이트(0-65535)에서 4바이트(최대 42억)로 확장되었습니다.
BGP의 경로 선택 알고리즘은 여러 속성을 기반으로 최적 경로를 결정합니다. LOCAL_PREF(높을수록 선호), AS_PATH(짧을수록 선호), MED(낮을수록 선호), ORIGIN(IGP > EGP > incomplete), WEIGHT(Cisco 전용) 등의 속성을 순차적으로 비교합니다. 이 복잡한 알고리즘 덕분에 네트워크 관리자는 트래픽 흐름을 세밀하게 제어할 수 있습니다.
BGP의 취약점으로 인한 대형 장애가 반복적으로 발생합니다. 2021년 10월 Facebook(Meta)은 BGP 설정 오류로 약 6시간 동안 전 세계적으로 서비스가 중단되었고, 수십억 달러의 손실이 발생했습니다. BGP Hijacking은 악의적인 AS가 잘못된 경로를 광고하여 트래픽을 가로채는 공격으로, 2018년 Amazon Route 53 하이재킹으로 약 15만 달러의 암호화폐가 탈취되기도 했습니다. 이를 방지하기 위해 RPKI(Resource Public Key Infrastructure)와 ROA(Route Origin Authorization) 등의 보안 메커니즘이 도입되고 있습니다.
# pip install pybgpstream (BGP 데이터 분석)
from pybgpstream import BGPStream
# BGP 업데이트 스트림 분석
stream = BGPStream(
from_time="2021-10-04 15:00:00",
until_time="2021-10-04 22:00:00",
collectors=["route-views2", "rrc00"],
record_type="updates",
filter="prefix more 32.0.0.0/8" # Facebook 관련 프리픽스
)
# BGP 메시지 파싱
for elem in stream:
if elem.type == "A": # Announcement
print(f"Announce: {elem.fields['prefix']}")
print(f" AS Path: {elem.fields['as-path']}")
print(f" Origin AS: {elem.peer_asn}")
elif elem.type == "W": # Withdrawal
print(f"Withdraw: {elem.fields['prefix']}")
# ExaBGP로 BGP 스피커 구현 (exabgp.conf)
"""
neighbor 192.168.1.1 {
router-id 10.0.0.1;
local-address 10.0.0.2;
local-as 65001;
peer-as 65002;
static {
route 203.0.113.0/24 next-hop self;
route 198.51.100.0/24 next-hop self community [65001:100];
}
}
"""
# RPKI 검증 (routinator 사용)
import requests
def check_rpki_validity(prefix, asn):
"""RPKI ROA 검증"""
url = f"https://rpki-validator.ripe.net/api/v1/validity/{asn}/{prefix}"
response = requests.get(url)
data = response.json()
return data.get("validated_route", {}).get("validity", {}).get("state")
# 예시: AS15169(Google)의 8.8.8.0/24 검증
result = check_rpki_validity("8.8.8.0/24", 15169)
print(f"RPKI Status: {result}") # valid, invalid, or not-found
# BGP 라우팅 테이블 조회 (Looking Glass)
# 공개 BGP Looking Glass 서비스 사용
# whois로 AS 정보 조회
whois -h whois.radb.net AS15169 # Google AS 정보
whois -h whois.radb.net 8.8.8.0/24 # IP 프리픽스 소유자
# bgpq4로 프리픽스 리스트 생성 (ISP 필터링용)
bgpq4 -4 -l prefix_list AS-GOOGLE # Google의 IPv4 프리픽스
# RIPE RIS Live BGP 스트림 (WebSocket)
websocat "wss://ris-live.ripe.net/v1/ws/?client=cli-example" | \
jq 'select(.data.type == "UPDATE")'
# BGP 경로 추적 (traceroute + AS 정보)
mtr --aslookup google.com
# RPKI 검증 상태 확인
curl "https://stat.ripe.net/data/rpki-validation/data.json?resource=8.8.8.0/24&prefix=8.8.8.0/24"
# BGP 업데이트 모니터링 (bgpstream)
bgpreader -w 1633356000,1633377600 \
-c route-views2 \
-p 32.0.0.0/8 \
| head -100
# AS 경로 분석
traceroute -A google.com # AS 번호 표시
# BGP 세션 상태 확인 (Linux FRRouting)
sudo vtysh -c "show bgp summary"
sudo vtysh -c "show ip bgp neighbors"
sudo vtysh -c "show ip bgp"
# Cisco IOS BGP 기본 설정
# BGP 라우터 설정
router bgp 65001 # 자신의 AS 번호
bgp router-id 10.0.0.1 # 라우터 ID
bgp log-neighbor-changes # 네이버 상태 변화 로깅
# eBGP 네이버 설정 (외부 AS)
neighbor 192.168.1.1 remote-as 65002
neighbor 192.168.1.1 description ISP_A
neighbor 192.168.1.1 password MySecretPassword
neighbor 192.168.1.1 ebgp-multihop 2
# iBGP 네이버 설정 (같은 AS)
neighbor 10.0.0.2 remote-as 65001
neighbor 10.0.0.2 update-source Loopback0
neighbor 10.0.0.2 next-hop-self
# 네트워크 광고
network 203.0.113.0 mask 255.255.255.0
# 경로 필터링 (Prefix-list)
neighbor 192.168.1.1 prefix-list ALLOWED-IN in
neighbor 192.168.1.1 prefix-list ALLOWED-OUT out
# Prefix-list 정의
ip prefix-list ALLOWED-IN seq 10 permit 0.0.0.0/0 le 24
ip prefix-list ALLOWED-IN seq 20 deny 0.0.0.0/0 le 32
ip prefix-list ALLOWED-OUT seq 10 permit 203.0.113.0/24
# Route-map으로 LOCAL_PREF 설정
route-map SET-LOCAL-PREF permit 10
set local-preference 200
!
neighbor 192.168.1.1 route-map SET-LOCAL-PREF in
# BGP 상태 확인 명령어
show ip bgp summary # BGP 세션 요약
show ip bgp neighbors # 네이버 상세 정보
show ip bgp # BGP 라우팅 테이블
show ip bgp 8.8.8.0/24 # 특정 프리픽스 경로
clear ip bgp * soft # BGP 세션 소프트 리셋
"BGP Looking Glass로 확인해보니 우리 프리픽스가 업스트림 ISP에서 철회(withdraw)된 것 같습니다. AS Path에서 우리 ASN이 사라졌어요. 피어링 세션 상태를 확인하고, 필요하면 BGP 세션을 hard reset 해봐야 할 것 같습니다."
"최근 BGP Hijacking 시도가 감지되었습니다. RPKI ROA를 설정해서 우리 프리픽스의 origin AS를 인증하고, 업스트림 ISP에 ROV(Route Origin Validation) 활성화를 요청해야 합니다. MANRS 이니셔티브 가입도 검토해 주세요."
"멀티호밍 구성을 위해 두 ISP와 BGP 피어링을 맺고, AS-prepending으로 트래픽 분산을 조절하려고 합니다. 주 ISP에는 LOCAL_PREF 200을, 백업 ISP에는 100을 설정해서 아웃바운드 트래픽 우선순위를 정하고, 인바운드는 AS Path 길이로 제어할 계획입니다."
Facebook 2021년 장애는 설정 변경 스크립트의 버그로 모든 BGP 세션이 끊어져 발생했습니다. 변경 전 반드시 lab 환경에서 테스트하고, 롤백 계획을 수립하세요. 'commit confirm' 같은 자동 롤백 기능을 활용하세요.
필터 없이 BGP 세션을 열면 route leak이나 hijacking에 취약합니다. 반드시 prefix-list와 as-path 필터를 적용하고, bogon 프리픽스(0.0.0.0/8, 10.0.0.0/8, 224.0.0.0/4 등)를 차단하세요.
iBGP는 학습한 경로를 다른 iBGP 피어에게 재광고하지 않습니다(split horizon). N개 라우터가 있으면 N*(N-1)/2 세션이 필요하거나, Route Reflector 또는 Confederation을 구성해야 합니다.
RPKI/ROA로 프리픽스 origin 인증, BGP 세션에 MD5 인증 또는 TCP-AO 적용, GTSM(TTL 보안)으로 원격 세션 스푸핑 방지, maximum-prefix 설정으로 route leak 대응. MANRS(Mutually Agreed Norms for Routing Security) 가이드라인을 따르세요.