브리지와 NAT는 같은 게스트를 VPN에 연결하는 두 가지 방법이 아닙니다. 두 방식은 터널이 개입하기 전에 게스트의 패킷이 누구 것인지를 정합니다. NAT 모드에서는 하이퍼바이저가 게스트의 트래픽을 다시 쓰고 호스트 측 코드에서 내보내므로, 게스트는 호스트가 그 코드에 준 경로를 따릅니다. 브리지 모드에서는 게스트가 물리 세그먼트에서 자체 링크 계층 식별자를 얻고 자체 기본 게이트웨이를 고르므로, LAN 라우터가 터널링하는 경우가 아니면 호스트의 터널은 게스트와 무관해집니다. 저는 VM을 'VPN 위에 있다'고 보는 것을 그만두고, 그 게스트의 기본 경로가 어디를 가리키는가라는 질문으로 다루기 시작했습니다. 아래 시험은 모드마다 몇 분이 걸리고 추측 없이 결론을 냅니다.

NAT는 게스트를 하이퍼바이저 코드 뒤에 두며, 그곳에서 호스트 경로가 적용된다

VirtualBox에서 NAT 게스트는 10.0.2.0/24에 있고 가상 게이트웨이는 10.0.2.2, DNS 프록시는 10.0.2.3에 있으며 물리 네트워크로 향하는 자체 경로는 없습니다. 나가는 패킷은 NAT 엔진이 가져가 출발지가 호스트가 되도록 다시 쓴 뒤 호스트의 IP 스택에 넘깁니다. 그 지점부터 게스트의 트래픽은 호스트 흐름이고 경로 조회는 목적지로 이뤄집니다. 0.0.0.0/1과 128.0.0.0/1을 호스트에 설치하는 전체 터널 클라이언트는 VM이 있다는 것조차 모른 채 그 트래픽을 붙잡습니다. Oracle의 VirtualBox 네트워킹 장에 이 기본값이 나옵니다. 자기 환경에서 주소를 확인하려면 참고하세요.

libvirt의 기본 네트워크도 192.168.122.0/24에서 같은 지점에 도달합니다. dnsmasq가 임대를 나누고 호스트가 서브넷을 마스커레이드하므로 게스트의 패킷은 다시 호스트의 라우팅 판단에 도착합니다. 예외는 경로가 아니라 프로세스로 트래픽을 고르는 클라이언트입니다. 분할 터널 목록에 브라우저만 있고 다른 것이 없다면 NAT 엔진은 그 목록에 없고, 게스트는 터널 없이 기계를 떠나지만 호스트의 브라우저는 여전히 보호되는 것처럼 보입니다. 같은 서브넷, 반대 결과입니다.

브리지는 게스트에게 물리 LAN에서 자기 자리를 준다

브리지 게스트에는 실제 어댑터에 연결된 가상 NIC가 주어지고, 자체 MAC 주소를 받으며 물리 네트워크에서 DHCP 임대를 받습니다. 기본 게이트웨이는 하이퍼바이저가 아니라 LAN 라우터이고, 프레임은 그 어댑터를 통해 선로로 나갑니다. 호스트의 터널 경로는 호스트의 표에 있고 결코 조회되지 않습니다. 게스트의 프레임이 호스트의 IP 스택에 들어가지 않기 때문입니다.

이것은 양방향으로 작용합니다. mDNS와 SMB 탐색이 작동하기 시작하는 것은 게스트가 LAN 브로드캐스트 트래픽을 보기 때문이고, 게스트는 사이에 호스트 방화벽 없이 같은 세그먼트의 다른 기계에서 접근할 수 있게 됩니다. 브리지는 기존 터널로 게스트를 밀어 넣는 수단도 아닙니다. VM을 호스트의 WireGuard나 OpenVPN 인터페이스에 붙이는 일은 VirtualBox나 libvirt가 대신 해 주지 않습니다. 브리지 게스트가 터널을 거쳐야 한다면 터널은 그 LAN 어딘가에서 끝나야 합니다.

논쟁을 끝내는 시험

두 모드에서 같은 점검을 실행하고 답을 적어 두세요.

  • 호스트에서 curl -s https://ifconfig.me는 공인 v4 주소를 줍니다.
  • 게스트에서는 같은 명령에 더해 기본 게이트웨이를 위해 Linux에서는 ip route, Windows에서는 Get-NetRoute -DestinationPrefix 0.0.0.0/0을 실행합니다.
  • 리졸버 정체: 게스트에서 resolvectl status 또는 cat /etc/resolv.conf로 10.0.2.3을 가리키는지 LAN 서버를 가리키는지 봅니다.
  • 주소 체계: ip -6 addr show scope global과 v6 요청 하나. v4 터널은 게스트가 가질 수 있는 전역 v6 주소에 대해 아무 말도 하지 않습니다.

