NetworkManager can either:
The different configurations coming from each interface are simply aggregated (see update_dns()).
If you do not use NetworkManager for the VPN, you might use openresolv exclusive mode (-x) in order to override the nameservers from NetworkManager with the ones from the VPN instead of adding them. This can be done with this (ugly) script (OpenVPN hook):
#!/bin/sh # Dump all foreign options (coming from environment variables foreign_option_N) to stdout foreign_options() { local i i=1 while true; do local varname=foreign_option_$i local value="$(eval echo \$$varname)" if [ -z "$value" ]; then return fi echo $value i=$((i+1)) done } #Create a resolv.conf file from OpenVPN environment variables create_resolvconf() { foreign_options | grep "^dhcp-option DNS " | sed "s/^dhcp-option DNS /nameserver /" } route_up() { create_resolvconf | resolvconf -x -a $dev } down() { resolvconf -d $dev } case "$script_type" in route-up) route_up "$@" ;; down) down "$@" ;; esac
You should be able to adapt this to be used as a NetworkManager dispatcher script (see man 8 NetworkManager) using:
IP4_NAMESERVERSVPN_IP4_NAMESERVERS IP6_NAMESERVERSVPN_IP6_NAMESERVERS
I didn't test it but something like this should do the trick:
#!/bin/sh create_resolvconf() { for ip in $IP4_NAMESERVERS$VPN_IP4_NAMESERVERS $IP6_NAMESERVERS;$VPN_IP6_NAMESERVERS; do echo nameserver"nameserver $ip$ip" done } up() { create_resolvconf | resolvconf -x -a $DEVICE_IFACE$VPN_IP_IFAC } down() { resolvconf -d $DEVICE_IFACE$VPN_IP_IFAC } case "$1" in tun* | tap*0) if ;; [ -z "$VPN_IP_IFACE" ]; *)then return 0;0 esacfi case "$2" in up) up ;; down) down ;; esac