OpenWrt as OpenVPN Client, ignores pushed DNS?

I've setup my OpenWrt 18.06.2 snapshot machine as a travel router. It's meant to establish a VPN tunnel to my home gateway, routing all traffic through the VPN. OpenWrt is the OpenVPN client. This works. There is just one tiny detail that appears to be not working:

My OpenVPN server pushes a DNS:

push "dhcp-option DNS 192.168.1.102"

I can't find where OpenWrt would consider this option. /tmp/resolv.conf contains

search lan
nameserver 127.0.0.1

and /tmp/resolv.conf.aut contains

# Interface trm_wwan
nameserver 172.20.10.1

Where/how can I tell the OpenVPN client on OpenWrt actually to use the DNS provided by the remote OpenVPN server if/when the VPN is established?

The log on OpenWrt for OpenVPN doesn't show any error or other trace of the pushed DNS option:

root@OpenWrt:~# logread -e openvpn
Wed May  1 11:51:04 2019 daemon.notice openvpn(custom_config)[1449]: OpenVPN 2.4.7 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD]
Wed May  1 11:51:04 2019 daemon.notice openvpn(custom_config)[1449]: library versions: OpenSSL 1.1.1b  26 Feb 2019, LZO 2.10
Wed May  1 12:16:33 2019 daemon.notice openvpn(custom_config)[1449]: TCP/UDP: Preserving recently used remote address: [AF_INET]x.x.x.x:1194
Wed May  1 12:16:33 2019 daemon.notice openvpn(custom_config)[1449]: UDP link local (bound): [AF_INET][undef]:1194
Wed May  1 12:16:33 2019 daemon.notice openvpn(custom_config)[1449]: UDP link remote: [AF_INET]x.x.x.x:1194
Wed May  1 12:16:34 2019 daemon.notice openvpn(custom_config)[1449]: [pfSenseOpenVPNServer] Peer Connection Initiated with [AF_INET]x.x.x.x:1194
Wed May  1 12:16:35 2019 daemon.notice openvpn(custom_config)[1449]: TUN/TAP device tun0 opened
Wed May  1 12:16:35 2019 daemon.notice openvpn(custom_config)[1449]: /sbin/ifconfig tun0 10.0.10.2 netmask 255.255.255.0 mtu 1500 broadcast 10.0.10.255
Wed May  1 12:16:35 2019 daemon.warn openvpn(custom_config)[1449]: ERROR: Linux route add command failed: external program exited with error status: 1
Wed May  1 12:16:35 2019 daemon.warn openvpn(custom_config)[1449]: WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Wed May  1 12:16:35 2019 daemon.notice openvpn(custom_config)[1449]: Initialization Sequence Completed 

It doesn't change DNS automatically.
You can do it either manually or with scripting.

Thanks, good to know that it‘s not meant to work this way. So I‘d need to - and could use - the up/down scripts in the OpenVPN config.

Question is, what exactly I‘d need to do. The example you linked appears to be more complex than what I think I’d need here. I just want to change the DNS when the OpenVPN is up - and change it back to what it was before, when it‘s down again. So couldn‘t I just in the up script (1) backup /tmp/resolv.conf.auto; (2) replace the content of /tmp/resolv.conf.auto with the VPN DNS; and (3) restart dnsmasq. And then in the down script restore the backup and restart.

Or am I missing something?

https://openwrt.org/docs/guide-user/services/vpn/openvpn/extras#dns_and_domain

I was afraid that pointing dnsmasq to a different resolv file might survive a reboot. I.e. if the VPN is up and the nameserver is set to an internal DNS, and if then power is pulled, the config still points to the VPN DNS. However, when power is restored, the VPN will not be established, because the VPN server's name cannot be resolved, as the DNS is not working (already pointing to the internal IP).

So I am now working with the following scripts - in case somebody should stumble upon this and should be curious:

up.sh:

#!/bin/sh

# Initiate
LOG="/tmp/openvpn.log"
VPNRESOLV="/tmp/resolv.conf.vpn"
CURRESOLV="/tmp/resolv.conf.auto"
BKPRESOLV="/tmp/resolv.conf.bkp"
NOW=$(date +"%d.%m.%Y %H:%M:%S")
echo "" >>"$LOG"
echo "up.sh started on $NOW" >>"$LOG"

