킬 스위치가 제대로 작동하는지 확인하는 데 실제 계정은 필요 없고, 위험에 노출되는 것은 바로 시험 자체다. 이 점검은 트래픽이 터널 밖으로 나갈 수도 나가지 않을 수도 있는 짧은 구간을 만들기 때문에, 잃어도 되는 것을 사용해야 한다. 나는 지금 미끼 페이지와 예비 브라우저 프로필로 이 작업을 하며, 예전에 쓰던 브라우저와 웹메일 조합보다 더 분명한 답을 얻는다. 아래에서는 클라이언트가 제시하는 순서, 즉 설정, 목적지, 전환, 증거의 순서를 따른다.

이 시험이 답하는 것은 하나의 좁은 질문이다. 이 전환 동안 이 애플리케이션이 터널 밖의 네트워크에 도달할 수 있는가? 나머지 정책이 합리적인지에 대해서는 아무것도 말하지 않는다. 범위를 그렇게 좁게 유지하면 결과는 기록할 가치가 있다.

클라이언트에서 스위치와 적용 범위 찾기

네트워크 상태를 바꾸기 전에 클라이언트를 열어 차단 설정을 찾는다. 업체마다 이름이 다르다: 킬 스위치, 잠금 모드, 네트워크 잠금, 터널 밖 트래픽 차단 등이다. 라벨은 그 안의 옵션에 대해 알려주지 않는다. 중요한 것은 차단이 항상 적용되는지, 앱이 터널 실패를 감지했을 때만 적용되는지, 그리고 모든 애플리케이션을 대상으로 하는지 선택한 목록만 대상으로 하는지다.

다음으로 클라이언트가 실제로 수행할 수 있는 전환을 나열한다. 사용자가 시작한 연결 해제, 앱 종료, 서버와의 접속 상실은 대부분의 클라이언트에서 서로 다른 코드 경로이며 하나의 차단 정책을 공유하지 않는다. 앱이 종료될 때 차단을 해제하는 제품도 있다. 무언가가 제거할 때까지 필터 규칙을 남기는 제품도 있다. 가정하지 말고 사용하는 빌드의 업체 설정 참고서를 읽고, 세 가지 중 무엇을 시험하는지 적는다.

프로필도 기록한다: 프로토콜, 주소 체계, 분할 터널링 활성화 여부. 프로필이 일부 앱을 의도적으로 제외한다면 기기 전체를 대상으로 한다는 주장은 의미가 없고, 직접 설정한 제외는 유출이 아니다. OpenVPN Connect 설정 참고서 는 어떤 토글이 어떤 동작을 바꾸는지 알려주는 종류의 페이지지만, 라벨은 클라이언트마다 다르다.

터널 없이도 동작하는 미끼 목적지 고르기

미끼에는 두 가지 속성이 필요하고, 둘 중 하나를 빠뜨리면 결과를 읽을 수 없다. 터널이 끊기고 차단이 꺼진 상태에서 직접 도달할 수 있어야 하며, 그렇지 않으면 응답이 멈췄다는 것이 단지 호스트가 사라졌다는 뜻일 수 있다. 그리고 로그인, 쿠키, 결제가 필요 없어야 하므로 유출의 대가는 세션이 아니라 로그 한 줄이다.

직접 관리하는 호스트의 정적 페이지가 가장 깔끔한 선택이다. 평범한 HTTP 서버를 돌리는 예비 가상 머신도 거의 비슷하게 좋고, 공개 연결 확인 페이지도 그 가용성이 내 통제 밖임을 받아들일 수 있다면 쓸 만하다. 주소, 포트, 주소 체계, 이름 조회가 필요한지 여부를 기록해 두면, 이들 각각은 나중에 분리해야 할 변수가 된다.

스위치를 건드리기 전에 기준선을 세운다. 터널이 올라가 있으면 미끼는 터널을 통해 응답해야 하며, 이는 정책 경로가 작동함을 뜻한다. 터널이 내려가고 차단이 꺼져 있으면 미끼는 직접 응답해야 하며, 이는 목적지가 살아 있음을 뜻한다. 그래야만 차단 상태에서의 실패가 무언가를 알려준다.

