Macos – OS X >10.6.5 DNS Lookup Order with VPN

dnsmacososx lionosx-snow-leopardvpn

After updating to OS X 10.6.5 (from .4), applications don't seem to be looking up host names in the correct order (according to the service order in Network Preferences) when my VPN is connected.

My current setup is a Cisco IPSec VPN service in front of an AirPort service. The DNS servers are automatically setup for the VPN connection (which is OK), and the AirPort service DNS is pointing to my router (192.168.1.1, which is pointed to OpenDNS servers).

When my VPN is connected, I would like for DNS lookups to go through the VPN DNS servers first, but all my applications (Firefox, Thunderbird, ssh) appear to be using my AirPort DNS server first (OpenDNS).

This was working just fine before the update.

Thanks for any help.

** edit **

I came across this post, and ran the commands in the accepted answer. It didn't seem to help though.

After searching a little more, I came across this command: scutil –dns

The output from the command is below. Everything looks correct, except I think resolver #2 should come first, and there's a search domain in resolver #1 (it's obviously not foobar.com, but the real VPN domain). I think this is were the bug (or whatever it is) lies. I didn't manually specify it, and it's not on the DNS tab for my AirPort connection. When the VPN is disconnected, that search domain isn't there, and resolver #2 is gone, as it should be.

resolver #1
  search domain[0] : foobar.com
  nameserver[0] : 192.168.1.1
  order   : 200000

resolver #2
  domain : foobar.com
  nameserver[0] : 172.30.50.100
  nameserver[1] : 172.30.50.80
  order   : 100200

resolver #3
  domain : local
  options : mdns
  timeout : 2
  order   : 300000

resolver #4
  domain : 254.169.in-addr.arpa
  options : mdns
  timeout : 2
  order   : 300200

resolver #5
  domain : 8.e.f.ip6.arpa
  options : mdns
  timeout : 2
  order   : 300400

resolver #6
  domain : 9.e.f.ip6.arpa
  options : mdns
  timeout : 2
  order   : 300600

resolver #7
  domain : a.e.f.ip6.arpa
  options : mdns
  timeout : 2
  order   : 300800

resolver #8
  domain : b.e.f.ip6.arpa
  options : mdns
  timeout : 2
  order   : 301000

** edit **

Well, until someone is able to answer my question, I've written a script to help with the workaround mentioned below. It should be run after you've connected your VPN, and run again after you've disconnected (I haven't found a way to run it automatically). A few notes:

  1. My account is run as an Admin with Network Preferences unlocked, so I'm not sure how this script would fair on anything but.

  2. You need to set vpn_srvc_name in the script to your, you guessed it, vpn service name.

  3. I'm sure there's probably an easier way of doing this, so feel free to post your remarks.

The script:

#!/bin/bash

function get_pri_srvc_id ()
{
  cat <<EOF | scutil | \
    grep 'PrimaryService' | \
    awk -F': ' '{print $2}'
show State:/Network/Global/IPv4
EOF
}

function get_srvc_name ()
{
  cat <<EOF | scutil | \
    grep 'UserDefinedName' | \
    awk -F': ' '{print $2}'
show Setup:/Network/Service/$1
EOF
}

function get_srvc_ids ()
{
  cat <<EOF | scutil | \
    sed -nEe '
/ServiceOrder/ {
  :ids
  n
  /[0-9]+ :/ {
    s/ *[0-9]+ : ([0-9A-Z-]+) */\1/p
    b ids
  }
}'
show Setup:/Network/Global/IPv4
EOF
}

function get_srvc_id_by_name ()
{
  local srvc_ids=$(get_srvc_ids)

  for srvc_id in $srvc_ids
  do
    local srvc_name=$(get_srvc_name "$srvc_id")
    if [[ "$srvc_name" == "$1" ]]
    then
      echo $srvc_id
      return
    fi
  done
}

function get_dns_ips ()
{
  local srvc_id=$(get_srvc_id_by_name "$1")

  cat <<EOF | scutil | \
    sed -nEe '
/ServerAddresses/ {
  :ips
  n
  /[0-9]+ :/ {
    s/ *[0-9]+ : ([0-9.]+) */\1/p
    b ips
  }
}'
show $2:/Network/Service/$srvc_id/DNS
EOF
}

function set_dns_ips ()
{
  networksetup -setdnsservers "$@"
}

vpn_srvc_name='NAME OF VPN SERVICE'
ip_file='/tmp/setup_dns_ips'

pri_srvc_id=$(get_pri_srvc_id)
pri_srvc_name=$(get_srvc_name "$pri_srvc_id")

if [[ ! -e "$ip_file" ]]
then
  setup_dns_ips=$(get_dns_ips "$pri_srvc_name" "Setup")
  state_dns_ips=$(get_dns_ips "$pri_srvc_name" "State")
  vpn_ips=$(get_dns_ips "$vpn_srvc_name" "State")

  set_dns_ips "$pri_srvc_name" $vpn_ips $setup_dns_ips $state_dns_ips

  if [[ -z "$setup_dns_ips" ]]
  then
    setup_dns_ips="Empty"
  fi

  echo $setup_dns_ips >$ip_file
else
  setup_dns_ips=$(cat $ip_file)

  set_dns_ips "$pri_srvc_name" $setup_dns_ips

  rm $ip_file
fi

** edit **

It looks like this is still an issue in Lion as well. I'm updating the title and adding a tag.

** edit **

Apparently Lion also brought some wireless changes, including renaming the AirPort service to Wi-Fi. This can cause issues with the workaround script I provided if one connects to their VPN over a wireless connection. Lion (for some reason) keeps the service named AirPort underneath the hood. To fix it, you need to rename your Wi-Fi service to something besides AirPort. If you would like to keep the Wi-Fi name, you must rename it to something different first, then rename it back to Wi-Fi.

Best Answer

In my case, FQDN requests weren't resolving to the correct internal address. Instead, they were pointing to the external address.

I connect to my Cisco ASA via IPsec. While the order is setup correctly in network connection, the DNS requests do not follow the order since updating to 10.6.5.

To work around it, I manually assigned the DNS server for my VPN into Airport connection (since I'm wireless). After I'm done with the VPN connect, I remove the manually added DNS address.

Related Question