Mac OS X - (persistent) Static routes based on "Location"

Imaging you use your Mac OS X device on you work and home, here is how to add static routes per location.

Network Locations (Under Apple - Location) is a facility to quickly change your network configuration. You might configure "Home" and "Work" for example.

Imaging you need to add a static route for your "Work" Location. Here is how to do it.

  1. Select your "Work" (or whatever) location under Apple (top left) - Locations.
  2. Open a Terminal
  3. Type: "networksetup -listallnetworkservices" to see the names of the Locations. You need one Location name in the next command.
  4. Type: "networksetup -setadditionalroutes $location $network $netmask $router". Replace $location for a location found in the previous command, $network with the network address, such as 192.168.0.0, $subnet for the subnet, such as 255.255.0.0, $router with the router, such as 172.16.0.1. You can add multiple routes by simply listing the next route, like so: "networksetup -setadditionalroutes $location $network $netmask $router $network2 $netmask2 $router2".
  5. To verify the route(s) just added: "networksetup -getadditionalroutes $location".

Now this route is persistent. If your interface is up, and the Location is in use, you'll see the route appear automatically.

Now another some-what related trick; when working with multiple locations and interface, you might need to configure DNS resolving in a very specific way; to resolve public requests to the internet and "private" requests to selected (caching) DNS servers, you can use a trick that Mac OS X provides. It may get clear with this example:

sudo mkdir /etc/resolver/

echo "nameserver 192.168.1.1
nameserver 192.168.2.1" | sudo tee -a /etc/resolver/internal.company.com

echo "nameserver 192.168.1.1
nameserver 192.168.2.1" | sudo tee -a /etc/resolver/domain.tld

So requests to internal.company.com (and all sub-domains, such as example.internal.company.com) will be resolved on the DNS servers 192.168.1.1 and 192.168.2.1. Same for domain.tld (and *.domain.tld).

To verify if this works, nslookup won't help, you can use these tools:

scutil --dns

dns-sd -G v4 example.internal.company.com

Just to be clear; these DNS tricks are persistent and work over all Locations.