사전 라우팅 루프
문제

라우팅 루프

gabury1고친 사람 github-actions[bot]

라우팅 루프는 패킷이 목적지 대신 라우터 몇 대 사이를 맴도는 고장입니다. 라우터들이 서로 상대 쪽이 길이라고 믿을 때 생깁니다. 맴도는 패킷은 결국 버려집니다. 그때까지 같은 회선을 몇십 번씩 차지합니다.

쉽고 빠른 이해

라우팅 루프는 패킷이 라우터 사이를 오가며 같은 구간을 맴도는 고장입니다. 라우터 갑은 「그 목적지는 을 쪽」이라고 압니다. 을은 「그 목적지는 갑 쪽」이라고 압니다. 그러면 패킷이 둘 사이를 끝없이 오갑니다.

이 고장을 따로 알아 둘 까닭은 증상이 엉뚱한 곳을 가리키기 때문입니다. 서버도 회선도 멀쩡합니다. 그런데 어느 목적지로만 연결이 안 됩니다. 원인은 장비 고장이 아니라 라우터들이 들고 있는 길 안내표가 서로 어긋난 데 있습니다.

어떻게 도나:

  1. 라우터마다 목적지별로 다음에 넘길 이웃을 적은 표를 들고 있습니다
  2. 두 라우터의 표가 같은 목적지에 대해 서로를 가리킵니다
  3. 패킷은 둘 사이를 오갑니다. 패킷에 적힌 「더 거칠 수 있는 라우터 수」가 바닥나면 버려집니다

무엇이 나빠지나 — 패킷 하나가 같은 회선을 수십 번 지나갑니다. 그만큼 회선이 붐빕니다. 그 회선을 같이 쓰는 다른 통신까지 밀립니다. 목적지로 가려던 연결은 응답 없이 시간 초과로 끝납니다.

상세

라우팅 루프는 패킷이 둘 이상의 라우터 사이를 되풀이해 오가는 고장입니다. 그 라우터들이 같은 목적지에 대해 서로를 다음에 넘길 이웃으로 가리킬 때 생깁니다. 아래에서는 라우터 두 대만 두고 고리가 어떻게 생기는지, 무엇이 그 고리를 끊는지, 왜 표가 어긋나는지를 차례로 봅니다.

다음 홉만 아는 라우터

라우터는 네트워크와 네트워크를 잇는 장비입니다. 패킷을 받으면 목적지 주소를 보고 다음 장비로 넘깁니다. 집의 공유기도, 통신사 망 안의 큰 장비도 이 일을 합니다.

어디로 넘길지는 라우팅 테이블을 보고 정합니다. 라우팅 테이블은 「이 주소 범위로 가는 패킷은 이 이웃에게 넘긴다」를 목적지마다 한 줄씩 적은 표입니다.

표의 한 줄이 가리키는 그 이웃을 다음 홉이라고 부릅니다. 라우터는 목적지까지의 전체 경로를 모릅니다. 자기 표에 적힌 다음 홉 하나만 압니다. 다음 라우터도 자기 표를 보고 또 다음 홉을 고릅니다.

패킷이 라우터를 한 번 거칠 때마다 홉 하나로 셉니다. 경로가 얼마나 긴지도 이 홉 수로 말합니다.

이 방식은 표들이 서로 맞는다는 것을 전제로 합니다. 누구도 전체 경로를 보지 않습니다. 그래서 표끼리 어긋나도 그것을 알아챌 장비가 없습니다.

두 라우터가 서로를 가리킬 때

라우터 갑과 을이 회선 하나로 이어져 있다고 해 봅시다. 갑의 표에는 「목적지 망으로 가는 패킷은 을에게」라고 적혀 있습니다. 을의 표에는 「목적지 망으로 가는 패킷은 갑에게」라고 적혀 있습니다.

목적지 망으로 가는 패킷이 갑에 닿으면 갑은 을에게 넘깁니다. 을은 자기 표를 보고 갑에게 되돌려 보냅니다. 갑은 다시 을에게 넘깁니다. 두 라우터는 저마다 표에 적힌 대로 일했을 뿐입니다.

