OS X >10.6.5 DNS Lookup Order with VPN

11,382

Solution 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.

Solution 2

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

Share:
11,382

Related videos on Youtube

citrusmoose
Author by

citrusmoose

Updated on September 17, 2022

Comments

  • citrusmoose
    citrusmoose over 1 year

    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.

    • Everett
      Everett over 13 years
      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)?
    • citrusmoose
      citrusmoose over 13 years
      Yes, they are correct.
    • Chris R. Donnelly
      Chris R. Donnelly almost 12 years
      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
    • citrusmoose
      citrusmoose almost 12 years
      You're right, @chris. I've updated the script. Not sure what you mean by "why to do this".
    • Chris R. Donnelly
      Chris R. Donnelly almost 12 years
      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.
  • citrusmoose
    citrusmoose over 13 years
    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.