스플릿 터널링이 어떤 트래픽을 VPN으로 보낼지 결정하는 방식
스플릿 터널링은 경로와 바인딩에 관한 결정의 집합이지 켜는 모드가 아닙니다. 앱별 규칙, 접두사, DNS, 킬 스위치가 어떻게 상호작용하는지 살펴보세요.
스플릿 터널링은 규칙 집합으로 표현되는 라우팅 정책이며, 클라이언트는 그 규칙을 설치하는 존재일 뿐입니다. 분리는 두 곳에서 일어납니다: 각 패킷의 경로를 고르는 일치 규칙과, 테이블이 무엇이라 하든 애플리케이션을 하나의 인터페이스에 붙잡아 두는 바인딩입니다. 클라이언트가 어느 메커니즘에 의존하는지가 사람들이 보고하는 놀라움의 대부분을 설명합니다.
한 줄로 진술할 수 있는 정책은 검증할 수 있습니다. 더 빠른 탐색이라고 설명된 정책은 그렇지 않으며, 요청이 잘못된 방향으로 갈 때 어떤 규칙을 바꿔야 하는지 알려주지 않습니다.
클라이언트가 규칙을 설치하고, 커널이 선택을 내립니다
터널이 올라오면 클라이언트는 다른 인터페이스가 사용하는 같은 테이블에 경로와 종종 정책 규칙을 추가합니다. 그러면 각 패킷은 목적지를 모든 후보 접두사와 비교해 가장 구체적인 일치를 남기는 조회에 도달하고, 서로 다른 테이블을 가리키는 규칙 사이의 동점은 우선순위가 해결합니다. 그 조회는 패킷이 백업 작업이 아니라 브라우저 탭에서 왔다는 것을 알지 못합니다. 이기는 규칙이 경로를 정하며, 변경 전과 후에 그것을 읽을 수 있습니다.
그래서 스플릿 터널은 자의적으로 보일 수 있습니다. 한 애플리케이션의 두 목적지가 서로 다른 경로를 택하는 것은 한 접두사가 다른 것보다 좁기 때문일 뿐일 수 있습니다.
같은 선택은 모든 플랫폼에 있지만 이름은 바뀝니다. Windows는 결정을 자체 필터 플랫폼으로 밀어 넣고, Android는 VPN 서비스를 통해 앱별 허용 목록을 노출하며, macOS는 라우팅 테이블을 여전히 따르는 장치에 터널을 붙입니다. Microsoft의 라우팅 노트는 Windows 사례에 읽을 만하며, 한 플랫폼을 위해 쓰인 안내서가 다른 플랫폼으로 그대로 옮겨지는 일은 드뭅니다.
앱별 바인딩과 목적지 접두사는 다른 도구입니다
목적지 정책은 패킷이 어디로 가는지 묻고 라우팅 테이블이나 정책 규칙을 참조합니다. 앱별 정책은 어느 프로그램이 소켓을 열었는지 묻고, 더 구체적인 경로가 다른 곳을 가리켜도 플랫폼은 그 프로그램을 터널 인터페이스에 붙잡아 둡니다. 두 번째가 더 강한 것은 테이블 변경을 견디기 때문이지만, 플랫폼이 귀속시킬 수 있는 프로세스만 다룹니다. 도우미 프로세스, 내장 브라우저, 또는 자체 연결을 여는 서비스는 가정한 바인딩을 상속하지 않을 수 있습니다.
이름 기반 정책에서는 어느 접근법도 도움 없이 살아남지 못합니다. 대형 사이트의 주소는 콘텐츠 네트워크 사이를 옮겨 다니므로, 호스트 이름을 몇 개의 접두사에 고정하면 조용히 일치를 멈추는 규칙이 생깁니다. 이름을 따라가야 하는 정책에는 정적 경로 대신 리졸버를 인식하는 구성 요소가 필요합니다.
DNS와 킬 스위치는 자체 규칙을 따릅니다
이름 확인은 패킷 라우팅과 별개의 결정이며, 스플릿 터널은 보통 두 개의 리졸버를 원합니다: 내부 이름에는 회사 것을, 나머지 전부에는 로컬 것을 씁니다. 클라이언트는 인터페이스별 DNS 설정을 설치하거나, 질의를 중간 리졸버에 넘기거나, 시스템 기본값을 그대로 둘 수 있습니다. 자체 암호화 리졸버를 가진 브라우저는 세 가지 배치를 모두 우회합니다. 리졸버가 경로를 따랐다고 가정하지 말고 조회를 시험해 보세요.
킬 스위치는 그 위에 필터를 더하며, 그 필터가 의도한 제외와 우발적 유출을 항상 구분하지는 못합니다. 어떤 클라이언트는 터널 밖의 모든 것을 차단하고 다른 클라이언트는 정책이 선언한 제외를 허용하므로, 둘 중 하나에 기대기 전에 자신의 것이 어떤 동작을 구현하는지 읽어 보세요.
양쪽에서 분리를 확인하세요
포함된 경로와 제외된 경로를 따로 시험하고, 결과는 공개 주소가 아니라 인터페이스 이름으로 판단하세요. 이 명령은 터널 장치가 이미 올라온 Linux 호스트를 가정합니다. 203.0.113.10은 정책이 안쪽으로 라우팅하는 목적지로, 198.51.100.25는 바깥으로 보내는 목적지로 바꾸세요.
ip route get 203.0.113.10
ip route get 198.51.100.25
resolvectl query intranet.example.com
curl -s --interface tun0 https://example.com -o /dev/null -w '%{http_code}\n'
처음 두 응답은 각 응답에 적힌 인터페이스가 그 목적지를 터널에 올렸는지 보여 주므로 함께 읽으세요. 리졸버 질의는 내부 이름에 어느 서버가 답했는지 보여 주고, 마지막 명령은 터널 장치가 요청을 실어 나를 수 있음을 증명합니다. 첫 줄이 성공하는데 둘째 줄에서 실패한다면 정책은 지시받은 대로 정확히 동작하는 것입니다.
다시 연결한 뒤와 네트워크가 바뀐 뒤에 이 묶음을 반복하세요. 임대 갱신과 인터페이스 변동은 분리가 만들어진 의도와 어긋나기 시작하는 지점이며, 실행할 때마다 저장한 출력은 그 어긋남을 분명히 보여 줍니다.