4 minute read

I had a few problems to make Network Manager behave as I needed in POP!_OS (should be the same for any Debian / Ubuntu distro).

Most of these problems only happened when using openvpn from Network Manager and would not happen when running the config from openvpn directly.

The DNS Problem

Injecting a DNS server from a VPN can be troublesome in Linux.

If you are not using Network Manager, you can fix this issue by adding the resolvconf script to your VPN config.

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

This will make it work if calling the config file directly

openvpn myconfig.ovpn

You can use this to test your config and also to check the DNS server IP if you don’t know it

The DNS IP will be shown in the VPN connection log as something like

2022-12-06 20:00:02 /etc/openvpn/update-resolv-conf tun0 1500 1624 10.8.0.240 255.255.255.0 init dhcp-option DNS 10.0.10.245

In this case it is 10.0.10.245
(and this is correct, since the server pushes a static route to the 10.0.10.x network)


Another option if you are not using Network Manager is to put the config file into the /etc/openvpn/client folder and use the systemd openvpn service.


Troubleshooting

You may need to symlink the /etc/resolv.conf for this to work. Can be done with

sudo dpkg-reconfigure resolvconf

or

sudo mv /etc/resolv.conf /etc/resolvconf-backup
sudo ln -s /etc/resolv.conf  /run/resolvconf/resolv.conf

This will change how systemd-resolve operates though (more info here).


NetworkManager DNS Issue

There is a long standing problem where the Linux (Ubuntu?) Network Manager app will not import and impose DNS configurations from an OpenVPN config file.

The fixes above will not make an imported OpenVPN config work in Network Manager. It will connect but not run the up/down scripts.

I use several VPNs and each of them inject their own DNS for internal domain names. They work only for the LAN part, not for the Internet, but uses the VPN DNS for everything (local and internet). I can’t let they all run at the same time (systemd service mode) because of conflicts.

In other words, being able to toggle ON / OFF on them as needed is the best option for me. My only other option would be to have bash scripts to connect and disconnect them.

As of December / 2022 POP!_OS 22.04 (and Ubuntu) will not import the DNS settings or apply the needed config.

Ubuntu Launchpad has a very long discussion on this problem and comment #92 provides the answer we need.

This fix will not import the DNS config from the OpenVPN Server, but will allow you to add your DNS server to the client config.

Tweak NetworkManager config

After importing your openvpn config file into network manager (and with it working, but only just not pulling the DNS config), disconnect from it if connected.

Edit the NetworkManager config file

sudo nano /etc/NetworkManager/system-connections/<vpn name>.nmconnection

where <vpn-name> is the name of the connection (tip: use tab to auto-complete)

Then edit the [ipv4] block to be something like this

[ipv4]
dns=<vpn dns server ip address>;
ignore-auto-dns=true
method=auto
dns-priority=-1

The negative dns-priority means only this dns server will be used (avoid dns leak)

Then reload the config file with

sudo nmcli c reload <vpn name>

Toggle it ON and it should be working with the VPN DNS

Forcing local internet

Most of my VPNs are not for internet and should not route the internet of clients through them.

The easiest way of doing this is by adding the following line to your server config

push "route 0.0.0.0 0.0.0.0 vpn_gateway 999"

This works great and lets you push that config to all clients. Except for clients using NetworkManager, because the vpn_gateway keywork is not supported by NM. This is an old issue and it seems like no one is working on it.


EDIT: IT DID NOT WORK AS PLANNED! I made many tests and some times it worked and some times it didn’t. The manual config below WORKS.

The easiest solution is to edit the server config and swap vpn_gateway to its actual IP value.

Suppose our gateway/server is 10.8.190.1

push "route 0.0.0.0 0.0.0.0 10.8.190.1 999"

This should make the route compatible with network manager and everything should work.


There are many times where we can’t (or don’t want to) edit the server config though. The workaround I found in this case was to disable automatic routes and then add the route above to the config manually.

NOTE: Most times your vpn_gateway is your VPN Server IP.

The main down side of this method is that you will also have to manually configure any other routes your VPN server was pushing into your connection. Normal routes (without keywords) are pushed fine, but when you turn off automatic routes you lose them too. With automatic routes ON the custom routes did not work for me.

Finding the pushed server routes

You can check your routes by manually connecting to your original .ovpn file and looking at the log for something like

2022-12-06 22:03:02 PUSH: Received control message: 'PUSH_REPLY,dhcp-option DNS 192.168.190.250,route 0.0.0.0 0.0.0.0 vpn_gateway 999,route 192.168.190.0 255.255.255.0,route-gateway 10.8.190.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.190.240 255.255.255.0,peer-id 0,cipher AES-128-GCM'

In this case I only had the route route 192.168.190.0 255.255.255.0
And the vpn_gateway (route-gateway) IP is 10.8.190.1 (for all routes)
The metric I used was 0 (see below)

Also, if you have a working connection with the proper routes established, you can list them with

route -n

This is also useful to check the Metrics of the routes


So this is How it looked like in the end

image

Comments