MacOS Tahoe does not allow the end user to specify local networks which by-pass the VPN. Routes on MacOS can be manually modified to send default traffic through the local LAN and only send specific routes across the VPN by creating more sepcific routes (i.e. 0.0.0.0/1 and 128.0.0.0/1) to use the local gateway and by creating specific routes for the VPN connection.
In my specific environment, I have the following networks:
- 192.168.0.0/24 - MacBook/Workstation LAN
- 192.168.0.1/32 - MacBook/Workstation LAN Gateway
- 10.0.0.0/8 - Remote VPN Networks
- en7 - Ethernet Interface on MacBook
The following exmaples use mypubip.com to determine the public IP address used to NAT LAN and VPN connections.
The following shows some of the routes on the MacBook prior to starting the IKEv2 VPN:
syzdek@wanderer$ netstat -rn |egrep '^(default|10|0|128|192)'
default 192.168.0.1 UGScg en7
192.168.0/24 link#23 UCS en7 !
192.168.0.1/32 link#23 UCS en7 !
192.168.0.1 xx:xx:xx:xx:xx:c1 UHLWIir en7 1190
192.168.0.22 xx:xx:xx:xx:xx:a7 UHLWI en7 607
192.168.0.133 xx:xx:xx:xx:xx:85 UHLWI en7 512
192.168.0.179 xx:xx:xx:xx:xx:3d UHLWI en7 400
192.168.0.189 xx:xx:xx:xx:xx:3d UHLWI en7 491
192.168.0.203/32 link#23 UCS en7 !
192.168.0.255 ff:ff:ff:ff:ff:ff UHLWbI en7 !
syzdek@wanderer$
The following shows the current public IP address the MacBook is NAT from when accessing the Internet without the VPN:
syzdek@wanderer$ curl -4 mypubip.com
IP Address: x.x.x.121
Hostname: <redacted>
User Agent: curl/8.21.0
syzdek@wanderer$
The following shows some of the routes on the MacBook after starting the IKEv2 VPN:
syzdek@wanderer$ netstat -rn |egrep '^(default|10|0|128|192)'
default link#24 UCSg ipsec0
default 192.168.0.1 UGScIg en7
10.0.0.40 link#24 UHWIig ipsec0
10.0.0.41 link#24 UHWIig ipsec0
10.0.10.197 10.0.10.197 UH ipsec0
10.0.10.255 link#24 UHWIig ipsec0
192.168.0/24 link#23 UCS en7 !
192.168.0.1/32 link#23 UCS en7 !
192.168.0.1 xx:xx:xx:xx:xx:c1 UHLWIir en7 1190
192.168.0.22 xx:xx:xx:xx:xx:a7 UHLWI en7 607
192.168.0.133 xx:xx:xx:xx:xx:85 UHLWI en7 512
192.168.0.179 xx:xx:xx:xx:xx:3d UHLWI en7 400
192.168.0.189 xx:xx:xx:xx:xx:3d UHLWI en7 491
192.168.0.203/32 link#23 UCS en7 !
192.168.0.255 ff:ff:ff:ff:ff:ff UHLWbI en7 !
syzdek@wanderer$
The following shows the public IP address the MacBook is NAT from when accessing the Internet with the VPN:
syzdek@wanderer$ curl -4 mypubip.com
IP Address: x.x.x.202
Hostname: <redacted>
User Agent: curl/8.21.0
syzdek@wanderer$
In the above example, the following ports and links are used:
- en7 / link#23 - ethernet port
- ipsec0 / link#24 - IKEv2 Tunnel
The following commands will effectively override the default route for the VPN tunnel and send only the remote networks through the VPN:
sudo route -nv add -net 0.0.0.0/1 -gateway 192.168.0.1 -ifp en7
sudo route -nv add -net 128.0.0.0/1 -gateway 192.168.0.1 -ifp en7
sudo route -nv add -net 10.0.0.0/8 -link 'link#24' -ifp ipsec0
The following example shows the output from the above commands:
syzdek@wanderer$ sudo route -nv add -net 0.0.0.0/1 -gateway 192.168.0.1 -ifp en7
u: inet 0.0.0.0; u: inet 192.168.0.1; u: inet 128.0.0.0; u: link 65.6e.37.0.0.e.0.0; RTM_ADD: Add Route: len 148, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP>
default 192.168.0.1 128.0.0.0 index: 0 65.6e.37.0.0.e.0.0
add net 0.0.0.0
syzdek@wanderer$
syzdek@wanderer$ sudo route -nv add -net 128.0.0.0/1 -gateway 192.168.0.1 -ifp en7
u: inet 128.0.0.0; u: inet 192.168.0.1; u: inet 128.0.0.0; u: link 65.6e.37.0.0.e.0.0; RTM_ADD: Add Route: len 148, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP>
128.0.0.0 192.168.0.1 128.0.0.0 index: 0 65.6e.37.0.0.e.0.0
add net 128.0.0.0
syzdek@wanderer$
syzdek@wanderer$ sudo route -nv add -net 10.0.0.0/8 -link 'link#24' -ifp ipsec0
u: inet 10.0.0.0; u: link link:24; u: inet 255.0.0.0; u: link 69.70.73.65.63.30.0.0.e.0.0.0; RTM_ADD: Add Route: len 156, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP>
10.0.0.0 index: 0 link:24 255.0.0.0 index: 0 69.70.73.65.63.30.0.0.e.0.0.0
add net 10.0.0.0: gateway link#24
syzdek@wanderer$
The following shows some of the routes on the MacBook after manually modifing routes:
syzdek@wanderer$ netstat -rn |egrep '^(default|10|0|128|192)'
0/1 192.168.0.1 UGScg en7
default link#24 UCSg ipsec0
default 192.168.0.1 UGScIg en7
10 link:24 UGSc ipsec0
10.0.0.40 link#24 UHWIig ipsec0
10.0.0.41 link#24 UHWIig ipsec0
10.0.10.197 10.0.10.197 UH ipsec0
10.0.10.255 link#24 UHWIig ipsec0
192.168.0/24 link#23 UCS en7 !
192.168.0.1/32 link#23 UCS en7 !
192.168.0.1 xx:xx:xx:xx:xx:c1 UHLWIir en7 1190
192.168.0.22 xx:xx:xx:xx:xx:a7 UHLWI en7 607
192.168.0.133 xx:xx:xx:xx:xx:85 UHLWI en7 512
192.168.0.179 xx:xx:xx:xx:xx:3d UHLWI en7 400
192.168.0.189 xx:xx:xx:xx:xx:3d UHLWI en7 491
192.168.0.203/32 link#23 UCS en7 !
192.168.0.255 ff:ff:ff:ff:ff:ff UHLWbI en7 !
128.0/1 192.168.0.1 UGSc en7
syzdek@wanderer$
The following shows the public IP address the MacBook is NAT from when accessing the Internet with the VPN and modified routes:
syzdek@wanderer$ curl -4 mypubip.com
IP Address: x.x.x.121
Hostname: <redacted>
User Agent: curl/8.21.0
syzdek@wanderer$
To restore the default routing after disconnecting from the VPN, run the following commands:
sudo route -nv delete -net 0.0.0.0/1 -gateway 192.168.0.1 -ifp en7
sudo route -nv delete -net 128.0.0.0/1 -gateway 192.168.0.1 -ifp en7
The following example shows the output from the above commands:
syzdek@wanderer$ sudo route -nv delete -net 0.0.0.0/1 -gateway 192.168.0.1 -ifp en7
u: inet 0.0.0.0; u: inet 192.168.0.1; u: inet 128.0.0.0; u: link 65.6e.37.0.0.e.0.0; RTM_DELETE: Delete Route: len 148, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP>
default 10.19.84.1 128.0.0.0 index: 0 65.6e.37.0.0.e.0.0
delete net 0.0.0.0
syzdek@wanderer$
syzdek@wanderer$ sudo route -nv delete -net 128.0.0.0/1 -gateway 192.168.0.1 -ifp en7
u: inet 128.0.0.0; u: inet 192.168.0.1; u: inet 128.0.0.0; u: link 65.6e.37.0.0.e.0.0; RTM_DELETE: Delete Route: len 148, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP>
128.0.0.0 192.168.0.1 128.0.0.0 index: 0 65.6e.37.0.0.e.0.0
delete net 128.0.0.0
syzdek@wanderer$
To restore default routes while connected to the VPN, run the following commands:
sudo route -nv delete -net 0.0.0.0/1 -gateway 192.168.0.1 -ifp en7
sudo route -nv delete -net 128.0.0.0/1 -gateway 192.168.0.1 -ifp en7
sudo route -nv delete -net 10.0.0.0/8 -link 'link#24' -ifp ipsec0