VPN을 전체 터널로 바꾸면 대부분의 트래픽이 따르는데, 그러다 한 주소가 직접 응답합니다 — 프린터, NAS, 10.x의 점프 호스트입니다. 뻔한 해석은 터널이 새고 있다는 것이어서 기본 경로의 메트릭을 낮추지만 아무것도 바뀌지 않습니다. 그 실패한 시도가 단서입니다: 기본 경로는 대체 수단이지 판결이 아닙니다. 경로 조회는 메트릭을 비교하기도 전에 가장 긴 일치 프리픽스를 선택합니다, 그래서 /24는 어느 쪽에 무슨 숫자를 붙이든 /0을 계속 이깁니다. 그 순서가 분명해지면, 누출은 보통 누군가 일부러 설치한 경로이거나 클라이언트가 결코 덮으려 하지 않은 프리픽스입니다.

기본 경로가 실제로 약속하는 것

0.0.0.0/0은 특정성 영 비트로 모든 IPv4 목적지와 일치합니다. 호스트가 자신의 테이블이 더 잘 설명하지 못하는 무엇이든 도달할 수 있도록 존재합니다. 192.168.1.0/24로 가는 경로는 24개의 일치 비트를 지니므로 192.168.1.40에 대해서는 누군가 메트릭, 관리 거리 또는 클라이언트가 우선순위 필드라고 부르는 것을 비교하기 전에 이깁니다. 같은 규칙이 Linux FIB, Windows 라우팅 테이블, macOS 뒤의 BSD 스택에 적용됩니다.

정상적인 LAN에서 그 동작은 기능입니다. 로컬 서브넷이 직접 연결되어 있고, 터널이 브라우징을 나르는 동안 프린터는 계속 작동하며, 잘못 설정된 것은 없습니다. 물어볼 가치가 있는 질문은 그 주소가 왜 직접 가는가가 아니라, 어느 테이블의 어느 프리픽스가 그것과 일치하는지, 그리고 누가 그것을 거기에 두었는지입니다.

하프 기본 경로, 또는 기본 항목이 손대지 않은 듯 보이는 이유

가장 깔끔한 예는 redirect-gateway def1 OpenVPN입니다. 기본 경로를 삭제하고 교체하는 대신 0.0.0.0/1과 128.0.0.0/1을 추가합니다. 함께 그 쌍은 IPv4 전체를 덮고, 각 프리픽스는 /0보다 길며, 둘 다 라우터의 기본 경로를 그 자리에 둔 채 이깁니다. 나중에 경로 목록을 실행하면 원래 기본 경로가 여전히 있고 여전히 게이트웨이를 가리킵니다; 다만 인터넷 목적지에는 결코 선택되지 않습니다.

WireGuard의 wg-quick은 정책 라우팅으로 같은 결과에 도달합니다. AllowedIPs가 0.0.0.0/0을 덮으면 자체 테이블을 만들고, 표시된 패킷을 그리로 보내며, 메인 테이블의 길이 영 프리픽스를 무시하는 규칙을 추가합니다. 메인 테이블은 기본 항목을 유지하고, 규칙은 인터페이스가 소유한 트래픽에 대해 터널 테이블을 먼저 참조한다고 결정합니다.

두 설계 모두 터널 밖에 정확히 하나의 경로가 필요합니다: 원래 게이트웨이를 통해 VPN 서버 자체 주소로 가는 호스트 경로입니다. 그것이 없으면 클라이언트는 터널을 만드는 패킷을 터널 안에서 나르려 할 것이고 연결은 결코 완료되지 않습니다. 따라서 엄격한 전체 터널 프로필에서도 테이블에 터널이 아닌 경로가 있는 것은 정상입니다. 의심할 가치가 있는 경로는 정말로 신경 쓰는 목적지를 덮는 경로입니다.

메트릭은 동점을, 프리픽스는 승자를 결정한다

메트릭은 목적지와 똑같이 잘 일치하는 후보들 사이에서만 비교됩니다. Linux에서는 ip route get 10.20.5.9 테이블과 함께 승자를 출력하고, ip route show table all 후보를 나열합니다(하프 기본 경로와 규칙이 가리키는 테이블도 포함). Windows에서는 Find-NetRoute -RemoteIPAddress 10.20.5.9 선택된 경로와 소스 주소를 반환하고, Get-NetRoute 원시 테이블을 보여줍니다 — 하지만 실효 비용은 경로 메트릭 더하기 인터페이스 메트릭이므로 느린 어댑터는 이기는 것처럼 보이는 동점을 잃을 수 있습니다.

세 가지 경우가 보게 될 것의 대부분을 덮습니다:

  • 같은 목적지, /24 대 /0: 메트릭이 무엇이라 하든 /24가 프리픽스 길이로 이깁니다.
  • 같은 목적지, 메트릭이 다른 두 개의 /24: 더 낮은 실효 메트릭이 이깁니다.
  • 같은 목적지, 두 테이블, 하나는 정책 규칙이 선택: 규칙이 먼저 테이블을 고르고, 프리픽스 비교는 그 안에서 일어납니다.

