This script automatically configures macOS packet filter (pf) to enable Multipass VMs to access resources through AWS VPN Client while maintaining internet connectivity.
Created as a way to bypass this issue: (Multipass VMs don't route traffic over VPN established on host (MacOS)) canonical/multipass#1336
The script dynamically detects and configures:
- VPN traffic routing: Routes traffic to private networks (10.x.x.x, 172.16.x.x) through the AWS VPN tunnel
- Internet traffic routing: Routes all other traffic through your regular internet connection
- NAT configuration: Sets up proper Network Address Translation for both paths
- Packet filter rules: Configures macOS pf to handle traffic intelligently
- Multipass installed with at least one running VM
- AWS VPN Client installed and connected
- Bridge networking configured for your Multipass VM
- sudo privileges to modify system network configuration
- Boot your laptop
- Launch and connect to AWS VPN Client
- Start your Multipass VM(s)
- Run the setup script:
./setup_vpn_routing.shThe script will:
- ✅ Detect your network interfaces automatically
- ✅ Find the AWS VPN tunnel interface (utun*)
- ✅ Discover VPN routes dynamically
- ✅ Generate and install pf rules
- ✅ Enable IP forwarding
- ✅ Load and activate the configuration
🔍 Detecting network configuration...
Looking for Multipass bridge interface...
✓ Multipass bridge: bridge100
Looking for WAN interface...
✓ WAN interface: en0
Looking for AWS VPN Client tunnel interface...
(Checking for utun* interfaces with VPN routes)
Found VPN routes on utun4:
- 10.110.1/27
- 172.16
✓ AWS VPN interface: utun4
✓ VPN routes found: 2
📝 Generating pf anchor configuration...
Normalized routes:
- 10.110.1.0/27
- 172.16.0.0/12
📦 Installing pf anchor configuration...
(requires sudo password)
✓ Anchor file created: /etc/pf.anchors/multipass_vpn
📝 Checking main pf configuration...
✓ Anchor already configured in /etc/pf.conf
🔧 Enabling IP forwarding...
✓ IP forwarding enabled
🚀 Loading pf rules...
✓ Configuration validated
✓ pf rules loaded and enabled
✅ Configuration complete!
From your Multipass VM, test access to VPN resources:
multipass exec <vm-name> -- curl https://internal-resource.example.com/...Test internet connectivity:
multipass exec <vm-name> -- curl https://www.google.comMake sure your Multipass VM is running. Check with:
multipass listIf your VM exists but isn't running:
multipass start <vm-name>The AWS VPN Client must be connected before running this script.
- Open AWS VPN Client
- Connect to your VPN
- Wait for connection to establish
- Run the script again
To verify VPN is connected:
netstat -rn -f inet | grep utunYou should see routes to 10.x or 172.16.x networks.
This is expected! The pf configuration is loaded at boot, but the VPN interface and routes change. Simply run the script again after connecting to VPN.
┌─────────────────────────────────────────────────────┐
│ macOS Host │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ en0 │ │ utun4 │ │
│ │ (WAN) │ │ (AWS VPN) │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ │ ┌────────────────┐ │ │
│ └────┤ pf (packet ├─┘ │
│ │ filter) │ │
│ └────────┬───────┘ │
│ │ │
│ ┌────────┴───────┐ │
│ │ bridge100 │ │
│ │ (Multipass) │ │
│ └────────┬───────┘ │
│ │ │
│ ┌────────┴───────┐ │
│ │ VM (Ubuntu) │ │
│ │ 192.168.2.x │ │
│ └────────────────┘ │
└─────────────────────────────────────────────────────┘
-
VM → VPN Resources (172.16.x.x, 10.x.x.x):
- Packet leaves VM with destination 172.16.x.x
- Reaches bridge100 (Multipass bridge)
- pf NAT rule matches → translates source to utun4 address
- Packet routed out utun4 (AWS VPN tunnel)
- Response comes back through utun4
- pf translates destination back to VM address
- Response delivered to VM
-
VM → Internet (all other traffic):
- Packet leaves VM with destination (e.g., 8.8.8.8)
- Reaches bridge100
- pf NAT rule matches → translates source to en0 address
- Packet routed out en0 (regular internet)
- Response comes back through en0
- pf translates destination back to VM address
- Response delivered to VM
/etc/pf.conf- Main packet filter configuration (adds multipass_vpn anchor)/etc/pf.anchors/multipass_vpn- VPN routing rules (regenerated each run)/etc/pf.conf.backup- Backup of original pf.conf (created on first run)
To see the current NAT rules:
sudo pfctl -a multipass_vpn -snTo see the current filter rules:
sudo pfctl -a multipass_vpn -srTo see statistics (packets/bytes processed):
sudo pfctl -a multipass_vpn -vsr # Filter rules with stats
sudo pfctl -a multipass_vpn -vsn # NAT rules with statsIf you need to remove the configuration:
# Disable pf
sudo pfctl -d
# Remove the anchor file
sudo rm /etc/pf.anchors/multipass_vpn
# Restore original pf.conf
sudo cp /etc/pf.conf.backup /etc/pf.conf
# Reload pf
sudo pfctl -f /etc/pf.conf
sudo pfctl -eMultipass VMs run in a bridged network, giving them their own IP addresses on the Mac's network. However:
- macOS doesn't automatically forward packets between the bridge and VPN tunnel
- NAT is needed so VPN servers accept packets from VM IPs
- Routing rules ensure traffic goes to the correct interface
- VPN tunnel interface names (utun0, utun1, etc.) change
- VPN routes change based on VPN configuration
- Bridge interface may change
- pf rules reference specific interfaces, so must be regenerated
- The script requires sudo to modify system network configuration
- pf rules are stateful (track connections) for security
- Only traffic from the Multipass bridge is affected
- Your Mac's own traffic routing is unchanged
- No permanent system modifications (rules reset on reboot)
The script automatically works with all VMs on the same Multipass bridge. All VMs will have VPN access once configured.
The script auto-detects VPN routes. If you need to add custom routes, modify the generated /etc/pf.anchors/multipass_vpn file and add additional vpn_netX entries.
This script is designed for AWS VPN Client but may work with other VPNs that:
- Create utun interfaces
- Add routes for 10.x or 172.16-31.x networks
- Use split tunneling
If you encounter issues:
- Verify AWS VPN Client is connected
- Verify Multipass VM is running
- Check the script output for specific error messages
- View active pf rules to verify configuration
- Test connectivity from the Mac itself to verify VPN works
MIT or something idk.