OS X >10.6.5 DNS Lookup Order with VPN

13

8

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.

citrusmoose

Posted 2010-11-18T22:33:31.260

Reputation: 131

When you look in System Preferences and click on networks, under the VPN connection on the left side select advanced (bottom right hand corener). You should now see a DNS tab at the top. On the left are the IP's for the DNS, and the right shows your domain. Are these correct (pointing at the VPN DNS server)? – Everett – 2010-11-20T08:23:42.427

Yes, they are correct. – citrusmoose – 2010-11-22T12:30:05.323

The line in set_dns_ips should be networksetup -setdnsservers "$@". My Mac Pro has two Ethernet connections ("Ethernet 1" and "Ethernet 2" are the default names) and so they have to be quoted.

EDIT: why to do this – Chris R. Donnelly – 2012-06-03T16:41:39.340

You're right, @chris. I've updated the script. Not sure what you mean by "why to do this". – citrusmoose – 2012-06-05T13:55:53.017

Sorry, @citrusmoose. Was just trying to say why I edited the comment; I hit submit then realized I didn't say why to change that and didn't want to come off as just advocating the change without a good reason. – Chris R. Donnelly – 2012-06-05T20:05:57.330

Answers

1

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.

KevinTM

Posted 2010-11-18T22:33:31.260

Reputation: 11

Yes, this is my workaround too (but very annoying). I'm glad someone else is having this problem, as it seems I was the only one. I suppose others might not notice since most lookups for internal domains will fail and fall back to the correct DNS servers. In my case however, there are few internal domains that (for some reason) have entries in external DNS servers. – citrusmoose – 2010-11-24T12:49:06.987

There's got to be a better approach than this, @Citrusmoose, have you had any luck with something less manual and more robust? – MightyE – 2011-02-08T14:37:52.960

Nope, I haven't come across anything yet. – citrusmoose – 2011-02-14T14:59:31.667

1

To stop OS X 10.8 from creating a default route to your VPN connection, open Internet Connect (in Applications). Choose Options from the Connect menu, then uncheck the "Send all traffic over VPN connection" option. Click OK, and you're done.

To make a custom route to the subnet on the other side of the VPN connection, read the rest of the hint...

As root, create /etc/ppp/ip-up, and put in the following code:

#!/bin/sh
# When the ppp link comes up, this script is called with the following
# parameters
#       $1      the interface name used by pppd (e.g. ppp3)
#       $2      the tty device name
#       $3      the tty device speed
#       $4      the local IP address for the interface
#       $5      the remote IP address
#       $6      the parameter specified by the 'ipparam' option to pppd

DEBUGFILE=/tmp/ip-up-debug.txt
## echo "1:$1 2:$2 3:$3 4:$4 5:$5 6:$6" > $DEBUGFILE
NET=`echo $5 | cut -d. -f1,2,3`
## echo $NET >> $DEBUGFILE

case $NET in 192.168.3)
     ## echo "CASE1" >> $DEBUGFILE
     RESULT=`/sbin/route add -net 192.168.30.0 $5 255.255.255.0`
     ##echo $RESULT >> $DEBUGFILE
     ;;
     192.168.2)
     ## echo "CASE2" >> $DEBUGFILE
     RESULT=`/sbin/route add -net 192.168.20.0 netmask 255.255.255.0 gw $5`
     ## echo $RESULT >> $DEBUGFILE
     ;;
     192.168.1)
     ## echo "CASE3" >> $DEBUGFILE
     RESULT=`/sbin/route add -net 192.168.10.0 netmask 255.255.255.0 gw $5`
     ## echo $RESULT >> $DEBUGFILE
     ;;
     *)
     ## echo "No match" >> $DEBUGFILE
     ;;
esac

Notes:

  1. Once you create the file, do a chmod u+x /etc/ppp/ip-up.
  2. The $5 variable is your remote IP address (your IP address on the remote network).
  3. In the first case statement, change the 192.168.x entry to the first three octets of your remote network. In this instance, the remote IP is 192.168.3.1, and the remote network is 192.168.30.0/24 (the remote VPN box is doing the routing -- this is so SAMBA will work without needing to proxy ARP).
  4. Uncomment (remove the ##'s) from the debug lines to see what this script is doing. Output will be written to the /tmp/ip-up-debug.txt file. Remember to put the ##'s back in when you are done testing.
  5. This script has options for three different VPN connections. Just change the 192.168.x entries to the different network addresses of your different VPNs.

Found here

Antonio

Posted 2010-11-18T22:33:31.260

Reputation: 597