Skip to content

Instantly share code, notes, and snippets.

@lukirs95
Created June 10, 2025 15:42
Show Gist options
  • Select an option

  • Save lukirs95/22df5447faaee2352d3d56f37a4aa6b3 to your computer and use it in GitHub Desktop.

Select an option

Save lukirs95/22df5447faaee2352d3d56f37a4aa6b3 to your computer and use it in GitHub Desktop.
How to access Host VPN Network from UTM Guest on MacOS

Problem

Your host machine (MacOS) get's an ip address from your VPN provider and possibly some routes to the remote network, but your VPN provider has no clue about other networks inside your host machine. That's what blocks UTM (QEMU) virtual machines from accessing the vpn network. UTM generates a new network for vm's and route entries for it automatically. This network is not known at the other side of the VPN, so although your PINGs reach the VPN the receiver of that ping does not know where to send it back.

Solution

The key solution is S-NAT (Source Network Address Translation). We have to tell the host machine (you're Mac where UTM is running on) to forward all packets from the virtual machines to the VPN with the IP address the host got from the VPN.

How to

First of all we have to enable ip routing, so MacOS can forward packets from one network to the other.

sudo sysctl -w net.inet.ip.forwarding=1

Now we need to enable the packet filter in the macos kernel to perform nat actions.

sudo pfctl -e

In order to perform the last step we need to find out what IP network macos uses for the virtual mashine and which virtual network device MacOS created for the VPN. In the virtual machine we need to find out the ip address and the network. For the vpn interface we need to lookup the ip we got from the VPN provider in System Settings -> VPN -> Info -> IP Address.

This IP Address we now use to look up the device with

netstat -rn -f inet

There you should find the ip network with the corresponding interface under "Netif" (something like "ipsec0"). We assume the network macos assigned to utm is 10.200.3.0/24 and the VPN interface is ipsec0.

Now we can create the NAT entry with

echo "nat on ipsec0 from 10.200.3.0/24 to any -> ipsec0" | sudo pfctl -f -

You should now see something like

pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

No ALTQ support in kernel
ALTQ related functions disabled

and you're good to go.

This is not persisting, so reboot of your host machine will remove the nat entry.

With

sudo pfctl -d

sudo sysctl -w net.inet.ip.forwarding=0

you can disable everything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment