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:
- Right-click on your VPN configuration
- Select "Edit Configuration..."
- Go to the "Settings" tab
- 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
)