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

137 lines
5.8 KiB
Markdown

---
title: "OpenVPN, systemd and PUSHed DNS"
date: 2018-08-10
url: openvpn-systemd-and-pushed-dns
layout: post
category: Tutorials
image: /img/blog/openvpn-systemd-and-pushed-dns.jpg
description: "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 :wink:) 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**](https://github.com/systemd/systemd/issues/6076).
### 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](https://github.com/jonathanio/update-systemd-resolved).
Why _this_ long ? Because it uses a "new" API provided by **systemd** to interact with some of its services, via DBus :no_mouth:
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](https://github.com/jonathanio/update-systemd-resolved/blob/master/README.md), 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 %}
:warning: If your system is running **NetworkManager**, you WILL experience issues sooner or later. Don't forget to follow [the procedure below](#and-what-about-networkmanager-). :warning:
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.
:warning: If you are counting on **NetworkManager** to handle connection-specific DNS configuration, I regret having to inform you it won't be possible anymore... :warning:
This could be achieved by tweaking `/etc/NetworkManager/NetworkManager.conf` :
{% highlight config %}
[main]
dns=none
{% endhighlight %}
:warning: 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 %}
:warning: All your connections will go down for a bit, wait for the end of your background downloads before running it :wink:
### 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.