# Parse Environment Variables
echo $foreign_option_1 | grep -E "DOMAIN|DNS" | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >"$VPNRESOLV"
echo $foreign_option_2 | grep -E "DOMAIN|DNS" | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >>"$VPNRESOLV"
echo $foreign_option_3 | grep -E "DOMAIN|DNS" | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >>"$VPNRESOLV"
echo $foreign_option_4 | grep -E "DOMAIN|DNS" | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >>"$VPNRESOLV"
echo $foreign_option_5 | grep -E "DOMAIN|DNS" | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >>"$VPNRESOLV"

# Log Environment Variables
echo "foreign_option_1 = $foreign_option_1" >>"$LOG"
echo "foreign_option_2 = $foreign_option_2" >>"$LOG"
echo "foreign_option_3 = $foreign_option_3" >>"$LOG"
echo "foreign_option_4 = $foreign_option_4" >>"$LOG"
echo "foreign_option_5 = $foreign_option_5" >>"$LOG"

# Find current and new DNS
CURRENT_DNS=$(cat "$CURRESOLV" | grep "nameserver" | cut -d" " -f2)
echo "Current DNS: $CURRENT_DNS" >>"$LOG"
NEW_DNS=$(cat "$VPNRESOLV" | grep "nameserver" | cut -d" " -f2)
echo "New DNS: $NEW_DNS" >>"$LOG"

# Process
if [ "$NEW_DNS" = "$CURRENT_DNS" ]; then
  echo "No change in DNS. Nothing done." >>"$LOG"
else
  if [ -z "$NEW_DNS" ]; then
    echo "No new DNS specified. No changing resolv.conf files." >>"$LOG"
  else
    if [ -e "$BKPRESOLV" ]; then
      echo "Warning, backed up resolv.conf existing; overwriting now." >>"$LOG"
      echo "Original content:" >>"$LOG"
      cat "$BKPRESOLV" >>"$LOG"
    fi
    mv "$CURRESOLV" "$BKPRESOLV"
    mv "$VPNRESOLV" "$CURRESOLV"
   /etc/init.d/dnsmasq restart
  fi
fi

exit 0

And down.sh:

#!/bin/sh

# Initiate
LOG="/tmp/openvpn.log"
VPNRESOLV="/tmp/resolv.conf.vpn"
CURRESOLV="/tmp/resolv.conf.auto"
BKPRESOLV="/tmp/resolv.conf.bkp"
NOW=$(date +"%d.%m.%Y %H:%M:%S")
echo "" >>"$LOG"
echo "up.sh started on $NOW" >>"$LOG"

# Find current and new DNS
CURRENT_DNS=$(cat "$CURRESOLV" | grep "nameserver" | cut -d" " -f2)
echo "Current DNS: $CURRENT_DNS" >>"$LOG"
OLD_DNS=$(cat "$BKPRESOLV" | grep "nameserver" | cut -d" " -f2)
echo "Old DNS: $OLD_DNS" >>"$LOG"

# Process
if [ "$OLD_DNS" = "$CURRENT_DNS" ]; then
  echo "No change in DNS. Nothing done." >>"$LOG"
else
  if [ -z "$OLD_DNS" ]; then
    echo "No DNS specified in backup. No changing resolv.conf files." >>"$LOG"
  else
    if [ ! -e "$BKPRESOLV" ]; then
      echo "Warning, no backed up resolv.conf existing; doing nothing." >>"$LOG"
    else
      mv "$BKPRESOLV" "$CURRESOLV"
      rm -f "$VPNRESOLV"
      /etc/init.d/dnsmasq restart
    fi
  fi
fi

exit 0

Thanks @vgaetera for pointing me into the right direction!

There is only one problem remaining: It appears that restarting dnsmasq doesn't flush the DNS cache (entirely). But I'll open a new topic on this, as it is something different.

Inside a script you should invoke the init-script directly:

/etc/init.d/dnsmasq restart

Or source the profile beforehand:

source /etc/profile >/dev/null
service dnsmasq restart

Indeed, that works much better. :upside_down_face:

Thanks!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.