flowchart TD
    S["보낸 컴퓨터"] --> A["라우터 갑<br/>목적지 망은 을에게"]
    A -->|넘긴다| B["라우터 을<br/>목적지 망은 갑에게"]
    B -->|되돌린다| A
    D["목적지 망"]

그림에서 갑과 을 사이의 두 화살표가 고리를 이룹니다. 목적지 망으로 들어가는 화살표는 어디에도 없습니다.

고리는 셋 이상으로도 생깁니다. 갑이 을에게, 을이 병에게, 병이 다시 갑에게 넘기면 셋이 도는 고리입니다. 몇 대가 얽히든 판정은 같습니다. 한 목적지에 대해 다음 홉을 따라가다가 이미 지난 라우터로 돌아오면 루프입니다.

맴돌기를 끊는 TTL

인터넷의 패킷은 IP(Internet Protocol, 인터넷 프로토콜)라는 약속에 맞춰 만들어집니다. 패킷 머리 부분에 어떤 칸을 두고 무엇을 적을지를 이 약속이 정합니다.

IP 패킷의 머리 부분에는 TTL(Time To Live, 살아 있을 시간)이라는 칸이 있습니다. 이름은 시간이지만 실제로는 앞으로 더 거칠 수 있는 라우터 수, 곧 남은 홉 수로 쓰입니다. 이 칸이 있어야 길을 잃은 패킷이 망을 영원히 떠돌지 않습니다.

라우터는 패킷을 넘길 때마다 TTL 을 1씩 줄입니다. 줄인 값이 0이면 더 넘기지 않고 버립니다. 버린 라우터는 보낸 컴퓨터에 「수명이 다해 버렸다」는 알림을 돌려보냅니다.

이 알림은 ICMP(Internet Control Message Protocol, 인터넷 제어 메시지 프로토콜)로 갑니다. ICMP 는 라우터와 컴퓨터가 오류와 상태를 알리는 데 쓰는 규약입니다. 패킷이 버려졌다는 소식도 이 규약으로 돌아옵니다.

수명이 다했다는 알림의 이름은 Time Exceeded입니다. 이 편에서는 수명 초과 알림이라고 부릅니다.

아래 그림은 TTL 을 4로 두고 보낸 패킷이 갑과 을 사이를 도는 모습입니다.

sequenceDiagram
    participant 보낸쪽 as 보낸 컴퓨터
    participant 갑
    participant 을
    보낸쪽->>갑: 패킷 · TTL 4
    갑->>을: 하나 줄여 TTL 3
    을->>갑: 하나 줄여 TTL 2
    갑->>을: 하나 줄여 TTL 1
    Note over 을: 줄이면 0 이라 버린다
    을-->>보낸쪽: 수명 초과 알림

처음 값이 4였으므로 패킷은 갑과 을 사이 회선을 세 번 지나고 버려졌습니다.

처음 값은 보내는 운영체제가 정합니다. 대개 수십 이상입니다. TTL 칸은 8비트라서 가장 큰 값은 255입니다. 처음 값을 64로 잡으면 패킷 하나가 갑과 을 사이 회선을 예순 번 넘게 지나갑니다.

IPv6(Internet Protocol version 6, 인터넷 프로토콜 버전 6)에도 같은 칸이 있습니다. 이름이 홉 제한으로 바뀌었을 뿐 하는 일은 같습니다. 남은 홉 수를 센다는 뜻이 이름에 그대로 드러납니다.

TTL 은 고리를 고치지 않습니다. 고리에 든 패킷이 망을 영원히 붙잡지 못하게 할 뿐입니다. 표가 어긋난 채로 있으면 새 패킷이 들어올 때마다 같은 일이 되풀이됩니다.

맴도는 동안의 피해

회선이 한 번에 실어 나를 수 있는 양을 대역폭이라고 합니다. 패킷 하나가 같은 회선을 예순 번 넘게 지나가면 그 회선의 대역폭을 예순 번 넘게 씁니다.

