Let’s say I’m connected to the VPN. All of my internet traffic goes through the VPN which is a thousand miles away. If I’m streaming a local radio station, that’s a long way to go out-and-back for something that is truly local. In addition, all of my local network resources are less usable because the VPN has instructed my computer to use the VPN’s DNS servers, so I can now only access them by IP.
It is possible to be connected to the VPN and still have access to local resources, and route (non-VPN) traffic though your normal gateway. Your VPN administrator might say this is poses a security risk, but s/he’ll be none the wiser if you don’t let on.
This configuration is for Dnsmasq and NetworkManager, which is used by Ubuntu & Fedora. But there’s no reason the concepts here can’t be applied to other Linux distributions and/or OSX.
VPN Gateway
Connect to your VPN per normal using NetworkManager. Once you’re connected you can probably deduce the default gateway by looking at output from running a traceroute
to a known computer on the VPN (such as the nameserver – see below).
$ traceroute 10.20.0.26
traceroute to 10.20.0.26 (10.20.0.26), 30 hops max, 60 byte packets
1 * * *
2 10.20.44.253 (10.20.44.253) 101.294 ms 101.715 ms 102.610 ms
3 10.20.0.26 (10.20.0.26) 100.205 ms 101.022 ms 101.486 ms
The first IP is likely the VPN’s default gateway, 10.20.44.253 in this case.
VPN Name Servers
You’ll also want to grab the name servers for your VPN. You can probably just inspect your /etc/resolv.conf
file for this information:
$ cat /etc/resolv.conf
...
nameserver 10.20.0.26
Add new VPN connection
With this information at hand, disconnect from the VPN and create a new VPN connection in NetworkManager that is essentially the same as the existing one. Name the new connection something that indicates it’s custom (we’ll use this name later). In NetworkManager on the IPv4 Settings tab, set the Method to Automatic (VPN) addresses only:
Then click the Routes… button. In the Routes dialog you’ll want to put in the network information for your work, using the information you deduced using traceroute
. My VPN addresses are all 10.x.x.x, and the VPN gateway is 10.20.44.253. So I added a line to the route table like this:
You can find the network address and netmask from the Private Network table on Wikipedia. The metric number should be fine at 10. Check the boxes to ignore obtained routes and to only use this network for resources contained within.
That gets you essentially halfway there, you can connect to the VPN and only requests for resources with network addresses that are part of the VPN will be routed through the VPN connection, everything else will gateway through your normal ISP. You can (and probably should) test this configuration by connecting to the VPN and ping
-ing or traceroute
-ing to a computer on the VPN (such as the nameserver) just to make sure the custom routing established is indeed working. Once routing is working, we need to fix the DNS as it’s kind of useless without it.
Create a NetworkManager dispatcher.d script to start Dnsmasq
In /etc/NetworkManager/dispatcher.d
add a file called 05vpn
:
#!/bin/sh
if [ "$2" = "vpn-up" ]; then
CONN_NAME=`/usr/bin/nm-tool | grep VPN | sed 's/^.*\[\(.*\)\].*$/\1/'`
if [ "$CONN_NAME" = "VPN Custom" ]; then
/etc/init.d/dnsmasq start
fi
fi
if [ "$2" = "vpn-down" ]; then
/etc/init.d/dnsmasq stop
fi
Set the comparison to $CONN_NAME to the name of your new VPN connection. After saving the file, set it to be executable:
$ sudo chmod 755 /etc/NetworkManager/dispatcher.d/05vpn
The /etc/NetworkManager/dispatcher.d
files are executed whenever a network interface goes up or down. The 05vpn
file will start/stop Dnsmasq when the “custom” VPN connection is turned on/off.
Configure Dnsmasq for your VPN
Configuring Dnsmasq for your VPN really boils down to adding server entries for every domain that either resides on the VPN, or that you want to route through the VPN. Add a file in /etc/dnsmasq.d
for your VPN DNS settings, such as /etc/dnsmasq.d/02_vpn
If your work has it’s own Top Level Domain (TLD), add a server line with the VPN DNS server IP and the TLD:
server=/tld/10.20.0.26
Similarly, if there are certain domains (like your company’s domain name) that act differently when you’re on the VPN, you’ll want to have them route through the VPN:
server=/mywork.com/10.20.0.26
That’s all there is to it. I’ve noticed some (newer) versions of NetworkManager automagically employ Dnsmasq to let you use any LAN resources, but other traffic (such as streaming music) would still go through the VPN.
Happy Hacking!