전환을 정해진 순서로 실행하기

전환은 하나씩 수행하고, 클라이언트가 그 사이에 규칙을 허물고 다시 만드는 경우가 많으므로 각각 몇 초씩 기다려 안정시킨다. 매번 같은 짧은 점검을 실행하면 관찰 결과를 비교할 수 있다:

curl -sS -o /dev/null -w 'http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_exit=$?"
dig +short decoy.example
curl -6 -sS -o /dev/null -w 'v6_http=%{http_code}\n' --max-time 5 http://decoy.example/
echo "curl_v6_exit=$?"
TransitionExpected with the block onFailure signature
Manual disconnectDecoy stops answering within secondsDecoy still returns 200
Server or path failureBlocked, with no exemption for the old endpointDirect access during the gap
Quit the appClient-dependent; record what happensBlock disappears with the process
Wi-Fi to EthernetBlock holds until the tunnel returnsTraffic flows mid-change

앱 종료 항목은 평소에 클라이언트를 닫지 않더라도 따로 실행할 가치가 있다. 종료 시 차단이 해제된다면 충돌이나 강제 업데이트도 같은 노출을 안겨주며, 이는 내 인내심이 아니라 배포에 관한 사실이다. Windows에서는 같은 확인을 Resolve-DnsName decoy.example 와 curl.exe -s -o NUL -w "%{http_code}" http://decoy.example/ 로 한다.

차단과 고장 난 리졸버 구분하기

페이지가 로드되지 않는 데는 여러 원인이 있고, 그중 하나만 스위치가 작동하는 경우다. 이름이 해석되지 않으면 배운 것은 DNS가 차단되었거나 고장 났다는 것이지 데이터 경로가 차단되었다는 것이 아니다. 리터럴 주소로도 확인하면 답이 이름 해석에 전혀 의존하지 않는다.

curl의 종료 코드는 이런 경우를 구분한다. 6은 이름 해석 실패, 7은 연결 거부, 28은 시간 초과다. 차단된 경로는 보통 리터럴 주소에 대한 시간 초과나 거부로 나타나고, DNS만 차단하면 6을 남기고 나머지를 숨긴다. 캐시된 페이지나 캡티브 포털은 눈을 속이므로 증거는 화면이 아니라 종료 코드다.

리터럴 주소로 IPv6에서도 확인을 반복한다. IPv4는 막고 IPv6를 무시하는 차단은 흔하므로 메모에 한 줄 더할 가치가 있으며, 터널 밖에서 IPv6를 끄는 클라이언트라면 두 주소 체계 모두에서 분명히 실패해야 한다.

결과가 포괄하는 범위 기록하기

터널이 돌아오면 미끼가 터널을 통해 응답하고 리졸버가 답을 돌려주며 정책이 두었던 자리에 있는지 확인해 복구를 점검한다. 그다음 실험을 되돌린다. 임시 방화벽 규칙, 디버그 경로, 테스트 프로필을 남겨두면 다음 실행이 혼란스러워지고 앱보다 오래 살아남을 수 있다.

한 번의 실행으로 다루는 것은 클라이언트 빌드 하나, 프로필 하나, 전환 하나, 주소 체계 하나뿐이다. 그 네 가지를 결과와 함께 적는다:

  • 클라이언트 빌드와 플랫폼, 설정이 프로필별인지 전역인지.
  • 프로필, 프로토콜, 분할 터널 예외.
  • 시험한 전환과 그것을 일으킨 방법.
  • 주소 체계와 DNS, 차단 및 비차단 상태의 curl 종료 코드.

어느 줄이라도 비어 있으면 시험은 끝난 것이 아니다. 로밍한다면 네트워크 변경 항목을 반복한다. 무인 재부팅은 규칙이 돌아오는지 확인하는 것 이며, 이는 스위치가 아니라 복원 순서에 관한 질문이다. 클라이언트 업데이트 후에는 순서를 다시 실행한다. 토글은 거의 바뀌지 않지만 그 뒤의 동작은 바뀌기 때문이며, 미끼는 계속 남겨두면 교체할 것도 없고 다음 확인은 오 분이면 된다.

관련 글