방화벽 프로필과 VPN 이그레스: 공용이 경로가 아닌 이유
방화벽 프로필은 어떤 규칙 집합이 적용되는지 고른다. 어떤 인터페이스가 패킷을 실었는지는 말하지 않으며, 명시적 차단은 더 좁은 허용보다 우선한다.
이 규칙은 정확해 보인다. 개인 프로필에서는 로컬 트래픽을 허용하고 공용 프로필에서는 VPN 트래픽만 허용하라는 것이다. 하지만 그렇지 않다. 네트워크 프로필은 어떤 방화벽 규칙 집합이 적용되는지를 고를 뿐이고, 어떤 어댑터가 패킷을 실었는지는 말하지 않는다. 프로필 이름을 경로 요구 사항으로 다루는 것이, 제한된 이그레스 설계를 실제로는 미완성인데도 완성된 것처럼 보이게 만드는 실수다.
먼저 흐름을 적고, 그다음 각 흐름을 실제로 강제할 수 있는 메커니즘을 정한다. 그 흐름 목록만이 다음 규칙 변경을 견디는 유일한 산출물이다.
범주는 규칙을 고르지 경로를 고르지 않는다
Windows가 네트워크를 공용 또는 개인으로 분류하면 방화벽은 그 프로필에 구성된 규칙 집합을 적용한다. 분류는 어댑터가 연결한 네트워크를 따르고, 규칙 집합은 그 위에서 무엇이 허용되는지를 정한다. 이 두 사실 중 어느 것도 애플리케이션 트래픽이 터널을 썼는지에 의존하지 않는다. 바로 이 독립성이 전체 어려움이다.
경로 선택은 라우팅이 한다. 인터페이스 메트릭과 터널이 설치하는 접두사를 통해서다. 따라서 프로필이 공용으로 표시되어 있어도 애플리케이션 연결이 물리 경로를 탈 수 있고, 방화벽은 여전히 공용 규칙 집합이 적용되었다고 보고한다.
그래서 프로필에 한정된 규칙은 터널 전용을 뜻할 수 없다. 두 속성은 서로 다른 구성 요소가 결정하며 하나가 다른 하나를 대신할 수 없다.
| Flow | What decides it | What a rule can enforce |
|---|---|---|
| VPN client to its endpoint | Routing plus the outer transport | Allow the client process before the tunnel exists |
| Application to an internet host | Interface metric and prefix length | Block the process unless the tunnel interface is up |
| Application to a LAN host | Local subnet route | Allow one destination, not the whole category |
명시적 차단이 더 좁은 허용보다 우선한다
Microsoft의 방화벽 규칙 지침은 기본 차단 동작에 대한 허용 예외와 허용과 충돌하는 명시적 차단을 구분한다. 명시적 차단이 그 충돌에서 이기며, 아웃바운드 규칙도 같은 우선순위를 따른다.
그래서 모든 것을 차단하는 규칙을 추가하고 그 위에 놓인 더 좁은 허용에 기대는 인기 있는 처방은 작성자가 기대하는 대로 동작하지 않는다. Windows 방화벽은 관리자가 지정한 규칙 순서로 충돌을 해결하지 않는다. 차단이 그냥 적용되고, 연결하는 애플리케이션은 시간 초과를 보고한다. 예외처럼 보였던 규칙은 처음부터 경쟁에 없었다.
지원되는 형태는 승인된 허용 규칙을 갖춘 기본 거부 정책이며, 각 허용은 프로그램, 서비스 또는 대상을 검토할 수 있을 만큼 정확히 지정한다. 그 설계는 감사를 견딘다. 모든 예외가 보이고 어느 것도 생성 순서에 의존하지 않기 때문이다.
서로 모순되는 두 규칙은 한 규칙보다 나쁘다. 결과 동작이 옳으면서 동시에 설명할 수 없기 때문이다.
아웃바운드 정책에 단일 소유자를 부여한다
지원되는 VPN 클라이언트는 이미 자체 차단 동작과 자체 엔드포인트 예외를 유지한다. 조정되지 않은 수동 규칙을 추가하면 그 클라이언트가 설정에 필요한 터널 밖에 남거나, 아무도 알아차리지 못한 두 번째 경로가 열린 채로 남을 수 있다.
규칙을 쓰기 전에 아웃바운드 정책의 소유자를 정한다. 클라이언트 자체 구성, 관리되는 방화벽 정책, 소유자가 명시된 문서화된 로컬 예외 목록 중 하나다. 그다음 무언가 연결될 때까지 실험을 쌓는 대신 계층을 조정한다. 이름 있는 소유자는 두 계층이 어긋날 때 물어볼 사람이기도 하다.
무엇이든 바꾸기 전에 복구 채널을 남긴다. 자체 관리 경로에서 잠긴 원격 머신은 닫으려던 정책 공백보다 나쁜 결과다. 복구 규칙은 미리 적어 두면 정당화하기 쉽고, 아무도 좋아하지 않는 시간에 변경이 잘못될 때 찾기도 쉽다.
레이블을 읽는 대신 네 가지 결과를 시험한다
정책은 구별하는 사례만큼만 쓸모가 있으므로 프로필 레이블은 결과가 아니라 출발점으로 다룬다. 네 가지 결과가 작동 여부를 알려 준다. 의도한 LAN 요청이 성공하고, 포함된 인터넷 요청이 성공하고, 금지된 직접 요청이 실패하고, 터널 장애 사례가 조용히 후퇴하는 대신 설계대로 동작한다. 네 결과를 규칙 변경 옆에 적는다. 이름 있는 네 사례로 이루어진 시험 계획은 매번 실행할 만큼 짧고 크게 실패할 만큼 구체적이다.
Get-NetConnectionProfile | Select-Object Name,NetworkCategory,InterfaceAlias Get-NetFirewallProfile | Select-Object Name,DefaultOutboundAction Get-NetFirewallRule -Direction Outbound -Enabled True | Where-Object Action -eq Block | Select-Object DisplayName,Profile
첫 번째 명령은 연결된 각 네트워크가 어떻게 분류되었는지 보여 주며, 이는 규칙을 쓴 사람이 가정한 것과 다른 경우가 많다. 두 번째는 프로필별 기본 동작을 보여 주고, 세 번째는 사용하도록 설정된 아웃바운드 차단을 나열하며, 더 좁은 허용을 조용히 덮어쓸 것도 포함한다.
네트워크가 바뀐 뒤 네 사례를 다시 실행한다. 머신이 다른 네트워크에 연결되면 프로필이 다시 분류될 수 있기 때문이다. 일치하는 프로필 레이블은 경로가 의도한 것이었다는 증거가 아니다.