How to Force Custom DNS Server in OpenVPN Client Without Modifying Server Configuration


2 views

When running OpenVPN on Linux systems with local DNS services (like Bind9), we often need temporary DNS override during VPN sessions while preserving the original 127.0.0.1 configuration when disconnected. This becomes tricky when you don't have control over the VPN server's push configuration.

We'll implement this using OpenVPN's up and down scripts to modify resolv.conf dynamically. The solution involves:

  • Creating custom scripts
  • Modifying OpenVPN client configuration
  • Handling permission and path considerations

First, create two scripts in /etc/openvpn/scripts/:

# /etc/openvpn/scripts/update-resolv-conf-up
#!/bin/sh
cp /etc/resolv.conf /etc/resolv.conf.bak
echo "nameserver x.y.z.t" > /etc/resolv.conf
# /etc/openvpn/scripts/update-resolv-conf-down
#!/bin/sh
if [ -f /etc/resolv.conf.bak ]; then
    mv /etc/resolv.conf.bak /etc/resolv.conf
fi

Make them executable:

chmod +x /etc/openvpn/scripts/update-resolv-conf-*

Add these lines to your .ovpn client configuration file:

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

For systems using systemd-resolved or NetworkManager, we need additional steps:

# For systemd-resolved systems
[Resolve]
DNS=x.y.z.t
Domains=~.

Alternatively, use resolvectl in your scripts:

# In up script
resolvectl dns tun0 x.y.z.t
resolvectl domain tun0 "~."

# In down script
resolvectl revert tun0

After implementation, verify with:

openvpn --config client.ovpn &
cat /etc/resolv.conf
dig example.com

When disconnected, confirm the DNS reverts to localhost:

cat /etc/resolv.conf
ping example.com

When running an OpenVPN client on an Ubuntu system with local BIND9 DNS (configured via 127.0.0.1 in resolv.conf), you might need to temporarily override DNS settings during VPN sessions while ensuring automatic rollback afterward. Here's how to implement this cleanly through client-side configuration.

Add these directives to your OpenVPN client configuration file (.ovpn):

# Force DNS during VPN session
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
dhcp-option DNS x.y.z.t

For Ubuntu systems, the openvpn package typically includes update-resolv-conf script. If missing, install it via:

sudo apt install openvpn-systemd-resolved

For more granular control, create a custom script (/etc/openvpn/custom-dns-handler.sh):

#!/bin/bash

case "$1" in
    up)
        echo "nameserver x.y.z.t" > /etc/resolv.conf.tmp
        echo "nameserver 127.0.0.1" >> /etc/resolv.conf.tmp
        mv /etc/resolv.conf.tmp /etc/resolv.conf
        ;;
    down)
        echo "nameserver 127.0.0.1" > /etc/resolv.conf
        ;;
esac

Then reference it in your OpenVPN config:

script-security 2
up /etc/openvpn/custom-dns-handler.sh up
down /etc/openvpn/custom-dns-handler.sh down

For systems using NetworkManager with OpenVPN:

[vpn]
dns-priority=50
dns=x.y.z.t

During VPN session, verify DNS with:

systemd-resolve --status
# Or traditional:
cat /etc/resolv.conf

For systems with immutable resolv.conf (common in Ubuntu 18.04+):

sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf