EINVAL: Valid solutions for invalid problems

VPNs are hard

, updated on

Almost every developer ends up using a VPN for work sooner or later. Apart from figuring out how to authenticate, it’s seemingly a simple matter. VPNs—usually associated with privacy—can unfortunately be a source of serious privacy leaks just as easily. Let’s talk about what we may want to check after connecting to a corporate VPN.

This post assumes we want to use the same machine both for personal and company matters, which is more and more common in this day and age. On a machine provided by the company used only for work this is far less of a concern.

Another thing this post assumes: we’re on GNU/Linux, obviously.

Good ol' DNS

If the company manages its own internal hostnames such as gitlab.company.example.com, it needs to provide a DNS server to use with the VPN. In the simplest case it will get added on top of /etc/resolv.conf to use before the DNS server we’ve chosen.

Before:

nameserver 192.168.0.1

After:

nameserver 10.0.1.42
nameserver 192.168.0.1

The problem is simple: /etc/resolv.conf has no way to tell which hostnames to resolve with which of these servers, they are simply tried from top to bottom. The effect? Every single of our DNS queries still goes through the company DNS servers, even though the actual traffic does not. In other words: every single domain we access is being silently reported!

As far as I know, the domain / search directives don’t help with this either, contrary to what our intuition might suggest.

To fix this we can install a local DNS server to forward our DNS queries to the correct servers. There are two common choices: dnsmasq and Unbound.

Not to delve too deep, this is the relevant part of the dnsmasq configuration:

server=192.168.0.1
server=/company.example.com/10.0.1.42

On the other hand, Unbound provides a CLI utility to modify the DNS forwards on the fly (the same can be done for dnsmasq with openresolv and/or some effort). It’s pretty easy to hook it up to a VPN connection script, but this is how one would use it by hand:

[email protected] ~> unbound-control forward 192.168.0.1
ok
[email protected] ~> unbound-control forward_add company.example.com. 10.0.1.42
ok
[email protected] ~> [connect to the VPN]
^C
[email protected] ~> unbound-control forward_remove company.example.com.
ok

Don’t forget to put nameserver 127.0.0.1 in your /etc/resolv.conf to utilize the local DNS server.

Summary

The default DNS setup can be surprisingly dangerous when used with a VPN. Stay safe!

Note: This post was heavily edited after the initial publication to better focus on the actual matter I wanted to write about. The original version is still available on Gemini.