Can't resolve host through VPN connection from Mac OS X [closed]

The Preamble

I set up a VPN connection from my Macbook, and it seems to connect successfully.

working VPN

However, I can't access my work computer because hostname doesn't get resolved:

$ ping myusername
ping: cannot resolve myusername: Unknown host

The New Workaround

After trying everything I could, I found that this command makes both VPN network and internet available to me:

sudo route add -net 192.168.7.218 192.168.7.117 255.255.0.0

Company's DNS servers are accessible by their IPs. How do I configure the network to use them for everything that starts from 192.168?

The Old Workaround

I found a temporary workaround that allows me to access the network via VPN by modifying two options:

I put a checkmark in Send all traffic over VPN connection:

VPN options

I manually enter Search Domain name in VPN interface's DNS settings:

entering domain name in VPN options

Performing these two steps is enough to make my working computer pingable:

$ nslookup myusername
Server:     192.168.10.16
Address:    192.168.10.16#53

Name:   myusername.universe.mycompany
Address: 192.168.11.56

$ ping myusername
PING myusername.universe.mycompany (192.168.11.56): 56 data bytes
64 bytes from 192.168.11.56: icmp_seq=0 ttl=126 time=126.164 ms

However, as I tunnelled all traffic to go through VPN, I can no longer access the Internet:

$ ping google.com
PING google.com (74.125.232.48): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1

The Question

How do I properly set up the network so it understands when to go through VPN, and when to use the normal connection? I need it to resolve Windows server names correctly.

If I need to post any console command output, I am willing to do that if you let me know which exactly.
Any help is highly appreciated, as this is a kind of show stopper for me now.

Thanks!


Solution 1:

You might want to look at the resolver manpage

To quote one solution:

The configuration for a particular client may be read from a file having the format described in this man page. These are at present located by the system in the /etc/resolv.conf file and in the files found in the /etc/resolver directory. However, client configurations are not limited to file storage. The implementation of the DNS multi-client search strategy may also locate client configuratins in other data sources, such as the System Configuration Database. Users of the DNS system should make no assumptions about the source of the configuration data.

AFAIK you need to put a file named example.com in /etc/resolver with the IPs of the nameservers for that domain if you want special nameservers for example.com -- Could be they use resolv.conf syntax, I can't remember. But you should be able to figure that out :)

EDIT: As far as automating the process goes, I'm pretty sure that's doable with AppleScript or Automator. But I never to my head around it so a second question on that topic might help.

Solution 2:

There seems to be an issue with OSX setting the netmask incorrectly. This was my experience using a PPTP VPN in both Snow Leopard and Mountain Lion, and is supported by this thread here.

I found a solution here, which involves setting a routing rule for ppp0 traffic.

Basically:

$ sudo <your_text_editor_of_choice> /etc/ppp/ip-up

    #!/bin/sh
    /sbin/route add -net 192.168 -interface ppp0

$ sudo chmod 755 /etc/ppp/ip-up

This will set the routing rule every time you connect to the VPN.

Solution 3:

Mac OSX DNS resolutions is funny. Here's the quick fix.

  1. Put this following code in a file name reset_dns.

    #!/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='MY VPN'
    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")
      setup_vpn_ips=$(get_dns_ips "$vpn_srvc_name" "Setup")
      state_vpn_ips=$(get_dns_ips "$vpn_srvc_name" "State")
    
      echo "set_dns_ips $pri_srvc_name $setup_vpn_ips $state_vpn_ips $setup_dns_ips $state_dns_ips"
      set_dns_ips "$pri_srvc_name" $setup_vpn_ips $state_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)
    
      echo "set_dns_ips $pri_srvc_name $setup_dns_ips"
      set_dns_ips "$pri_srvc_name" $setup_dns_ips
    
      rm $ip_file
    fi
    
  2. Replace the word 'MY VPN' with the name of your VPN connection.

  3. Once connected to your VPN, run reset_dns from a terminal window

Mac OSX only uses DNS servers associated with your 'Primary' network connection. The above code adds the DNS servers of your VPN connection to the Primary network connection (i.e. usually Wi-Fi or Ethernet) so that your VPN DNS servers will be used first, then your Primary connection DNS servers second.

Run the reset_dns command again after disconnecting form your VPN to remove the entries and restore the original DNS server configuration. This is optional, though, as it usually doesn't hurt anything to just keep the DNS servers associated.