공인 주소가 같다면 게스트는 호스트의 경로에 있습니다. 게스트 주소가 LAN의 평소 출구와 같다면 그렇지 않습니다. 사람들이 건너뛰는 단계는 대조 실험입니다. 호스트 터널을 내리고 게스트 요청을 다시 하세요. 그래도 게스트가 탐색을 계속한다면 모드 이름이 무엇을 암시하든 그 게스트는 호스트 터널에 의존한 적이 없습니다. NAT 모드라면 호스트 터널을 내렸을 때 게스트가 인터넷을 잃어야 합니다. 클라이언트가 터널 밖 트래픽을 허용하도록 설정된 경우는 예외이며, 그것 자체로 알아 둘 가치가 있습니다.

두 신호는 거짓말을 합니다. 성공한 ping은 도달 가능성을 증명할 뿐 출구 경로를 증명하지 않습니다. 그리고 DNS는 호스트 리졸버를 거쳐 10.0.2.3 프록시가 응답하는데 TCP는 다른 경로를 탈 수 있습니다. 페이지는 열리는데 로그인이 끝나지 않는 상황이 그렇게 생깁니다.

어떤 모드가 작업에 맞는가

모드는 라우팅 결정이므로 습관이 아니라 요구 사항에서 고르세요.

RequirementMode that fits
Every guest flow must exit through the host tunnelNAT, with a host client that tunnels by route, verified from inside the guest
The guest needs its own VPN account or profileBridged, or NAT with a client running inside the guest, not both
The guest must serve SSH, SMB, or a dev server to the LANBridged; NAT needs a port forward, which does not change the outbound path
The guest must stay invisible to the LANNAT; a bridged guest is another host on the segment
The guest needs a real public IPv6 addressBridged; VirtualBox NAT mode has no IPv6 forwarding
Isolation from the LAN with access to the hostHost-only adapter, not NAT

첫 줄이 사람들이 걸리는 지점입니다. NAT에 호스트의 전체 터널 클라이언트를 더하면 게스트를 덮는 것은 맞지만, 클라이언트가 경로로 터널링하고 호스트의 상향 링크가 그 터널인 동안만 그렇습니다. 클라이언트를 브라우저만 허용하는 목록으로 옮기면 어디에서도 오류 없이 보호가 사라집니다. 넷째 줄은 반대 방향의 실수입니다. 편의를 위해 브리지한 게스트가 사무실 LAN에서 조용히 SMB나 SSH에 응답하기 시작합니다.

VPN 탓으로 돌려지는 장애

Windows에서는 NAT 변환이 VirtualBox VM 프로세스 안에서 실행되므로, 앱별 클라이언트는 가상 머신 전반에 걸친 규칙이 아니라 바로 그 이미지를 목록에 넣어야 합니다. 클라이언트 업데이트가 프로세스 목록을 다시 만들면 NAT 게스트가 가장 먼저 보호를 잃고, 보고서는 호스트는 멀쩡한데 VM이 LAN에는 닿고 인터넷에는 닿지 않는다는 형태로 올라옵니다.

Wi-Fi로 브리지하는 것도 단골입니다. 액세스 포인트는 외부 출발지 MAC을 가진 프레임을 좀처럼 전달하지 않으므로, wlan0로의 브리지는 아주 실패하거나 AP의 클라이언트 격리가 떨어뜨리기 시작할 때까지 동작합니다. VirtualBox는 그래도 목록에 무선 어댑터를 제시합니다. 호스트가 Wi-Fi에 있고 게스트를 브리지해야 한다면 가정하지 말고 시험할 계획을 세우세요.

셋째는 MTU입니다. 브리지 게스트는 LAN의 1500바이트 MTU를 유지합니다. 그 게스트가 자체 WireGuard 클라이언트를 1420에서 돌리면 작은 요청은 통과하는데 큰 TLS 핸드셰이크가 멈춥니다. NAT 아래에서는 호스트 터널의 MTU가 호스트의 문제이지만, 게스트는 여전히 1500을 믿고 있고 don't-fragment 비트를 세운 UDP는 같은 방식으로 사라집니다.

모드를 기록하고 어댑터를 바꾼 뒤 다시 확인한다

모드, 브리지가 쓰는 호스트 인터페이스, 게스트의 기본 게이트웨이, 리졸버, v4와 v6 출구 주소를 기록하세요. 그 기록이 다음 장애를 싸게 만듭니다. 노트북이 도크에서 Wi-Fi로 옮겨 가면 브리지 게스트는 브리지를 따라 다른 물리 어댑터로 이동해 다른 서브넷에서 임대를 다시 받을 수 있습니다. 반면 NAT 게스트는 10.0.2.x 주소를 유지하고 조용히 다른 상향 링크를 물려받습니다.

티켓을 닫기 전에 다음 항목을 확인하세요.

  • 게스트의 출구 주소가 호스트의 출구 주소와 다르므로 호스트 터널 위에 있지 않습니다.
  • 리졸버가 10.0.2.3 프록시이거나 LAN 서버이고, 어느 쪽이 응답했는지 압니다.
  • 터널 설계가 v4 전용이라면 게스트에 전역 v6 주소가 없습니다.
  • 호스트 터널을 내리면 게스트가 탐색을 멈추거나, 이제 그 게스트가 그것에 의존한 적이 없음을 압니다.
  • 게스트가 관계없는 LAN 브로드캐스트 트래픽을 보고 있지 않습니다.

관련 글