VPN to office without routing all internet traffic
Solution 1:
The general idea is to modify the routing table so only known office subnets (address blocks) get routed through your VPN interface (e.g. ppp0) and all other subnets get routed through your normal network interface (e.g. en0). When you connect to VPN Gnome network manager adds so-called default route to the VPN interface (ppp0). You need to remove this route but add new routing entries for known office subnets.
Firstly, you need to find what private subnets are used by your office network. The easiest way is just to ask your office network administrators. If this not an option, you can figure it yourself by resolving your office host names after you connected to VPN. For example:
$ nslookup service.company.office
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: service.company.office
Address: 192.168.1.22
In this case the subnet you need to route through your VPN is 192.168.1.0/24 which means all addresses from 192.168.1.0 to 192.168.1.255. Your office may have more than one subnet you need to route.
Secondly, you need to modify routing table by using ip
command. Print out the table by typing ip r
and look for an entry that points to VPN device:
$ ip r
default dev ppp0 proto static scope link metric 50
default via 192.168.20.1 dev eno1 proto dhcp metric 100
...
192.168.20.0/24 dev eno1 proto kernel scope link src 192.168.20.126 metric 100
192.168.100.1 dev ppp0 proto kernel scope link src 192.168.100.89 metric 50
So now you know that ppp0
is your VPN device. In my example there are two default routes but ppp0
has smaller metric so all traffic goes there. Now, add a separate route to your office network:
$ ip route add 192.168.1.0/24 dev ppp0 proto static scope link
Now you just need to remove the default route to ppp0
and you are good to go:
$ ip route delete default dev ppp0
You can automate this by the following script:
#!/bin/bash
# List your office networks
networks=(
192.168.1.0/24
192.168.2.0/24
)
# Execute it with sudo
if [ $(id -u) != "0" ]; then
echo "You must be root to execute this script. Use sudo?"
exit -1
fi
# Check if VPN is active. You can use ipsec status command
# if your VPN is not L2TP
tunnel=$(ip l2tp show tunnel 2>&1)
if [ -z "$tunnel" ]; then
echo "VPN is not active."
exit -2
fi
# Add office private network routes
for net in ${networks[*]}; do
ret=$(ip route add $net dev ppp0 proto static scope link 2>&1)
if [[ $ret =~ "File exists" ]]; then
echo "routes have been already added."
exit -3
fi
done
# Delete default routes so Internet is routed via local ISP
ip route delete default dev ppp0