It really was a nasty job to figure out how to force Mac OS to route all traffic through a VPN line and deny any non-tunneled traffic even if the VPN line is down. I tried the route command but the routes seem to get broken once you've connected or disconnected the VPN line. And in my desired configuration, all connections should be blocked unless they go through the VPN.
But reading about the IPFW, the integrated IP firewall some unixes including Mac OS support, inspired me to try that configuration. Since my sister is will be subject of using this technique, I needed some sort of UI (some people don't like Terminal).
Necessary downloads
Prerequisites
Determine the IP address of your VPN provider
- Open Network Utility from Applications > Utilities
- Press Lookup tab
- Enter the VPN host (e.g. connect.swissvpn.net)
-
Press Lookup
- This will yield "80.254.79.48" in the example
Configuring the rules
Idea: We will set up the following rules:
- block all traffic by default (prio 1)
- allow all traffic to the obtained VPN host IP (prio 2)
- allow all traffic through the VPN tunnel interface (prio 3)
This can be done in the following way:
- Start WaterRoof
- Press the "Rules" button
-
Create a new rule using the "+" button in the lower right corner
- Rule action: deny
- ipv6: not checked
- Source address: any
- Destination: not me
- Network interface: all
- press "Add new rule"
-
Create a new rule using the "+" button in the lower right corner
- Rule action: allow
- ipv6: not checked
- Source address: any
- Destination: [IP of VPN host, e.g. 80.254.79.48]
- Network interface: all
- press "Add new rule"
-
Create a new rule using the "+" button in the lower right corner
- Rule action: allow
- ipv6: not checked
- Source address: any
- Destination: any
-
Network interface: ppp0
- this might be a different interface, you can find out which one to use by comparing the list of interfaces when connected to the VPN and when disconnected
- press "Add new rule"
-
Create a new rule using the "+" button in the lower right corner
- Rule action: deny
- ipv6: checked
- Source address: any
- Destination: any
- Network interface: all
- press "Add new rule"
-
Create a new rule using the "+" button in the lower right corner
- Rule action: allow
- ipv6: checked
- Source address: any
- Destination: any
- Network interface: ppp0 (as above)
- press "Add new rule"
For experts: The configuration will look like
add 01000 allow ip from any to any via ppp0 add 01100 allow ip from any to [IP of VPN host] add 01200 deny ip from any to not me add 65535 allow ip from any to any -- add 01000 allow ipv6 from any to any via ppp0 add 01100 deny ipv6 from any to any add 65535 allow ipv6 from any to any
Making rules load by default
- Choose "Save current rules..." from the "System" menu in WaterRoof
- Choose "Install Startup script..." from the "System" menu in WaterRoof
Manually disabling firewall
In case you need some specific precedure to get your internet connection working at all you might want to temporarily disable the routing rules.
- Choose "Flush current ipv4..." from the "Firewall" menu in WaterRoof
Manually re-enabling firewall
- Choose "Restore rules..." from the "System" menu in WaterRoof
Testing the setup
If everything has worked successfully the situation should be as follows:
- you cannot access the internet when the VPN tunnel is down
- you can access the internet once the VPN tunnel is established