VPN이 끊겨도 아무것도 새지 않도록 리눅스 출구를 잠그는 방법
라우팅과 필터링은 별개의 결정입니다. 출력 훅을 잠그고, 터널이 다시 연결되는 데 필요한 엔드포인트, DNS, 관리 예외를 제한하십시오.
터널을 통해서만 인터넷에 나가야 하는 홈 회선의 미디어 박스를 떠올려 보십시오. 터널이 끊기면 애플리케이션은 물리 인터페이스로 조용히 계속 흐르는 대신 멈춰야 합니다. 이런 동작을 얻는 것은 라우팅이 아니라 방화벽의 문제이며, 그 구분이 중요한 이유는 라우트는 데몬 재시작으로 바뀔 수 있지만 필터는 놓아둔 자리에 그대로 남기 때문입니다. 이제 패킷 경로가 실제로 어떻게 판단하는지, 그리고 터널을 다시 연결시키는 예외를 어떻게 제한할지 살펴봅니다.
로컬 출력은 포워딩과 다른 훅입니다
머신의 애플리케이션에서 나가는 패킷은 출력 훅을 지나고, 머신이 다른 호스트를 위해 라우팅하는 패킷은 포워딩을 지납니다. forward만 언급한 정책은 후자를 제한하고 전자를 활짝 열어 두므로, 많은 출구 잠금이 맞아 보이면서 아무것도 하지 않습니다. 인터페이스 매칭도 같은 규칙에 속하며, oifname "tun0" accept은 이미 터널로 라우팅된 트래픽을 통과시킵니다. 라우팅과 필터링 역시 별개의 결정으로 남으므로, 필터가 패킷을 거부하는 동안에도 상향 링크 라우트는 존재할 수 있습니다. 여러분이 기대는 것은 바로 이 분리입니다.
다른 장치를 위해 포워딩하는 게이트웨이는 두 훅이 모두 필요합니다. 출력만 잠그면 머신 자체는 보호되지만 하위의 모든 클라이언트는 새어 나갈 자유를 얻습니다.
예외 목록은 엔드포인트에서 바깥으로 씁니다
터널 엔드포인트에서 시작하여 목적지 주소 하나 또는 승인된 작은 집합, 전송 프로토콜, 목적지 포트(예: udp dport 1194 ip daddr 203.0.113.7 accept)를 정합니다. 클라이언트가 호스트 이름을 해석한다면 초기 DNS 교환에는 리졸버와 포트 53으로 한정된 자체 규칙이 필요하며, 그 리졸버 주소에 대한 포괄 허가여서는 안 됩니다. 모든 예외는 존재하는 이유를 밝혀야 합니다. VPN 포트로 가는 모든 UDP 트래픽을 허용하면 염두에 두었던 하나의 인증된 서비스보다 훨씬 많은 것을 덮습니다.
초기 해석은 잠금이 흔히 썩는 지점입니다. 타이머로 갱신되는 주소 집합에는 갱신이 실패했을 때의 정의된 동작이 필요하며, 그 동작이 성공할 때까지 회선을 여는 것이어서는 안 됩니다. 터널이 올라와 있는 동안에는 터널로 갱신하고, 그렇지 않으면 마지막으로 알려진 정상 엔드포인트로 돌아갑니다.
로컬 관리도 같은 대우가 필요합니다. 관리 서브넷은 주소가 사설이라는 이유만으로 신뢰할 수 없으며, 그것을 신뢰하는 규칙은 잠금 주위로 두 번째 경로를 불러들입니다.
인터페이스 매칭은 건강한 터널의 증거가 아닙니다
tun0에서 나가는 모든 것을 받아들이는 규칙은 그 인터페이스의 패킷이 터널에서 왔다고 가정합니다. 인터페이스 이름은 다시 만들어지고, 이름은 암호학적 신원이 아닙니다. 피어가 사라져도 인터페이스가 올라와 있을 수 있어, 그 규칙은 매우 설득력 있는 무동작이 됩니다.
연결 추적은 관련된 함정을 더합니다. 설정된 연결에 대한 넓은 규칙은 흐름이 앞서 얻은 허가를 다시 재생하므로, 터널이 끊기기 전에 시작된 세션은 그 뒤에도 계속 동작합니다. 상태 기반 수락을 정말 의도한 인터페이스와 주소로 제한하지 않으면 스스로 열리는 잠금을 만든 것입니다. 입력과 출력 규칙도 서로 다른 질문에 답하며, 하나만 강화하고 다른 하나를 무시하면 고려하지 않은 방향으로 머신이 도달 가능한 채 남습니다.
데몬 크래시를 견디는 것
터널이 올라온 뒤에 실행되는 스크립트가 설치한 필터는, 바로 그것이 필요했던 순간에 터널과 함께 사라집니다. 잠금은 부팅 시 불러오고, 데몬에게는 그 예외만 관리하게 하십시오.
기본 라우트를 지우는 것도 대안이 아닙니다. 라우트는 데몬이 소유하고 다시 쓰는 상태이며, 지우면 다시 연결에 필요한 경로까지 잃을 수 있습니다. IPv6에는 이웃 탐색과 라우터 광고가 일반 트래픽이 차단된 동안에도 계속 동작해야 하는 링크 서비스이므로 자체 계획이 필요합니다. DHCP도 같은 범주입니다. 이것들은 나중에 장애로 발견하는 대신 목적이 있는 예외로 적어 두십시오.
배포 전 복구 경로
잠금이 실패할 그 방식, 즉 터널 없이 부팅하고, 데몬을 죽이고, 엔드포인트를 바꾸고, 다시 연결하는 방식으로 시험하십시오. 어느 경우든 애플리케이션은 멈추고 복구 통로는 살아 있어야 합니다. 원격 셸이야말로 자신의 규칙에 가장 잘 잠기는 세션이므로 이것은 콘솔에서 하십시오.
다음으로 일반 애플리케이션이 여전히 어디까지 닿는지 무해한 목적지와 검증할 수 있는 요청으로 확인합니다. 원하는 결과는 상향 링크에서의 거부와 터널을 통한 성공이며, 둘 중 무엇이든 될 수 있는 모호한 타임아웃이 아닙니다. 규칙 집합은 셸 스크립트에서 테이블 전체를 바꾸는 대신 방화벽의 나머지와 같은 소유자 아래 두십시오. 모든 허용이 스스로를 정당화할 수 있는 정책은 아무도 설명하지 못하는 긴 규칙 집합보다 값집니다.