Fix OpenVPN DNS in Kubuntu 18.04

OpenVPN does not correctly set DNS servers in Kubuntu 18.04 (this may also apply to other Ubuntu flavors, although to date I have only installed Kubuntu 18.04 so cannot confirm this). I have not yet looked in to the reason why this is the case, but it looks like it’s something to do with resolved – something that was introduced with systemd.

The Problem

The problem becomes apparent when you connect to an OpenVPN server and then cannot access websites, but can ping IP addresses. For example:

$ sudo openvpn --config client.ovpn
...
Tue May 15 21:39:09 2018 Initialization Sequence Completed

And then from another terminal tab (or a new terminal instance):

$ ping www.yahoo.com
ping: www.yahoo.com: Temporary failure in name resolution
 
$ ping 87.248.98.8
PING 87.248.98.8 (87.248.98.8) 56(84) bytes of data.
64 bytes from 87.248.98.8: icmp_seq=1 ttl=54 time=29.4 ms
64 bytes from 87.248.98.8: icmp_seq=2 ttl=54 time=35.3 ms
64 bytes from 87.248.98.8: icmp_seq=3 ttl=54 time=33.7 ms
64 bytes from 87.248.98.8: icmp_seq=4 ttl=54 time=31.8 ms
^C
--- 87.248.98.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 29.487/32.605/35.360/2.195 ms

Solution 1 – Manually Set DNS Servers

The service that manages DNS in systemd is systemd-resolved. You can manually set your DNS servers by editing /etc/systemd/resolved.conf. For example, to set your DNS to the OpenDNS servers:

[Resolve]
DNS=208.67.222.222 208.67.220.220
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#Cache=yes
#DNSStubListener=yes

Save the file and exit your text editor, then restart the systemd-resolvd service:

$ sudo systemctl restart systemd-resolved.service

Your DNS should now be working. To analyze your DNS traffic (i.e. make sure DNS requests are going through your OpenVPN tunnel), first find the name and IP address of your tunnel:

$ ip -o addr | cut -d'\' -f 1
1: lo    inet 127.0.0.1/8 scope host lo
1: lo    inet6 ::1/128 scope host 
2: eno1    inet 10.20.0.2/24 brd 10.20.0.255 scope global dynamic noprefixroute eno1
2: eno1    inet6 fe80::83c4:13d2:1d0a:4769/64 scope link noprefixroute 
3: virbr0    inet 10.20.122.1/24 brd 10.20.122.255 scope global virbr0
11: tun0    inet 10.8.0.2/24 brd 10.8.0.255 scope global tun0
11: tun0    inet6 fe80::c21:4634:5033:18a/64 scope link stable-privacy

From the above, it can be seen that “tun0” is the name of the OpenVPN tunnel interface (which is pretty standard), and the (version 4) IP address is 10.8.0.2.

Open two terminal windows. In one terminal, use tcpdump to watch how you’re DNS requests are being resolved:

$ sudo tcpdump -n -i tun0 udp port 53

In the other terminal window, ping www.yahoo.com:

$ ping www.yahoo.com

Observe the tcpdump output – DNS requests are definitely being sent out via the OpenVPN tunnel:

$ sudo tcpdump -n -i tun0 udp port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
22:46:06.745398 IP 10.8.0.2.46492 > 208.67.222.222.53: 49908+ [1au] A? www.yahoo.com. (42)
22:46:06.745443 IP 10.8.0.2.44293 > 194.168.4.100.53: 6508+ A? www.yahoo.com. (31)
22:46:06.745534 IP 10.8.0.2.47191 > 208.67.222.222.53: 22444+ [1au] AAAA? www.yahoo.com. (42)
22:46:06.745572 IP 10.8.0.2.46421 > 194.168.4.100.53: 48421+ AAAA? www.yahoo.com. (31)
22:46:06.774704 IP 208.67.222.222.53 > 10.8.0.2.46492: 49908 3/0/1 CNAME atsv2-fp.wg1.b.yahoo.com., A 87.248.98.7, A 87.248.98.8 (103)
22:46:06.774961 IP 10.8.0.2.51415 > 194.168.4.100.53: 60754+ A? atsv2-fp.wg1.b.yahoo.com. (42)
22:46:06.778239 IP 208.67.222.222.53 > 10.8.0.2.47191: 22444 3/0/1 CNAME atsv2-fp.wg1.b.yahoo.com., AAAA 2a00:1288:110:1c::3, AAAA 2a00:1288:110:1c::4 (127)
22:46:06.778494 IP 10.8.0.2.44693 > 194.168.4.100.53: 61947+ AAAA? atsv2-fp.wg1.b.yahoo.com. (42)
22:46:06.820753 IP 10.8.0.2.52569 > 208.67.222.222.53: 5938+ [1au] PTR? 8.98.248.87.in-addr.arpa. (53)
22:46:06.820831 IP 10.8.0.2.60037 > 194.168.4.100.53: 39315+ PTR? 8.98.248.87.in-addr.arpa. (42)
22:46:06.842059 IP 208.67.222.222.53 > 10.8.0.2.52569: 5938 1/0/1 PTR media-router-fp2.prod1.media.vip.ir2.yahoo.com. (113)

Solution 2 – Add new OpenVPN client Up/Down Script

While looking in to this problem, I came across this github repo.

Most of the steps mentioned in the README are not required. The only thing that is required from that repository is the update-systemd-resolved file. I prefer to keep the original update-systemd-resolved file (in /etc/openvpn), so I download the new update-systemd-resolved to another directory:

sudo mkdir -p /etc/openvpn/scripts
sudo wget https://raw.githubusercontent.com/jonathanio/update-systemd-resolved/master/update-systemd-resolved -P /etc/openvpn/scripts/
sudo chmod +x /etc/openvpn/scripts/update-systemd-resolved

Now modify your OpenVPN client file (it might be called something like, for example, client.ovpn) by changing the up/down lines to point to the newly downloaded update-systemd-resolved:

 script-security 2
 up /etc/openvpn/scripts/update-systemd-resolved
 down /etc/openvpn/scripts/update-systemd-resolved
 down-pre

Your DNS should now be working when you connect to your OpenVPN server. You can follow the steps above to use tcpdump to make sure your DNS is working and not leaking.

3 thoughts on “Fix OpenVPN DNS in Kubuntu 18.04

Comments are closed.