Configuring OpenVPN Client to Use Custom DNS on MacOS: A Script-Based Solution Without Server Access


14 views

When working with OpenVPN clients on MacOS (particularly through Tunnelblick), many developers encounter situations where:

  • The VPN server's provided DNS doesn't function properly
  • You need to use a local DNS that's only accessible when the VPN is active
  • Server configuration changes aren't an option

OpenVPN provides powerful script hooks that execute at different connection stages. The key ones we'll leverage are:

--up: Runs after tunnel establishment
--down: Runs before tunnel teardown
--route-up: Runs after routes are added

Here's how to automate DNS configuration using OpenVPN client scripts:

1. Create the Configuration Directory

First, ensure you have a directory for your custom scripts in the OpenVPN config folder:

mkdir -p ~/Library/Application\ Support/Tunnelblick/Configurations
cd ~/Library/Application\ Support/Tunnelblick/Configurations

2. The Up Script (vpn-up.sh)

#!/bin/bash

# Store original DNS settings
original_dns=$(networksetup -getdnsservers Wi-Fi)
echo "$original_dns" > /tmp/original_dns.txt

# Set VPN-specific DNS (replace with your actual DNS IP)
networksetup -setdnsservers Wi-Fi 10.8.0.1 10.8.0.2

# Flush DNS cache
dscacheutil -flushcache
killall -HUP mDNSResponder

3. The Down Script (vpn-down.sh)

#!/bin/bash

# Restore original DNS settings
original_dns=$(cat /tmp/original_dns.txt)
networksetup -setdnsservers Wi-Fi $original_dns

# Clean up
rm /tmp/original_dns.txt

# Flush DNS cache
dscacheutil -flushcache
killall -HUP mDNSResponder

4. Modify Your OpenVPN Configuration

Add these lines to your .ovpn file:

script-security 2
up "/path/to/vpn-up.sh"
down "/path/to/vpn-down.sh"

For Tunnelblick users, you can configure this through the GUI:

  1. Right-click on your VPN configuration
  2. Select "Edit Configuration..."
  3. Go to the "Settings" tab
  4. Check "Set DNS/WINS" and enter your preferred DNS servers
  • Ensure scripts are executable: chmod +x *.sh
  • Debug by adding set -x at the script start
  • Check logs in Tunnelblick's "VPN Details" window
  • For corporate networks, additional routes might be needed

When implementing this solution:

  • Store scripts securely (avoid world-writable locations)
  • Validate DNS server IPs before setting them
  • Consider using full paths in scripts to prevent PATH hijacking

When your OpenVPN server either doesn't push DNS settings or pushes incorrect ones, you need client-side control. This is especially critical when:

  • Local network resources require special DNS resolution
  • Server-side DNS fails to propagate properly
  • You need temporary DNS changes during VPN session only

Tunnelblick supports three key script hooks we'll leverage:

--up script: Runs after connection
--down script: Runs before disconnection
--route-up script: Runs after routes are established (best for DNS)

Edit your .ovpn file and add these directives:

script-security 2
route-up /path/to/set_dns.sh
down /path/to/restore_dns.sh

Create set_dns.sh:

#!/bin/bash
networksetup -setdnsservers "Wi-Fi" 192.168.1.100 192.168.1.101
echo "nameserver 192.168.1.100" > /etc/resolver/mydomain.local

Create restore_dns.sh:

#!/bin/bash
networksetup -setdnsservers "Wi-Fi" Empty
rm -f /etc/resolver/mydomain.local
chmod 755 /path/to/set_dns.sh
chmod 755 /path/to/restore_dns.sh

Verify with:

scutil --dns | grep "nameserver"

For dynamic environments, enhance set_dns.sh:

#!/bin/bash
CURRENT_GW=$(route -n get default | grep gateway | awk '{print $2}')

if [[ $CURRENT_GW == "10.8.0.1" ]]; then
  networksetup -setdnsservers "Wi-Fi" 10.8.0.53
fi
  • Use --verb 4 in OpenVPN config for detailed logs
  • Check Tunnelblick's "Details..." window for script errors
  • Test scripts manually before VPN connection
  • Remember MacOS may cache DNS (flush with dscacheutil -flushcache)