Defining a persistent static route on Mac OS X

How does one define a static route on MacOS X which persists through reboots? The only suggestion I've found on Google advises setting up a launchd service to run at boot, which seems like a horrible hack (does it survive a network restart without rebooting, for instance?)

To set up the route I need temporarily, I can run the following:

route add -net ${network} ${gateway} ${netmask}

How would I make this persist?


Solution 1:

Except that a Launch Daemon (like a Startup Item before it) suffers from two important problems in this regard:

  1. If System Configuration redoes the network configuration, it will trash your route. You can combat that by making launchd run your Launch Daemon periodically, but you might still have to wait for that length of time for your route to be restored.

  2. Both Launch Daemons and Startup Items can run before some network interfaces are fully configured. In that case, you may not be able to make a route at that time, and might have to fall back to waiting for a periodic invocation of your Launch Daemon (or in the case of a Startup Item, perhaps for a cron job).

I just posted what will hopefully be a better (i.e. more robust) solution on my website. I built an installer package (download) for it; there's also some source code, but I can't post the link on Server Fault as I don't have a high enough reputation yet to put more than one hyperlink per post.

To use it, install the package (so far only tested on my laptop, but appears to work). It should install a Launch Daemon that starts the "staticrouted" server process (you can check this in top; if it isn't running, it probably means I got the installer slightly wrong, but you should be able to start it using launchctl as usual).

To create static routes, you use the "staticroute" program (which you'll find in /usr/local/sbin). e.g.

staticroute add 10.128.4.0/24 "Main Network Interface"
staticroute delete 10.192.0.0/16 "Other Interface"

You can also see the list of configured static routes with

staticroute list

and a list of interface names with

staticroute list-interfaces

Configured static routes survive a restart, and will automatically be added and removed as network interfaces go up and down.

There are also man pages; these are installed in /usr/local/share/man/man8, so you might also want to add /usr/local/share/man to your MANPATH if it isn't already there.

I should emphasise, I just knocked this code up today to fix a problem that is being caused by my having to use a cron job to keep static routes in place. It appears to work for me, but YMMV. The code and the binaries are MIT licensed.

Solution 2:

Three approaches, in ascending order of goodness:

  • Manually create a launchd service to set up the route, as per http://osxfaq.com/tips/kluskens/index.ws
  • Use Lingon to automate the creation of a service, otherwise as above; this software is unmaintained, but still works fine as of OS X 10.5.8.
  • Use RouteSplit, a tool built for the purpose.

Solution 3:

I have to disagree on the order of goodness - if the OP uses launchd (either with a manually created plist or one created with lingon), they can have it run at boot. If they use an AppleScript based solution like RouteSplit, they won't be able to run it without a user logged in.

Charles, I'm curious, why does using an OS vendor sanctioned tool like launchd seem hackish to you?