VPN을 자체 네임스페이스 안에서 시작하고 그곳에서 애플리케이션 하나를 실행해도 트래픽은 여전히 호스트 라우트로 나간다. 망가진 것은 없다: 네임스페이스는 들어오는 프로세스만 지배하며, 누출은 한 번도 들어오지 않은 프로세스에서 비롯됐다. 인터페이스, 주소, 라우트, 방화벽 규칙, 소켓이 네임스페이스가 소유하는 것이다. 파일, 계정, 이미 실행 중인 서비스는 그렇지 않으며, 놀라움의 대부분은 여기서 나온다.

네임스페이스가 소유하는 것, 그리고 소켓이 태어나는 곳

인터페이스를 네임스페이스로 옮기면 호스트는 그것을 잃고, 안에 터널을 만들면 호스트는 볼 수 없다. 이것이 네임스페이스로 한정된 VPN의 원리다: 장치와 그것을 가리키는 라우트는 선택된 프로세스만 닿을 수 있는 문맥에 존재한다. 호스트는 기본 라우트를 유지하므로 바깥의 모든 것은 그대로 남는다.

WireGuard에서는 생성 당시의 문맥이 현재 위치만큼 중요하다: UDP 소켓은 인터페이스가 만들어진 네임스페이스에 결합되며, 장치가 다른 곳으로 옮겨진 뒤에도 그렇다. 암호화된 패킷이 어느 라우팅 테이블을 따르는지는 그 태생에 달려 있다. 소켓이 피어로 가는 라우트가 없는 문맥에 남으면 인터페이스는 조회하고 핸드셰이크는 결코 나가지 않는다. 태생을 먼저 확인하고, 그다음 현재 위치를 확인한다.

네임스페이스가 격리하지 않는 것

여기서 무엇도 파일 시스템, 계정, 비밀을 분리하지 않는다, 그리고 네임스페이스를 만들었다고 해서 그런 경계가 생기는 것도 아니다. 리졸버 설정은 파일이므로 안의 프로세스는 여전히 호스트 리졸버를 가리키는 설정을 읽고 그 설정이 함축하는 라우트로 질의를 내보낼 수 있다. 요청을 이미 실행 중인 브로커나 시스템 서비스에 넘기는 애플리케이션은 전혀 다른 문맥의 프로세스를 개입시킨다. 둘 다 경계가 답하도록 설계된 적 없는 요청이다.

해법은 /etc/netns/<name>/resolv.conf에 네임스페이스별 파일을 두거나, 준비한 파일을 bind mount 하여 안에서 닿을 수 있는 리졸버를 가리키게 하는 것이다. 호스트의 /etc/resolv.conf을 편집해도 네임스페이스가 보는 것은 달라지지 않는다.

프로세스 배치가 곧 통제다

얻는 격리는 안에서 시작한 프로세스의 격리와 정확히 같다. 네임스페이스의 exec 도우미로 시작한 셸과 그것이 만드는 모든 것은 안에 남고, 호스트 세션에서 실행한 데스크톱 애플리케이션은 남지 않는다. 문맥을 만들고 장치를 옮긴 뒤 양쪽을 증명한다:

ip netns add vpn1
ip link set wg0 netns vpn1
ip netns exec vpn1 wg show
wg show

네임스페이스 안에서 첫 번째 wg show을, 호스트에서 두 번째를 읽고 둘 중 하나만 피어를 나열할 것이라 예상한다. 둘 다 나열하면 장치는 옮겨진 적이 없고, 어느 쪽도 나열하지 않으면 다른 곳으로 간 것이다. 실행기가 서비스 관리자라면 편집할 것은 unit 파일이지 데스크톱 바로가기가 아니다. 네임스페이스 설정이 없는 unit은 데몬을 호스트 문맥에서 시작하고 설계를 조용히 무효로 만든다.

애플리케이션의 문맥에서 시험한다

애플리케이션이 쓰는 것과 같은 바이너리, 같은 사용자로 네임스페이스 안에서 점검을 실행한다. DNS와 두 주소 체계를 모두 포함해야 한다: 생각하지 못한 IPv6 라우트가 흔한 출구이기 때문이다. 자신의 셸에서 한 시험은 자신의 셸이 격리됐다는 것만 증명한다.

그다음 호스트에서 동일한 점검을 실행해 답이 다르다는 것을 확인한다: 안에서는 터널 주소와 의도한 출구, 밖에서는 호스트 라우트와 사무실 출구, 그리고 리졸버는 이름으로 확인한다. 네임스페이스 이름은 프로토콜이 아니라 배포에 따라 붙여, 정리 스크립트가 둘을 혼동하지 않게 한다.

전달, 실패 정책, 정리

게이트웨이라면 전달을 의도적으로 켜고 터널이 끊겼을 때 무엇이 일어나야 하는지 정한다. 네임스페이스는 안에 설치한 라우트를 막지 않으므로 호스트로 가는 대체 라우트를 만들면 그것이 쓰인다. 이는 정책 결정이며, 장애가 시험하기 전에 기록해 두어야 한다.

네임스페이스 이름, 인터페이스, 설정 소유자를 기록해 정리가 배포가 만든 것만 제거하게 한다. 롤백 중 호스트 네트워킹을 초기화하면 정리가 장애가 된다. network_namespaces(7) 페이지는 짧고 그 경로를 설계하기 전에 읽을 가치가 있다.

관련 글