This is a helper script designed to integrate OpenVPN with the
service via DBus instead of trying to override
/etc/resolv.conf, or manipulate
systemd-networkd configuration files.
Since systemd-229, the
systemd-resolved service has an API available via
DBus which allows directly setting the DNS configuration for a link. This script
makes use of
busctl from systemd to send DBus messages to
to update the DNS for the link created by OpenVPN.
NOTE: This is a beta script. So long as you're using OpenVPN 2.1 or greater, iproute2, and have at least version 229 of systemd, then it should work. Nonetheless, if you do come across problems, fork and fix, or raise an issue. All are most welcome.
If you are using a distribution of Linux with access to the Arch User Repository, the simplest way to install is by using the openvpn-update-systemd-resolved AUR package as this will take care of any updates through your package manager.
Alternatively, the package can be manually installed by running the following:
git clone https://github.com/jonathanio/update-systemd-resolved.git cd update-systemd-resolved make
How to Enable
Make sure that you have
systemd-resolved enabled and running:
systemctl enable systemd-resolved.service systemctl start systemd-resolved.service
Then update your
/etc/nsswitch.conf file to look up DNS via the
service (you may need to install the NSS library which connectes libnss to
# Use /etc/resolv.conf first, then fall back to systemd-resolved hosts: files dns resolve myhostname # Use systemd-resolved first, then fall back to /etc/resolv.conf hosts: files resolve dns myhostname # Don't use /etc/resolv.conf at all hosts: files resolve myhostname
Note: If you intend on using this script, the latter two are preferred otherwise the configuration provided by this script will only work on domains that cannot be resolved by the currently configured DNS servers (i.e. they must fall back after trying the ones set by your LAN's DHCP server).
Note: The NSS interface for
systemd-resolved may be deprecated and has
already been flagged for deprecation in Ubuntu (see
for details). In this case, you should set your
nameserver in your
127.0.0.53, which will interact with the stub resolver
(introduced in systemd-231) giving you the improved configuration and routing
support, without having to worry about trying to manage your
Finally, update your OpenVPN configuration file and set the
options to point to the script, and
down-pre to ensure that the script is run
before the device is closed:
script-security 2 setenv PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin up /etc/openvpn/scripts/update-systemd-resolved down /etc/openvpn/scripts/update-systemd-resolved down-pre
down-pre options here will not work as expected where
openvpn daemon drops privileges after establishing the connection (i.e.
when using the
group options). This is because only the
will have the privileges required to talk to
openvpn-plugin-down-root.so plugin does provide support for
down script to be run as the
root user, but this has been known
to be unreliable.
Ultimately this shouldn't affect normal operation as
will remove all settings associated with the link (and therefore naturally
/etc/resolv.conf, if you have it symlinked) when the TUN or TAP device
is closed. The option for
down-pre just make this step explicit
before the device is torn down rather than implicit on the change in
Alternatively if you don't want to edit your client configuration, you can add the following options to your openvpn command:
openvpn \ --script-security 2 \ --setenv PATH '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' \ --up /etc/openvpn/scripts/update-systemd-resolved \ --down /etc/openvpn/scripts/update-systemd-resolved \ --down-pre
update-systemd-resolved works by processing the
dhcp-option commands set in
OpenVPN, either through the server, or the client, configuration:
||This sets the DNS servers for the link and can take any IPv4 or IPv6 address.|
||The primary domain for this host. If set multiple times, the last provided is used. Will be the primary search domain for bare hostnames. All requests for this domain as well will be routed to the
||Secondary domains which will be used to search for bare hostnames (after any
||All requests for these domains will be routed to the
||Control of DNSSEC should be enabled (
Note: There are no local or system options to be configured. All configuration for this script is handled though OpenVPN, including, for example, the name of the interface to be configured.
push "dhcp-option DNS 10.62.3.2" push "dhcp-option DNS 10.62.3.3" push "dhcp-option DNS 2001:db8::a3:c15c:b56e:619a" push "dhcp-option DNS 2001:db8::a3:ffec:f61c:2e06" push "dhcp-option DOMAIN example.office" push "dhcp-option DOMAIN-SEARCH example.com" push "dhcp-option DOMAIN-ROUTE example.net" push "dhcp-option DOMAIN-ROUTE example.org" push "dhcp-option DNSSEC yes"
This, added to the OpenVPN server's configuration file will set two IPv4 DNS
servers and two IPv6 and will set the primary domain for the link to be
example.office. Therefore if you try to look up the bare address
mail.example.office will be attempted first. The domain
example.com is also
added as an additional search domain, so if
mail.example.office fails, then
mail.example.com will be tried next.
example.org will also be routed though to the
four DNS servers listed too, but they will not be appended (i.e.
mail.example.net will not be attempted, nor
mail.example.com do not exist).
Finally, DNSSEC has been enabled for this link (and this link only).
How to help
If you can help with any of these areas, or have bug fixes, please fork and raise a Pull Request for me.
I have built a basic test framework around the script which can be used to
monitor and validate the calls made by the script based on the environment
variables available to it at run-time. Please add a test for any new features
you may wish to add, or update any which are wrong, and test your code by
./run-tests from the root of the repository. There are no dependencies
run-tests - it runs 100% bash and doesn't call out ot any other program or
TravisCI is enabled on this repository: Click the link at the top of this README to see the current state of the code and its tests.
Jonathan Wright firstname.lastname@example.org