blog/_posts/2018-08-10-openvpn-systemd-...

5.8 KiB

title date url layout category image description
OpenVPN, systemd and PUSHed DNS 2018-08-10 openvpn-systemd-and-pushed-dns post Tutorials /img/blog/openvpn-systemd-and-pushed-dns.jpg The final guide to make OpenVPN PUSHed DNS work with systemd...

Okay so basically we are in 2018, Linux is soon turning 30, Debian (as long as CentOS, I heard you starting complaining at the back of the room 😉) are recognized and almost fully-tested environments, but systemd is still a f*cking problem for our distributions and softwares.

Today problem : Using OpenVPN with DNS "PUSH-ed" by configuration, on recent systems.

Note to readers : This article could actually be set into many of the categories above.

IMPORTANT NOTE : If you are looking for a solution which doesn't change the way the name resolution works on your system, you can directly close this tab and keep wandering the WEB few more hours.

Where we start from

Let's say you are trying to connect to a service whose IP is supposed to be given by a DNS server, itself supposed to be PUSHed by your OpenVPN connection configuration while you opened the tunnel.

Where we arrive

If you have ended up there, not very far, isn't it ?
It's very likely that the PUSHed DNS has not been "pushed" at all, because of (guess what ?) : systemd.

The workaround

The workaround is not very a workaround, but mostly a long trip around the globe as it is actually a 400-line long script developed by a very experienced Linux user.

Why this long ? Because it uses a "new" API provided by systemd to interact with some of its services, via DBus 😶

So basically we set this script as a "hook" for OpenVPN, to tell it to set its PUSHed DNS(s) via the magnificent systemd-resolved binary (Yes... One of the 70 systemd provides, thank God).

You perfectly understood, this solution implies we move forward from resolvconf or any other resolution services, to systemd's resolved.

How to make the workaround... Working around

Did you really think this could be easy as installing the thing and re-connect to the VPN (that's what I've done) ? We are talking about systemd !
Don't forget... Ever.

So let's follow the guy's README instructions, and set up everything !

Installation

{% highlight bash %}

For Debian

apt install openvpn-systemd-resolved

If you were using resolvconf for instance, it won't be necessary anymore

#apt purge resolvconf

Generally

systemctl enable --now systemd-resolved.service {% endhighlight %}

Configuration

Once it's done, let's begin the configuration tweaking.

First, open up /etc/nsswitch.conf, and replace the host line by :

{% highlight config %} hosts: files resolve dns myhostname {% endhighlight %}

Next, open up /etc/resolv.conf and replace the content by :

{% highlight config %} search home nameserver 127.0.0.53 {% endhighlight %}

⚠️ If your system is running NetworkManager, you WILL experience issues sooner or later. Don't forget to follow the procedure below. ⚠️

As you will be now using a host-based resolver, I'd advise you to tweak your DNS resolution configuration.
The point is, as it will be now centralized (due to resolved usage), all you have to do is tweaking /etc/systemd/resolved.conf (!) :

{% highlight config %} [Resolve]

Quad9's DNSs first

DNS=9.9.9.9 149.112.112.112 2620:fe::fe 2620:fe::9

OpenDNS's DNSs as backup

FallbackDNS=208.67.222.222 208.67.220.220 2620:0:ccc::2 2620:0:ccd::2 {% endhighlight %}

Note : It's a personal choice (#GTFO_Google), feel free to adapt it for your own system !

If everything looks good to you :

{% highlight bash %} systemctl reload systemd-resolved {% endhighlight %}

Connection (!)

You can now try to open again your OpenVPN connection, but you'll need some additional flags (you could send them in the connection configuration, but I'd rather use parameters) :

{% highlight bash %} openvpn --config openvpn-configuration.ovpn --script-security 2 --up /etc/openvpn/update-systemd-resolved --down /etc/openvpn/update-systemd-resolved --down-pre {% endhighlight %}

And what about NetworkManager ??

Oh yeah, thanks, I almost forgot...

So as always, it's a mess.

Explanations : Even if you have perfectly followed this walk-through, if you are using NetworkManager, it may break anyway next time you reboot or so.

So the workaround (again...), is to tell NetworkManager not to handle the DNS configuration, and thus, not overriding the /etc/resolv.conf settings, EVER.

⚠️ If you are counting on NetworkManager to handle connection-specific DNS configuration, I regret having to inform you it won't be possible anymore... ⚠️

This could be achieved by tweaking /etc/NetworkManager/NetworkManager.conf :

{% highlight config %} [main] dns=none {% endhighlight %}

⚠️ Now, if you simply reload the NetworkManager daemon, you'll end up pulling your hairs out from your head as the /etc/resolv.conf would be overridden, again and again...

SO, the ultimate workaround is (the following of the sentence has not been 100%-proved) to restart the daemon, and not reloading it :

{% highlight bash %} systemctl restart NetworkManager {% endhighlight %}

⚠️ All your connections will go down for a bit, wait for the end of your background downloads before running it 😉

Conclusion

As always, I hope this helped you.

It is very complicated to keep using "old" (even basic) features with new distributions running systemd. Although everything has been re-thought, everything is not necessarily working as expected.