Kill switch와 중복 금지 규칙은 반대 방향을 가리키며, 그래서 일반적인 VPN 설정은 두 번째를 결코 표현하지 않는다. Kill switch는 내려간 터널에 반응하는 반면, 이 요구 사항은 올라간 터널에 반응하고 애플리케이션을 그림 밖에 둔다. 하나의 설계 결정이 대부분을 정리한다. 앱을 중지할지, 시작을 막을지, 아니면 네트워크 접근만 박탈할지다. 방화벽 규칙이나 프로세스를 죽이는 루프에 손을 뻗기 전에 그 계층을 고르라. 관찰로 강제되는 규칙은 매번 실행마다 창을 흘리기 때문이다.

신화: kill switch는 프로그램의 시작을 막는다

Kill switch는 트래픽 제어이며 그 점에서 정직하다. 터널 상태에 따라 패킷을 허용하거나 거부한다. 어느 것도 프로그램 시작을 거부하지 않고, 어느 것도 어떤 실행 파일이 소켓을 열었는지 검사하지 않는다. 데스크톱 바로가기, 예약된 작업, 백그라운드 도우미는 모두 앱 이름을 아는 무엇을 거치지 않고 네트워크에 도달한다. 이 두 메커니즘 사이의 거리가 대부분의 혼란이 사는 곳이다.

프로그램이 시작될 수 있는지를 실제로 결정하는 구성은 애플리케이션 제어다. Windows에서는 AppLocker 또는 WDAC, 관리형 macOS에서는 기기 프로필이 강제하는 허용 목록이다. 둘 다 터널과 무관하므로 두 요구 사항은 같은 티켓에 합쳐지고 나서 어느 것도 충족되지 않는다.

도구의 이름을 붙이기 전에 모드의 이름을 붙이라

규칙을 세 상태의 상태 기계로 쓰라. 일반 사용, VPN 작업 세션, 그리고 퇴장이다. 금지된 중복은 중간 상태에 속하며 클라이언트 소프트웨어의 것이 아니다.

상태를 바꾸는 사람은 순서대로 세 가지 행동을 소유한다. 앱의 작업을 끝내고, 정상 종료를 요청하고, 터널이 올라오기 전에 인스턴스가 사라졌음을 확인한다. 순서는 반대쪽에서도 중요하다. 먼저 연결하고 나중에 프로그램을 멈추는 VPN은 이미 중복을 허용한 것이다. 요구 사항이 연결 설정을 포함한다면 연결됨 표시를 기다리는 것은 너무 늦다.

양방향 충돌이 실제로 하는 일

정말 systemd가 관리하는 두 서비스의 경우 Conflicts=는 대칭이다. 하나를 시작하면 다른 하나가 멈춘다. 유닛 참조는 그 동작을 문서화하고, 하나가 멈추기를 끝낸 뒤 다른 하나가 시작해야 할 때 명시적 순서를 별도로 요구한다. 그 순서 항목이 없으면 중지와 시작이 경쟁하고 결과는 타이밍에 달린다.

이것은 거부 목록이 아니다. 의존성을 반대로 연결하면 앱 시작이 대신 VPN을 멈추게 되며, 예측 가능한 순간에 터널이 스스로 끊길 때 의심해야 할 고장이 바로 이것이다. 데스크톱 앱은 systemd 유닛이 아니고 NetworkManager 연결도 유닛이 아니므로 이 패턴은 직접 감싼 서비스에만 작동한다.

첫 실행이 아니라 전환을 시험하라

네 가지 전환이 요구 사항의 유지를 결정한다. 앱이 실행 중인 채 세션에 들어가기, 세션 중간에 다시 실행하기, VPN 시작 실패, 의도적 연결 해제다. 각각을 시험하고 결과를 유닛 파일 옆에 두라. 아래 명령은 현재 관계를 읽고 가장 중요한 전환을 연습한다.

systemctl show work-vpn.service -p Conflicts -p After
systemctl start work-vpn.service
systemctl is-active office-sync.service
nmcli connection show --active

세 번째 명령은 앱을 비활성으로 남겨야 하고, 네 번째는 세션이 도는 동안 터널 연결만 나열해야 한다. 다른 결과라면 그 전환은 전혀 강제되지 않는다.

세션 중 재실행은 래퍼 기반 설계를 드러내는 사례다. 데스크톱에서 시작한 바로가기는 실행 스크립트에 결코 묻지 않는다. 이 우회가 중요하다면 강제는 애플리케이션 제어에 속하며 VPN 클라이언트가 아니다. 세션의 끝도 문서화하고, 들어올 때 멈춘 모든 프로세스를 다시 여는 대신 의도적 재개를 선호하라. 각 전환의 결과를 유닛 파일을 보관하는 같은 메모에 기록하라.

관련 글