목적지 망으로 가는 패킷이 계속 들어오면 갑과 을 사이 회선이 금방 찹니다. 그 회선을 같이 쓰는 다른 목적지의 통신도 줄을 서거나 버려집니다. 고리와 상관없는 서비스까지 느려지는 까닭이 이것입니다.

고리에 든 목적지로 가려던 연결은 답을 못 받습니다. 패킷이 목적지에 한 번도 닿지 않기 때문입니다. 백엔드 개발자 눈에는 연결 시간 초과로 보입니다. 상대 서버도 방화벽도 멀쩡합니다. 그 목적지로만 연결이 안 됩니다.

재현되는 조건

셋이 모두 서면 라우팅 루프가 됩니다.

  1. 어떤 목적지에 대해 라우터 갑의 다음 홉이 을입니다
  2. 같은 목적지에 대해 을의 다음 홉을 따라가면 다시 갑으로 돌아옵니다
  3. 그 목적지로 가는 패킷이 고리 안의 어느 라우터에 들어옵니다

그러면 그 패킷은 TTL 이 0이 될 때까지 고리를 돌고 버려집니다.

둘째가 빠지면 고리가 없습니다. 을의 다음 홉이 고리 밖을 가리키면 패킷은 거기서 빠져나갑니다.

셋째가 빠지면 고리는 표 안에만 있고 드러나지 않습니다. 그 목적지로 아무도 보내지 않으면 회선도 안 붐비고 오류도 안 납니다. 누군가 그 목적지로 처음 연결할 때 비로소 증상이 나옵니다.

서로를 가리키는 기본 경로와 정적 경로

표가 어긋나는 흔한 경우는 사람이 표를 손으로 적을 때입니다. 사람이 직접 적어 넣은 표의 줄을 정적 경로라고 합니다.

기본 경로는 표의 어느 줄에도 안 맞는 목적지를 받는 마지막 줄입니다. 「나머지는 전부 이 이웃에게」라는 뜻입니다. 세상의 모든 목적지를 표에 적을 수는 없어서 이 한 줄이 나머지를 받습니다.

컴퓨터에도 기본 경로가 있습니다. 컴퓨터 쪽에서 기본 경로의 다음 홉을 부르는 이름이 기본 게이트웨이입니다. 집이라면 대개 공유기가 그 다음 홉입니다.

두 라우터가 서로를 기본 경로로 삼으면 둘 다 모르는 목적지는 전부 고리에 빠집니다. 갑은 모르는 곳을 을에게 넘깁니다. 을도 모르는 곳을 갑에게 돌려보냅니다.

더 흔한 꼴은 기본 경로와 정적 경로가 엇갈리는 경우입니다. 회사 라우터 갑은 바깥으로 가는 것을 모두 통신사 라우터 을에게 넘깁니다. 을은 회사에 나눠 준 주소 범위 전체를 갑에게 넘깁니다. 그런데 회사 안에서는 그 범위의 절반만 씁니다.

라우터 목적지 다음 홉
갑 회사 안에서 쓰는 절반 회사 안쪽 망
갑 그 밖의 전부 · 기본 경로 을
을 회사에 나눠 준 범위 전체 갑

표에서 안 쓰는 절반으로 가는 패킷을 따라가 봅니다. 을은 범위 전체가 갑 쪽이라 갑에게 넘깁니다. 갑의 표에는 그 절반에 맞는 줄이 없어서 기본 경로를 따라 을에게 돌려보냅니다. 고리입니다.

이 고리는 아무도 안 쓰는 주소를 누군가 찌를 때만 드러납니다. 주소 범위를 훑는 스캐너가 이 범위를 두드리면 갑과 을 사이 회선이 갑자기 붐빕니다.

길이 바뀌는 동안 잠깐 생기는 루프

