This is part three of a three part series covering Dnsmasq’s uses regarding:

  1. Local Development DNS
  2. Local Area Network (LAN) DNS
  3. Virtual Private Network (VPN) routing

IT savvy business often use a Virtual Private Network (VPN) connection to allow employees to connect to the (normally internal) work network while they’re traveling or working from home.  Many VPNs (once connected) act at the default gateway for your computer.  This is effectively like unplugging your computer from your local network  and plugging it in at your workplace.  This is probably for security reasons, and it’s certainly a simple configuration for most, as your computer is truly now on a remote network as if you were at your desk at work.  But for some, this is becomes a restriction, and we’ll examine some cases and a workaround.

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!

2 thoughts on “(Re)routing VPN traffic with Dnsmasq

  1. Pingback: Pimpin’ your dev env with Dnsmasq « Business Unusual

  2. Pingback: Pimp your LAN with OpenWrt & Dnsmasq « Business Unusual

Leave a Reply