리눅스 한 대에서 VPN 두 개: 결과를 섞지 않고 각각 따로 시험하기
초록색 아이콘 두 개는 비교가 아니다. 각 터널을 자기 네트워크 네임스페이스에 넣고, 기대를 먼저 적고, 결과를 믿기 전에 경로를 증명하라.
초록색 연결 아이콘 두 개는 비교처럼 보이지만 대개는 우연이다. 시험 요청이 두 터널 중 어느 것을 써도 되었다면, 결과는 잘해야 둘 중 하나를 설명하고 못하면 둘 다 설명하지 못한다. 모든 관찰에 네트워크 문맥과 의도한 목적지, 그리고 시험을 실행하기 전에 적어 둔 기대를 붙여라. 직접 관리하는 리눅스에서는 이름이 붙은 네트워크 네임스페이스가 그 분리를 사는 가장 싼 방법이다.
초록불 두 개는 비교가 아니다
네임스페이스는 라우팅 테이블, 인터페이스, 네트워크 스택 상태를 분리하므로 한쪽 안에서 시작한 요청이 다른 쪽 터널을 조용히 빌려 쓸 수 없다. 분리하지 못하는 것은 CPU, 물리적 업링크, 호스트에서 도는 리졸버 데몬이다. 바로 이 마지막 틈에서 이런 시험 대부분이 아무도 모르게 실패한다. 네임스페이스를 떠나 호스트 리졸버에 묻는 조회는 시험 중인 터널과 아무 관계도 없는 답을 돌려준다.
이 절차는 이미 준비되어 승인된 시험용 네임스페이스 두 개와 동작하는 외부 연결, 지원되는 클라이언트를 전제한다. 무엇도 만들지 않고, 무엇도 등록하지 않으며, 어떤 설정도 바꾸지 않는다. 클라이언트가 완전한 데스크톱 세션을 필요로 하거나 그 밖에서 도는 것을 거부하면 별도의 가상 머신이 정직한 선택이다.
첫 실행 전에 기대를 고정하라
문맥마다 성공이 어떤 모습인지 정하라. 리졸버, 서비스 이름, 기대하는 주소, 그리고 터널이 끊길 때 요구되는 행동이다. 이 계획 값은 따로 둔 칸에 넣어라. 계획과 관찰을 섞은 기록은 시각 도장이 찍힌 허구다. 아래 점검 목록이 기록에 필요한 형태이며, 첫 연결 전에 모든 행을 채울 수 있어야 한다.
| Tunnel | Owner | Client interface inside the namespace | Proof command | Required on disconnect |
|---|---|---|---|---|
| vpn-a | the identity that owns profile A, recorded by name | its own tun device, never the host's | ip -n vpn-a -4 route get 10.55.10.20 | traffic stops; no host-side fallback |
| vpn-b | a separate owner, even when both run on one box | its own tun device in its own namespace | ip -n vpn-b -4 route get 10.55.20.20 | verified separately, never inferred from A |
가장 거짓말하기 쉬운 항목이므로 리졸버 배선은 그 기록에서 제 줄을 차지해야 한다. 네임스페이스에 묶인 파일은, 예를 들어 /etc/netns/vpn-a/resolv.conf 명령이 네임스페이스 안에서 실행될 때 늘 쓰던 경로에 나타나며, iproute2의 네임스페이스 설명서 가 설명하는 대로다. 다만 이름 서비스 전환 설정과 그것이 띄우는 로컬 리졸버는 조회를 다시 호스트로 끌어올 수 있다.
한 번에 터널 하나, 다른 하나는 끊긴 채로
B를 내려 둔 채 A를 기존 소유자를 통해 연결하고, 관리 문맥에서 정책과 라우트, 선택된 경로를 살펴라. 아래 명령 중 셋은 상태를 읽을 뿐이고, 마지막 하나만 이름 서비스에 닿으며, 어느 것도 응용 프로그램 요청을 보내지 않는다.
sudo ip -n vpn-a -4 rule show
sudo ip -n vpn-a -4 route show table all
sudo ip -n vpn-a -4 route get 10.55.10.20
sudo ip netns exec vpn-a getent ahostsv4 svc-a.lab.internal라우트 조회는 목적지에 대한 가정적 질문에 답할 뿐이므로 서비스가 트래픽을 받는지 보여 주지 못한다. 이 두 종류의 증거는 다른 칸에 두어라. 거부된 연결 옆의 건강한 라우트는 실제로 흔한 결과이기 때문이다. 다음으로 실제 응용 프로그램으로 무해한 승인 요청 하나를 보내라. A의 문맥에서 그 본래의 비특권 사용자로 띄우고, 인증서 검증과 응용 프로그램 인증은 그대로 둔다. 그리고 서비스가 본 출발지 주소와 함께 결과를 기록한다. A를 그 소유자를 통해 끊고 B에 대해 같은 기준선을 모두 반복하라. 설정을 바꾼 것이 있으면 적어라. 그러지 않으면 두 기준선은 비교할 수 없게 된다.
둘 다 올린 다음 하나씩 내린다
정상 상태는 쉬운 부분이다. 두 터널이 연결된 채로 각 문맥의 조회와 응용 프로그램 요청을 반복하고, 다음에 한 터널을 끊어 다른 쪽을 확인하라. 연결 순서 자체가 질문일 때는 거꾸로 다시 연결한다.
sudo ip netns exec vpn-a tcpdump -ni any port 443 -c 5
sudo ip netns exec vpn-b getent ahostsv4 svc-b.lab.internal
sudo ip -n vpn-b -4 route get 10.55.20.20캡처는 응용 프로그램 결과로는 결판나지 않는 논쟁을 결판낸다. 요청이 기대한 인터페이스로 나갔는지, 아니면 전혀 다른 것으로 나갔는지를 보여 준다. 전이마다 소유자의 조치, 시각, 라우트 결과, 이름 결과, 응용 프로그램 결과를 기록하라. 그다음 영향받은 네임스페이스 안에서 실패 시 차단 요건을 확인하라. 격리는 킬 스위치가 아니다. 네임스페이스는 두 터널을 갈라 두지만, 프로필이 트래픽을 멈춰야 한다고 말할 때 어느 쪽도 트래픽을 나르지 못하게 하지는 않는다.
이 기록이 주장할 수 있는 것과 없는 것
합격은 이 배치에 대해, 이 호스트에서, 그 시점의 관찰을 증명한다. 데스크톱 라우팅 테이블 하나를 공유하는 두 클라이언트에 대해서는 아무 말도 하지 않고, 두 터널이 부하를 나를 때의 처리량에 대해서도 아무 말도 하지 않는다. 그것은 각기 다른 시험이 필요한 다른 질문이며, 비교는 각 행에 붙은 문맥만큼만 쓸모가 있다.
실패도 성공 옆에 기록하고, 그 시점에 어느 터널이 올라 있었는지 표시하라. 측정 시점의 상태를 감추는 깨끗한 페이지는 그것을 보여 주는 못생긴 페이지보다 나쁘다. 기록을 나중에 다시 쓸 수 있게 하는 것은 점수가 아니라 문맥이다.
한 기계 위의 두 터널은 정직하게 비교할 수 있지만, 실제로 통제한 만큼의 문맥 안에서만 가능하다. 그 너머는 옆에 초록 아이콘이 붙은 소망일 뿐이다.