망이 크면 표를 손으로 적지 않습니다. 라우터들이 서로 길 정보를 주고받아 표를 스스로 고칩니다. 이렇게 표를 자동으로 고치는 방식을 동적 라우팅이라고 합니다.

길 정보를 주고받는 약속을 라우팅 프로토콜이라고 합니다. 어떤 정보를 언제 누구에게 보낼지를 이 약속이 정합니다.

회선 하나가 끊기면 그 소식이 모든 라우터에 퍼지기까지 시간이 걸립니다. 그동안 어떤 라우터는 새 표를 씁니다. 어떤 라우터는 아직 옛 표를 씁니다. 새 표와 옛 표가 같은 목적지에 대해 서로를 가리키면 그 사이에 고리가 생깁니다.

모든 라우터의 표가 새 상태로 맞춰지는 것을 수렴이라고 합니다. 수렴이 끝나면 이런 고리는 저절로 풀립니다. 그래서 잠깐 패킷이 버려지다가 다시 멀쩡해지는 모습으로 나타납니다.

무한 카운트

거리 벡터 라우팅은 라우팅 프로토콜의 한 갈래입니다. 라우터는 이웃에게 「나는 목적지까지 몇 홉」을 알립니다. 이웃이 알려 온 수에 1을 더해 자기 표에 적습니다.

이 방식에서는 고리가 오래 가는 경우가 있습니다. 목적지 망, 갑, 을이 한 줄로 이어져 있다고 해 봅시다. 갑은 목적지 망에 직접 붙어 있습니다. 을은 갑을 거쳐 목적지로 갑니다. 직접 붙은 것을 1홉으로 셉니다.

목적지 망과 갑 사이 회선이 끊기면 표가 이렇게 바뀝니다.

차례 갑의 표 을의 표
끊기기 전 1홉 · 직접 2홉 · 갑 경유
끊긴 뒤 갑이 을의 소식을 받음 3홉 · 을 경유 2홉 · 갑 경유
을이 갑의 소식을 받음 3홉 · 을 경유 4홉 · 갑 경유
갑이 다시 을의 소식을 받음 5홉 · 을 경유 4홉 · 갑 경유

둘째 줄에서 갑은 을이 알려 온 2홉을 믿습니다. 그 2홉이 자기를 거치는 길이라는 것을 갑은 모릅니다. 그 뒤로 둘은 서로의 수에 1씩 더해 가며 번갈아 올립니다.

수가 오르는 동안 갑은 을을, 을은 갑을 다음 홉으로 적고 있습니다. 그 사이 목적지로 가는 패킷은 둘 사이를 맴돕니다. 수가 미리 정한 상한에 닿아야 「갈 수 없음」으로 정리됩니다. 상한이 없으면 수가 끝없이 오르므로 이 현상을 무한 카운트(count to infinity)라고 부릅니다.

루프를 알아채는 단서

traceroute 는 목적지까지 거치는 라우터를 차례로 보여 주는 명령입니다. TTL 을 1, 2, 3 으로 늘려 가며 패킷을 보냅니다. 돌아오는 수명 초과 알림의 보낸 주소를 모으면 홉마다 어느 라우터였는지 나옵니다.

고리가 있으면 같은 두 주소가 번갈아 나옵니다. 목적지에는 끝내 닿지 않습니다.

 1  192.168.0.1     # 공유기
 2  198.51.100.1    # 라우터 갑
 3  198.51.100.2    # 라우터 을
 4  198.51.100.1    # 다시 갑
 5  198.51.100.2    # 다시 을
 6  198.51.100.1    # 다시 갑

방금 본 출력에서 2번 줄부터 두 주소가 한 줄씩 엇갈립니다. 명령이 정한 최대 홉 수에 닿을 때까지 이 무늬가 이어집니다.

traceroute 말고도 볼 것이 둘 더 있습니다.

보는 것 루프일 때
traceroute 같은 두 주소가 번갈아 끝없이 나온다
수명 초과 알림 한 목적지로 보낸 패킷에 대해 몰려 돌아온다
고리에 든 두 라우터 사이 회선 그 회선만 유독 붐빈다