세 번째 경우가 이런 보고서 대부분이 끝나는 곳입니다. Linux의 ip rule 또는 Windows VPN 트래픽 필터는 트래픽을 터널 기본 경로를 결코 담지 않은 테이블로 보낼 수 있고, 메인 테이블은 내내 완벽해 보입니다.

보통 이 우회를 소유한 쪽은 누구인가

테이블이 아니라 프로필에서 시작하세요. 스플릿 터널 구성과 앱별 VPN 설정은 이름 붙은 프리픽스를 의도적으로 터널 밖에 두고, 하나의 사설 서브넷을 보호하고 일반 브라우징은 직접 나가게 하는 업무 프로필은 설계대로 동작하며, 그것을 덮어쓰면 원래 강제하려던 정책이 깨집니다. Microsoft의 VPN 라우팅 지침 도 강제 터널 트래픽과 명시적 예외 사이에 같은 선을 그으므로, 무엇이든 편집하기 전에 유용한 교차 점검이 됩니다.

다음으로 잔여물을 찾으세요. 더 이상 존재하지 않는 인터페이스나 이전 네트워크의 주소를 가리키는 경로는 도킹 스테이션, USB 어댑터, 컨테이너 브리지가 오간 뒤에 나타납니다. 한 번 삭제하는 것이 끝이 아닙니다: NetworkManager 연결 프로필, netplan 파일, Windows 영구 경로가 다음 연결이나 부팅 때 그것을 다시 설치하므로, 무엇이든 편집하기 전에 그것을 소유한 파일이나 프로필을 찾으세요.

그다음 IPv6를 따로 확인하세요. ip -6 route 와 Get-NetRoute -AddressFamily IPv6 는 별도의 상태, 별도의 기본 경로, 별도의 클라이언트 동작을 유지합니다. IPv4만 감사해서는 네이티브 IPv6 경로를 조용히 선호하는 듀얼 스택 호스트에 대해 아무 말도 할 수 없고, 그것만으로도 클라이언트가 스플릿 터널처럼 보일 수 있습니다.

애플리케이션 자체의 흐름으로 확인하라

애플리케이션이 실제로 사용하는 목적지를 기록한 뒤, 그 애플리케이션이 바인딩하는 소스 주소에서 어떤 경로를 택할지 시스템에 물으세요. ip route get 10.20.5.9 from 192.168.1.40 Linux에서 그것에 답하고, Find-NetRoute -RemoteIPAddress 10.20.5.9 에 로컬 주소를 더하면 Windows에서 그것을 합니다. 결과를 프로필이 주장하는 것과 비교하세요. 브라우저의 공인 IP 페이지는 한 프로토콜에서 한 목적지만 시험하고 불만을 시작한 사설 주소에 대해서는 아무 말도 하지 않습니다.

차이를 설명하는 가장 좁은 객체를 고치세요. 예외가 승인되었다면 프리픽스를 적어 두고 그대로 두세요; 아니라면 기본 경로의 메트릭을 낮추는 대신 경로를 제거하거나 터널을 통한 명시적인 더 좁은 경로를 추가하세요. 메트릭을 낮추는 것으로는 더 긴 프리픽스를 앞설 수 없고, 두 개의 /1 경로가 인터넷 경로를 소유한 상태에서 기본 경로를 편집해도 아무것도 바뀌지 않습니다.

그다음 터널을 다시 연결하고 같은 쿼리를 반복하세요. 클라이언트는 연결할 때마다 경로를 다시 설치하므로 다음 핸드셰이크까지만 유지되는 변경은 검증되지 않은 것입니다. 경로가 여전히 어긋난다면 남은 용의자는 정책 규칙, 두 번째 테이블, 클라이언트 측 필터이지 기본 경로가 아닙니다.

  • 앱이 실제로 사용하는 목적지와 소스 주소를 지목하세요.
  • 이긴 경로를 ip route get 또는 Find-NetRoute 로 출력하세요.
  • /1 쌍과 정책 테이블 중 무엇이 인터넷 경로를 소유하는지 확인하세요.
  • 목적지와 일치하는 /0보다 긴 모든 프리픽스를 나열하세요.
  • IPv6 확인을 따로 반복하세요.
  • 살아남은 경로를 그것을 설치하는 파일, 프로필, 필터까지 거슬러 추적하세요.
  • 고쳐졌다고 부르기 전에 다시 연결하고 쿼리를 다시 실행하세요.

일곱 가지가 모두 프로필과 일치하면 터널은 설정된 대로 정확히 동작하는 것이고, 수정은 메트릭이 아니라 프로필에 속합니다.

관련 글