Always-on VPN 대 kill switch: 실제로 켠 것은 어느 쪽인가
Always-on VPN은 터널을 다시 연결하고, kill switch는 터널 없이 무엇이 나갈 수 있는지 정합니다. 라벨을 믿기 전에 확인할 다섯 가지.
Always-on과 kill switch는 같은 설정 화면에서 두 줄 차이로 붙어 있어서, 사람들은 이들을 한 기능의 두 이름으로 읽습니다. 그렇지 않습니다. Always-on은 재연결 정책입니다. 부팅 시 터널을 시작하고, 크래시나 네트워크 변경 뒤에 다시 올리고, 실패하는 동안 계속 재시도합니다. Kill switch는 트래픽 정책입니다. 터널이 내려간 동안 어떤 패킷이 여전히 기기를 떠날 수 있는지 정합니다. 두 번째 없이 첫 번째를 켤 수 있고, 대부분의 플랫폼에서 기본 결과는 그 틈 동안에도 트래픽을 내보냅니다.
확인 1: 차단은 별도의 스위치인가
Android 10 이상에서는 저장된 VPN 프로필이 톱니바퀴 아이콘 뒤에 두 개의 독립 스위치를 엽니다. Always-on VPN과 Block connections without VPN입니다. kill switch는 두 번째뿐입니다. always-on만 있으면 터널은 끊긴 뒤 실제로 돌아오지만, 그 전까지 요청 중인 어떤 앱이든 Wi-Fi나 모바일 데이터로 네트워크에 닿을 수 있습니다.
관리되는 기기는 정책 API에서 같은 분리를 유지합니다. setAlwaysOnVpnPackage()은 패키지 이름과 lockdownEnabled 플래그를 받습니다. 패키지를 설정하고 플래그를 false로 둔 관리자는 닫힌 기기가 아니라 상시 터널을 만든 것입니다. 콘솔의 문구는 그 차이를 거의 드러내지 않습니다.
상태는 콘솔이 아니라 기기에서 읽습니다. adb shell settings get global always_on_vpn_app와 adb shell settings get global always_on_vpn_lockdown입니다. 첫 번째가 null를 반환하면 플랫폼 수준에서 강제되는 패키지가 없고, 두 번째가 0를 반환하면 플랫폼이 아무것도 차단하지 않습니다. Android VPN 가이드는 이 둘을 하나의 모드가 아닌 별개의 기능으로 설명합니다.
확인 2: 차단은 어느 계층의 것인가
라벨은 클라이언트에 있고 차단은 보통 방화벽에 있습니다. 그래서 같은 단어가 플랫폼마다 다른 뜻이 됩니다. 아래 행들은 어느 하나를 믿기 전에 확인할 가치가 있는 것들입니다.
| Where you see the label | What the label promises | What actually blocks |
|---|---|---|
| Android VPN profile | Always-on VPN | Block connections without VPN |
| Android device policy | Always-on package | lockdownEnabled flag |
| Windows built-in VPN | Always On tunnel | Outbound firewall rules |
| WireGuard for Windows | Tunnel service | Block untunneled traffic option |
| wg-quick on Linux | Route via AllowedIPs | Your own nftables or iptables rules |
Windows는 차단하지 않는 라벨의 가장 분명한 예입니다. 여기서 Always On은 터널의 지속성을 뜻합니다. 머신 인증용 장치 터널과 로그인한 계정용 사용자 터널이며, 프로필 XML이나 Add-VpnConnection로 구성합니다. 그 프로필 어디에도 터널이 없을 때 나가는 패킷을 막는 것이 없고, 아웃바운드 필터링은 기본으로 켜져 있지 않아서, Wi-Fi에 연결된 노트북은 VPN이 내려가도 계속 동작합니다.
WireGuard도 같은 방식으로 갈라지지만 기준은 클라이언트입니다. WireGuard for Windows에는 터널별 Block untunneled traffic 옵션이 있어 필터 규칙을 설치합니다. Linux 도구에는 그런 스위치가 없습니다. wg-quick은 각 AllowedIPs 항목에 경로를, 그리고 fwmark 규칙을 추가하고, wg-quick down은 둘 다 제거하므로 물리적 기본 경로가 패킷을 하나도 떨어뜨리지 않고 다시 맡습니다.
Apple 플랫폼에서 always-on은 감독되는 기기용 관리 프로필 기능으로 오고, 체크박스가 아니라 on-demand 규칙으로 표현됩니다. 페이로드에서 답해야 할 질문은 실패한 터널이 트래픽을 거부하는지, 아니면 다른 연결만 요청하는지입니다. 메뉴 제목은 그것을 알려주지 않습니다.
확인 3: 아이콘이 아니라 틈을 측정하라
중요한 전환은 네 가지이고, 각각 다르게 실패합니다. 누군가 로그인하기 전의 부팅, 절전과 복귀, Wi-Fi에서 모바일 데이터로의 전환, 그리고 터널 인터페이스를 반쯤 구성된 채로 남기는 클라이언트 크래시입니다. 그중 하나에서 깔끔한 재연결은 나머지 셋에 대해 아무것도 증명하지 않습니다.
가장 싼 시험은 일부러 터널을 멈춘 뒤 밖으로 나가보는 것입니다. 터널이 내려간 상태에서 curl -m 5 -sS -o /dev/null -w '%{http_code}' https://example.com가 200를 반환하면 정책이 fail-open입니다. 시간 초과나 거부된 연결은 아직 무언가가 막고 있다는 뜻입니다. ip route get 1.1.1.1는 패킷을 실어 나를 인터페이스를 알려주며 보통 트레이 아이콘보다 정보가 많고, systemctl status wg-quick@wg0는 인터페이스가 깔끔히 제거되었는지 보여줍니다.
같은 점검을 네트워크가 안정된 뒤에만 하지 말고, 바뀌는 중에 두 번째 창에서 실행하세요. 끊김과 재시도 사이의 간격이 핵심이며, 이름 조회는 트래픽이 빠져나갔음을 알아차리는 가장 빠른 방법입니다. 터널이 내려간 동안 로컬 리졸버가 응답하면 차단은 완전하지 않습니다.
확인 4: 잠그기 전에 예외를 정하라
두 가지 예외는 구조적입니다. 클라이언트는 VPN 서버 자체에 닿아야 하므로, 모든 것을 버리는 규칙 집합은 보호를 되살릴 재연결도 막습니다. 캡티브 포털도 올라와 있지 않은 터널로는 닿을 수 없으므로, 호텔 Wi-Fi에서 잠긴 기기에는 즉흥적인 방법이 아니라 문서화된 포털 여는 방법이 필요합니다.
최소 형태는 엔드포인트를 허용하고 나머지는 버립니다.
table inet vpnlock {
chain output {
type filter hook output priority 0; policy drop;
oifname "lo" accept
ip daddr 203.0.113.10 udp dport 51820 accept
oifname "wg0" accept
}
}
그 엔드포인트 줄은 상수가 아니라 변수로 다루세요. 제공자는 주소를 바꾸고, 낡은 예외는 작동하던 kill switch가 재연결할 수 없는 기기가 되는 흔한 이유입니다. 로컬 프린터, NAS 공유, 개발 서비스도 같은 문서화된 목록에 들어가야 하며, 그렇지 않으면 지원 티켓마다 하나씩 발견됩니다.
확인 5: 실제로 무엇을 증명했는지 기록하라
네 열짜리 표를 두고 시험으로 채우세요. 상태, 기대 동작, 관찰된 동작, 증거입니다. 행은 확인 3의 전환에 의도적인 실패 하나를 더한 것입니다. 명령 출력으로 채울 수 없는 행은 시험하지 않은 행이며, 재연결 행은 통과하지만 부팅 행에서 실패하는 기기는 흔해서 추가 십 분을 들일 값이 있습니다.
끝났다고 하기 전에:
- 차단 설정이 재연결 설정과 별개인지 확인하고, 기기에서 그 값을 읽으세요.
- 차단을 어느 계층이 강제하는지 - 클라이언트 옵션, 기기 정책, 방화벽 - 와 그 계층이 어디서 구성되는지 아세요.
- 차단을 증명하는 점검 명령 하나를 남기고, 전환 중에 실행하세요. 끝난 뒤가 아니라.
- 예외 목록을 엔드포인트까지 적고, 누가 갱신하는지 메모하세요.
- 관리되는 하드웨어에서는 강제된 정책을 그대로 두세요. 차단을 없애는 것은 터널을 고치는 대신 요구 사항을 바꾸는 일입니다.