수렴 중에 생긴 고리는 곧 풀리므로 다시 재면 안 보일 수 있습니다. 몇 번을 재도 같은 무늬가 나오면 누군가 표를 잘못 적었을 가능성이 큽니다.

이름이 비슷한 다른 루프

「루프」가 붙는 네트워크 고장은 라우팅 루프 말고도 있습니다. 가장 자주 헷갈리는 것은 스위치에서 나는 고리입니다.

스위치는 한 망 안의 장비끼리 데이터를 넘겨 주는 장비입니다. 라우터가 망과 망 사이를 잇는다면 스위치는 망 안쪽을 잇습니다.

스위치가 넘기는 데이터 묶음은 프레임이라고 부릅니다. 프레임에는 TTL 같은 칸이 없습니다. 몇 번을 돌아도 줄어드는 수가 없다는 뜻입니다.

그래서 스위치끼리 고리로 이어지면 프레임이 버려지지 않고 계속 돕니다. 이것이 스위칭 루프입니다.

리다이렉트 루프는 웹 서버들이 「저 주소로 가라」는 응답으로 서로를 가리키는 고장입니다. 라우터와 상관없이 웹 서버의 설정에서 생깁니다.

셋은 무엇이 도는지와 무엇이 그것을 끊는지로 갈립니다.

이름 무엇이 도나 무엇이 끊나
라우팅 루프 패킷이 라우터 사이를 TTL 이 0이 되면 버려진다
스위칭 루프 프레임이 스위치 사이를 끊는 수가 없어 계속 돈다
리다이렉트 루프 웹 요청이 주소 사이를 브라우저가 몇 번 따르다 멈춘다

고리를 끊는 방법

고치는 길은 원인마다 다릅니다. 이 편은 이름과 무엇을 깨는지만 짚습니다.

수단 무엇을 깨나
정적 경로 바로잡기 서로를 가리키는 줄을 없앤다
널 라우트 안 쓰는 주소 범위를 일부러 버리게 해 기본 경로로 새지 않게 한다
스플릿 호라이즌 이웃에게서 배운 길을 그 이웃에게 되알리지 않는다
포이즌 리버스 되알리되 「갈 수 없음」으로 표시해 알린다
홀드다운 끊긴 길에 대한 새 소식을 한동안 믿지 않고 기다린다
링크 상태 라우팅 이웃이 전한 홉 수 대신 망 전체 지도로 경로를 계산한다

앞의 둘은 손으로 적은 표에서 난 고리를 막습니다. 뒤의 넷은 동적 라우팅에서 수렴 중에 생기는 고리를 줄입니다.

관련 항목

라우팅 루프에 얽히는 장비와 표

라우터 · 라우팅 테이블 · 다음 홉 · 기본 게이트웨이 · 기본 경로 · 정적 경로 · 게이트웨이 · 라우팅

라우팅 루프를 끊거나 알리는 헤더 필드와 메시지

TTL · 홉 제한 · ICMP · Time Exceeded · IP · IPv4 · IPv6 · 패킷

표를 어긋나게 만드는 경로 교환 방식

동적 라우팅 · 라우팅 프로토콜 · 거리 벡터 라우팅 · 링크 상태 라우팅 · RIP · OSPF · BGP · 수렴

라우팅 루프를 막는 규칙과 설정

스플릿 호라이즌 · 포이즌 리버스 · 홀드다운 · 널 라우트 · 경로 요약

라우팅 루프와 같이 드러나는 네트워크 장애

무한 카운트 · 마이크로루프 · 블랙홀 경로 · 비대칭 라우팅 · 패킷 손실 · 연결 시간 초과 · 혼잡

라우팅 루프를 찾아내는 진단 도구

traceroute · mtr · ping · tcpdump

이름이 겹치는 다른 계층의 루프

스위칭 루프 · 브로드캐스트 스톰 · 스패닝 트리 프로토콜 · 리다이렉트 루프

다른 이름: routing loop