같게 들리는 두 가지 요구, «이 앱을 VPN에서 제외하라»와 «내 핫스팟에 있는 노트북을 위해 이 하나의 목적지를 VPN 밖으로 보내라»는 같지 않습니다. 전자는 휴대폰의 소켓이 네트워크를 선택하는 방식을 바꿉니다. 후자는 휴대폰이 이미 받아들인 뒤 다른 기기에서 도착한 패킷의 전달 결정을 바꿔야 합니다. 둘을 혼동하면 핫스팟 클라이언트에는 늘 휴대폰 자체의 브라우저에만 적용되던 예외만 남습니다.

두 가지 질문을 가진 두 개의 하위 시스템

Android는 앱 네트워킹과 테더링을 분리해 둡니다. 앱의 소켓은 연결 스택이 네트워크에 할당하고, VPN 앱은 자기 소켓 가운데 어느 것이 터널로 들어갈지 결정합니다. 테더링된 클라이언트에서 전달된 패킷은 테더링 하위 시스템이 처리하며, 하위 인터페이스에서 경로와 정책 규칙, 변환을 netd에 요청합니다.

앱별 제외는 앱이 소켓을 열 때 평가됩니다. 전달된 패킷은 이 기기의 앱 소켓에서 비롯된 것이 아니므로 그 검사에 결코 도달하지 않습니다. 두 설정이 서로를 대신할 수 없는 이유는 바로 이것이며, 어느 쪽의 버그도 아닙니다.

앱별 제외가 실제로 바꾸는 것

VpnService 빌더는 addDisallowedApplication으로 터널 밖에 남는 패키지를 지정하거나, addAllowedApplication으로 내부에서 허용되는 유일한 패키지를 지정할 수 있습니다. 그러면 그 앱들은 기반 네트워크에서 소켓을 열고, VPN은 나머지 전부에 대한 기본 경로를 계속 소유합니다.

범위는 정확하며, 그 패키지 자체의 소켓이, 이 기기에서, 터널이 올라와 있는 동안만입니다. 전달되는 트래픽에 대해서도, 두 번째 기기에 대해서도, 시스템이 테더링을 대신해 보내는 패킷에 대해서도 아무것도 말하지 않습니다.

목적지 제어도 아닙니다. 브라우저를 제외하면 그 브라우저가 도달하는 모든 주소가 제외되며, 터널 안에 두고 싶었던 주소도 포함됩니다. 요구가 앱이 아니라 목적지를 지목하면, 앱 선택기는 구조상 이미 잘못된 도구입니다.

휴대폰에게 테더링된 패킷은 어떻게 보이는가

클라이언트의 패킷은 휴대폰이 할당한 사설 출발지 주소(예: 192.168.43.20)와 공인 목적지를 가지고 핫스팟 인터페이스에 도착합니다. 전달하려면, 클라이언트의 사설 주소가 셀룰러 네트워크에서 의미가 없으므로, 응답이 돌아올 길을 찾도록 휴대폰에 업링크로 향하는 경로와 변환 규칙이 필요합니다.

Android는 라우팅 테이블을 선택하는 정책 규칙으로 이를 표현하고, 네트워크와 VPN이 바뀌면 netd가 관련 테이블과 규칙을 다시 만듭니다. 포럼 글이나 같은 모델의 오래된 릴리스에서 복사한 테이블 번호, 규칙 우선순위, 인터페이스 이름은 지속적인 소유권을 세우지 못합니다. 이 재구성이야말로 손으로 쓴 규칙이 한 시간쯤 동작하다가 다음 재연결 뒤에 멈출 수 있는 이유입니다.

핫스팟 예외에 정말 필요한 정책

규칙을 건드리기 전에 결정을 출발지, 목적지, 의도한 경로로 적고, 승인된 목적지 하나에 대한 최소 형태는 이렇습니다.

SourceDestinationIntended path
One authorized hotspot clientOne approved public service addressOrdinary cellular uplink
The same clientAll other covered destinationsShared VPN
The phone's own appsTheir existing destinationsUnchanged phone policy

두 방향이 모두 완전해야 합니다. 직접 분기에는 마침 현재인 셀룰러 업링크를 지나는 사용 가능한 경로가 필요하고, VPN 분기에는 터널 경로와 전달 허가가 필요합니다. 출발지 변환은, 터널 인터페이스에 적용된 NAT가 터널 주소를 보여 주고 셀룰러 주소가 아니므로, 선택한 출구와 일치해야 합니다.

응답은 추적된 상태나 명시적 경로를 통해 같은 하위 클라이언트에 도달해야 하며, 나가는 패킷 카운터는 그중 아무것도 증명하지 않습니다. VPN 자체의 외부 전송도 예외 범위 밖에 두지 않으면 터널의 운반 패킷이 클라이언트의 웹 요청을 위해 쓰인 정책을 물려받습니다.

잡힌 주소 하나는 목적지가 아니다

브라우저에서 읽은 IPv4 주소 하나는 한순간의 스냅숏입니다. 대형 서비스는 애니캐스트나 회전하는 엣지 주소 집합에서 응답하고, 많은 곳이 이중 스택이며, 로그인 흐름은 페이지가 결코 보여 주지 않는 인증과 텔레메트리 호스트를 건드릴 수 있습니다. 우연히 본 주소를 중심으로 만든 예외는 서비스가 부하를 다시 분산하는 다음 번에 깨집니다.

서비스 소유자가 문서화한 주소나 그가 공개한 범위를 사용하고 두 주소 체계를 모두 고려하십시오. 요구를 안정된 집합으로 표현할 수 없다면, 그것은 아마 서비스에 대한 정책 질문이며 휴대폰의 라우팅 요령이 아닙니다.

하위 측에서 검증하십시오

이 순서로, 노트북에서 선택한 서비스, VPN 안에 남아야 하는 평범한 목적지, 영향을 받지 않아야 하는 휴대폰 앱의 세 가지를 확인합니다. 그런 다음, 정책 테이블이 다시 만들어지는 재연결 뒤와 업링크 변경 뒤에 다시 하십시오.

휴대폰의 공유 구현이 재연결을 넘겨 그 계약을 유지하지 못한다면, 핸드셋에 root 규칙을 쌓는 대신 선택적 정책을 지원되는 하위 라우터로 옮기십시오. 라우터는 안정된 소유자와 함께 출발지와 목적지 일치를 표현할 수 있고, 테더링 모듈 문서가 휴대폰이 실제로 하는 일에 대한 올바른 참조입니다.

관련 글