How to Force All VirtualBox VM Traffic Through VPN with IPTables Routing (Avoiding Double NAT)


4 views

When dealing with VPN routing for VirtualBox VMs, we need to consider three critical network components:

1. Host physical interface (eth0/enp0s3)
2. VirtualBox host-only network (vboxnet0)
3. VPN tunnel interface (typically tun0)

First, configure your VM to use Host-only Adapter in VirtualBox settings. Then implement these iptables rules on the host:

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# NAT all VM traffic through VPN
iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE

# Block all non-VPN traffic from VM
iptables -A FORWARD -i vboxnet0 -o eth0 -j DROP
iptables -A FORWARD -i vboxnet0 ! -o tun0 -j DROP

For better performance, consider setting up a bridged TAP interface:

# Create TAP interface
sudo tunctl -t tap0 -u $(whoami)
sudo ifconfig tap0 up

# Bridge with physical interface
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo brctl addif br0 tap0
sudo ifconfig br0 up

To use different VPN endpoints without double tunneling:

# On host (assuming OpenVPN):
route-nopull
route 10.8.0.0 255.255.255.0

# On guest VPN config:
redirect-gateway def1
route 10.8.1.0 255.255.255.0 10.8.0.1

Check your routing with these commands:

# Verify routes
ip route show
traceroute 8.8.8.8

# Test VPN leak protection
curl https://ipleak.net/json/

When configuring a VirtualBox VM to route traffic exclusively through a VPN while maintaining separate host connectivity, we need to carefully architect the network stack. The key components are:

Host Machine:
- Physical NIC (eth0)
- VPN TUN interface (tun0)
- VirtualBox Host-Only Network (vboxnet0)

Guest VM:
- Virtual NIC (eth0)
- Potential secondary interface for management

The most reliable approach uses VirtualBox's host-only networking combined with iptables rules:

# On Host Machine:
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Create NAT rules for VM traffic
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -A FORWARD -i vboxnet0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o vboxnet0 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Block all non-VPN traffic from VM
iptables -A OUTPUT -m owner --uid-owner vboxuser -o ! tun0 -j DROP

For lower latency and better throughput, consider bridging:

# Create persistent TAP interface
tunctl -t tap0 -u $(whoami)
ifconfig tap0 up

# Bridge configuration
brctl addbr br0
brctl addif br0 tap0
brctl addif br0 tun0
ifconfig br0 up

# In VirtualBox VM settings:
Adapter 1: Bridged Adapter, Name: tap0

To maintain separate VPN endpoints for host and guest:

# Create separate routing table for VM traffic
echo 200 vmrouting >> /etc/iproute2/rt_tables

# Route VM traffic through alternate VPN
ip rule add from 192.168.56.0/24 table vmrouting
ip route add default via 10.8.1.1 dev tun1 table vmrouting

# Policy routing for the host
ip rule add not from 192.168.56.0/24 table main

To ensure traffic drops when VPN fails:

# Monitoring script
while true; do
  if ! ping -c 1 -W 1 vpn-gateway; then
    iptables -A OUTPUT -m owner --uid-owner vboxuser -j REJECT
    killall -9 openvpn
  else
    iptables -D OUTPUT -m owner --uid-owner vboxuser -j REJECT 2>/dev/null
  fi
  sleep 30
done