TUN OpenVPN 서버를 통해 host-only VM 트래픽 라우팅하기
터널과 host-only 프리픽스를 분리하고, 게스트 경로를 푸시한 다음, 각 가상 머신에 호스트를 거치는 의도적인 반환 경로를 부여합니다.
host-only 어댑터는 로컬 가상 네트워크를 만들고, 라우팅된 TUN 터널은 주소 사이에서 IP 패킷을 운반합니다. 둘 중 어느 것도 다른 쪽으로 향하는 브리지가 아니므로, 동작하는 구성은 누가 포워딩하고 반환 경로가 누구의 것인지 말해야 합니다. 이 두 가지 할당을 잘못하면 게스트는 터널 클라이언트가 요청한 적 없는 출발지로 터널에 응답합니다. 아래 설계는 두 프리픽스를 분리하고 반환 경로를 명시적으로 만듭니다.
두 네트워크, 두 프리픽스
터널 풀과 host-only 네트워크에 서로 다른 프리픽스를 주고, 하나를 다른 하나에 재사용하지 마십시오. 이 예에서 VPN 풀은 10.44.0.0/24이고 host-only 네트워크는 192.168.99.0/24이며, 호스트는 192.168.99.1, 게스트는 192.168.99.20에 있습니다. 같은 프리픽스를 TUN 장치와 host-only 어댑터 양쪽에 할당해도 둘은 결합되지 않습니다. 하나의 주소 범위에 두 개의 주장이 생기고, 라우팅 테이블은 우연히 유지한 쪽의 주장에 답합니다.
host-only 어댑터는 호스트와 게스트 내부 모두에 존재하며, 그 자체로는 머신 밖으로 나가는 경로가 없습니다. 브리지 및 NAT 연결은 노출이 다르며, 게스트 서비스 하나에 도달하기 위해 브리지 모드로 전환하는 것은 요구 사항이 아닙니다.
호스트는 이미 경로를 쥐고 있습니다
무언가를 추가하기 전에 무엇이 있는지 보십시오. 호스트에는 host-only 네트워크의 인터페이스와 그 프리픽스에 대한 경로가 있으며, 둘 다 어댑터가 올라올 때 생성되었습니다.
ip -br addr show
ip route show 192.168.99.0/24
sysctl net.ipv4.ip_forward
세 번째 줄은 호스트를 홉으로 만드는 메커니즘입니다. 그것이 없으면 터널에서 도착한 패킷은 호스트가 도달할 수 있지만 포워딩하지는 않을 네트워크로 주소 지정됩니다. 포워딩은 필요하지만 충분하지 않습니다. 필터 정책은 터널 인터페이스와 host-only 인터페이스 사이의 특정 흐름이 허용되는지 여전히 결정하며, 그 결정은 아무도 읽지 않은 기본 정책이 아니라 문서로 남아야 합니다.
경로를 푸시한 다음, 그것이 닿는 범위를 필터링하십시오
서버는 푸시된 경로를 받아들이는 클라이언트에 host-only 프리픽스를 제공할 수 있으며, 이는 터널 뒤의 다른 서브넷에 사용되는 것과 같은 메커니즘입니다.
push "route 192.168.99.0 255.255.255.0"
iptables -A FORWARD -i tun0 -o vboxnet0 -d 192.168.99.20 -p tcp --dport 5432 -j ACCEPT
iptables -A FORWARD -i vboxnet0 -o tun0 -s 192.168.99.20 -p tcp --sport 5432 -m conntrack --ctstate ESTABLISHED -j ACCEPT
이 두 규칙은 한 방향의 서비스 하나와 그 응답을 허용합니다. 전체 프리픽스에 도달하는 경로와 포트 하나를 허용하는 필터는 의도적인 조합이며, 경로에 무조건적 수락을 더하면 실험실 서비스가 노출된 서비스가 되는 방식입니다. 푸시된 경로도 권한 부여가 아닙니다. 클라이언트가 받아들이고, 호스트가 포워딩하며, 게스트 방화벽과 서비스 자체는 여전히 발언권을 가집니다.
게스트에게는 돌아갈 길이 필요합니다
10.44.0.x에서 도달하는 게스트는 응답을 호스트의 host-only 주소로 보내야 하며, 그렇지 않으면 호스트가 출발지를 변환해야 합니다. VirtualBox DHCP에서 주소를 받는 것은 두 배치 중 어느 것에 대해서도 말해 주지 않습니다.
ip route add 10.44.0.0/24 via 192.168.99.1 dev enp0s8
ip route get 10.44.0.15
게스트 안에서 그 경로를 추가하면 원래 출발지가 보존되어 클라이언트별 정책과 로그가 의미를 유지합니다. 호스트에서 범위가 제한된 출발지 변환이 대안이며, 그것도 동작하지만 어느 클라이언트가 연결했는지 감추는 대가를 치릅니다. 겹침은 또 다른 실패 모드입니다. 집 LAN이 이미 192.168.99.0/24를 쓰는 원격 클라이언트는 푸시된 경로를 자기 네트워크로 읽고, 서버 측 변경으로는 그 모호함이 해결되지 않습니다. 한쪽 번호를 다시 매기거나 충돌 가능성이 낮은 프리픽스를 고르십시오.
TUN 장치는 IP 패킷을 운반하므로, 게스트 안에 기본 게이트웨이를 추가해도 터널이 host-only 어댑터와 이더넷 세그먼트가 되지는 않습니다. TAP 브리지는 자체 클라이언트 지원과 주소 소유권을 가진 다른 설계이며, 두 설명을 섞으면 결코 수렴하지 않는 구성이 됩니다.
검증하고, 재시작을 견디게 만드십시오
일반 원격 클라이언트에서 무해한 서비스 하나를 시험하고, 게스트의 반환 경로를 확인하고, 허용하지 않은 서비스가 느린 것이 아니라 거부되는지 확인하십시오.
ss -lntp '( sport = :5432 )'
conntrack -L | grep 192.168.99.20
그다음 VPN 서비스와 가상 머신 네트워킹을 재시작하고 같은 세 가지 점검을 반복하십시오. 손으로 추가한 경로는 다음 재부팅까지만 유지되며, 따뜻한 세션에서만 동작하는 구성은 설계가 아닙니다. 두 프리픽스, 포워딩 정책, 게스트 경로를 함께 기록하십시오. 다음 가상 머신을 추가하는 사람은 세 가지 모두 필요하며, 그렇지 않으면 실패한 연결마다 그것들을 다시 발견하게 됩니다.