연결한 뒤 라우팅 테이블을 열면 주소 하나만 터널을 통해 나가고 그 주변 서브넷은 여전히 로컬 게이트웨이로 가는 것이 보인다. 그 항목이 호스트 경로다. 즉 주소 하나이며 모든 비트가 켜진 프리픽스로 일치한다. 라우팅 결정이 가장 긴 일치 프리픽스를 쓰기 때문에 /32가 /24나 기본 경로를 바꾸지 않고도 우선할 수 있다는 점이 중요하다. 이것이 신중한 예외인지 향후 장애인지는 어떤 주소를 가리키고 누가 유지하느냐에 달려 있다.

주소 하나, 테이블 항목 하나

IPv4 호스트 경로는 /32 프리픽스를, IPv6 호스트 경로는 /128을 가지므로 항목은 정확히 목적지 주소 하나와 일치할 수 있다. 테이블의 다른 것은 움직이지 않는다. 덮는 서브넷과 기본 경로는 원래 자리에 그대로 있다. 좁은 항목이 그 주소에서 이기는 이유는 나중에 추가되었기 때문이 아니라 프리픽스가 더 길기 때문이다.

그 성질 때문에 호스트 경로는 좋은 예외이자 나쁜 습관이 된다. 서비스의 정문을 가리키는 두 개의 /32 항목은 두 번째 주소도, IPv6 주소도, 다음 달 옮겨갈 주소도 덮지 않는다. 설명 없는 단일 주소 항목으로 가득한 테이블은 보통 누군가 서브넷 결정을 내리는 대신 그 주변을 계속 덧대고 있었다는 뜻이다. 먼저 프리픽스 길이를 읽고, 그다음 그 항목이 무엇을 보호하려는지 물어야 한다.

클라이언트에서 바깥으로 항목을 읽어라

문제가 있는 머신에서 시작하라. 같은 주소라도 노트북과 그 앞의 게이트웨이에서 다르게 라우팅될 수 있다. 테이블을 위에서 읽는 대신 애플리케이션이 쓰는 정확한 주소에 대해 커널이 어느 경로를 고를지 물어라. 답에는 인터페이스와 다음 홉 이 포함되며, 둘이 합쳐져 결정이 된다.

ip route get 203.0.113.25
ip -6 route get 2001:db8:4::25
ip route show | grep -F 203.0.113.25
Find-NetRoute -RemoteIPAddress 203.0.113.25

애플리케이션이 실제로 고르는 주소 체계에 대해 질의를 반복하라. 클라이언트가 IPv6를 선호하며 IPv4 예외를 조용히 우회할 수 있기 때문이다. 터널이 올라오기 전과 후의 결과를 비교하고 두 출력을 모두 보관하라. 이 비교는 클라이언트가 연결할 때 항목을 추가했는지, 아니면 이미 있었는지를 보여 준다.

영구 항목과 런타임 항목은 다르게 실패한다. 런타임 항목은 세션과 함께 사라지고, 영구 항목은 재부팅을 견디며 더 이상 존재하지 않는 게이트웨이로 트래픽을 계속 보낸다.

엔드포인트 예외와 재귀의 함정

VPN 클라이언트는 보통 기본 경로를 돌리기 전에 원래 게이트웨이를 통해 서버의 외부 주소로 가는 호스트 경로를 설치한다. 그 항목이 없으면 암호화된 패킷이 만들려는 터널 안으로 들어가 버리고, 연결은 시간 초과가 될 때까지 루프를 돈다.

터널이 받아들인 서브넷에 그 엔드포인트 주소가 우연히 포함되거나, 나중에 두 번째 프로필이 더 넓은 경로를 추가하면 함정이 나타난다. 그러면 엔드포인트 항목이 더 긴 프리픽스에 밀리고, 트래픽을 통과시키기 시작하는 순간 세션이 무너진다. 받아들인 서브넷 옆에 엔드포인트 주소를 적는 것이 사용자보다 먼저 충돌을 알아차리는 가장 값싼 방법이다. 같은 프로필이 어떤 네트워크에서는 되고 다른 네트워크에서는 안 되는 이유도 이것으로 설명된다.

애플리케이션이 실제로 쓰는 경로를 확인하라

애플리케이션이 다른 주소나 다른 체계로 연결할 때 호스트 이름에 대한 성공적인 ping은 약한 증거다. 클라이언트를 실행하는 머신에서 주소, 체계, 포트, 인터페이스의 정확한 조합을 확인하라.

ip route get 203.0.113.25
sudo nft list ruleset | grep -A 4 'chain output'
curl -sS --max-time 8 -o /dev/null -w '%{remote_ip}
' https://app.example.net

경로가 틀렸다면 무엇이든 편집하기 전에 요구가 네트워크인지 주소 하나인지 결정하라. 단일 주소 요구라면 주석과 소유자를 붙인 호스트 경로로 정당화된다. 주소가 돌아가는 서비스에는 도메인 기반 라우팅이나 정직한 서브넷 결정이 필요하다.

더 이상 실제 목적지에 대응하지 않는 항목을 제거하고, 남기는 항목은 기록하라. 설명 없는 /32는 석 달 뒤에는 버그와 구별되지 않으며, 다음 사람은 무엇이 그것에 의존했는지 모른 채 삭제할 것이다.

관련 글