Change ssh configuration when the "Location" changes on Mac OS X

Have you ever used the "Location" facility in Mac OS X? It changes network settings for you when you work from different locations, like "work", "home", "mobile" or any other setting. As far as I can tell it's designed to change:

  • IP, netmask, gateway
  • Used interfaces (airport, ethernet, etc)
  • Proxy server

What's missing here is SSH settings. You configure your ssh-client in ~/.ssh/config manually. In my case I can login a machine from home directly, but when I am somewhere else, I need to use a step-stone.

That would mean I'd have to change ~/.ssh/config every time I am on a different location! Here is a solution to the problem, inspired by an article about Location based scripts.

  1. Create a new Location in Mac OS X Click on the Apple logo in the left corner, Location - Network Preferences - Edit Locations - The + symbol and so on.
  2. Copy/create ssh configurations, call them ~/.ssh.$PROFILE and replace $PROFILE by the name you came up with for you profile names. I use "~/.ssh/config.Automatic" and "~/.ssh/config.Mobile".
  3. Add a few lines to /~.locationchanger These lines actually link ~/.ssh/config to the right ssh configuration.
    location=$(scselect 2>&1|grep ' \* ' | awk '{print $NF}' | sed 's/(//g;s/)//g')
    if [ -f ~/.ssh/config.$location ] ; then
    rm ~/.ssh/config
    ln -s ~/.ssh/config.$location ~/.ssh/config
    fi
  4. Make the ~/.locationchanger executable Use chmod 750 ~/.locationchanger to do that.
  5. Create a file ~/Library/LaunchAgents/LocationChanger.plist The content should be like this:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
            "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
            <key>Label</key>
            <string>tech.inhelsinki.nl.locationchanger</string>
            <key>ProgramArguments</key>
            <array>
                    <string>/Users/robertdb/.locationchanger</string>
            </array>
            <key>WatchPaths</key>
            <array>
                    <string>/Library/Preferences/SystemConfiguration</string>
            </array>
    </dict>
    </plist>
  6. Load that LocationChanger into launchd. Use launchctl load ~/Library/LaunchAgents/LocationChanger.plist to do this, or reboot.

From now on the script ~/.locationchanger will be started when changing Location.

Some items that might be changed when you switch locations are using a stepstone to ssh to machines or using corkscrew to puch through http proxies.

This tool uses scselect, an apple tool that confiures or prints locations.

SCSELECT(8)               BSD System Manager's Manual              SCSELECT(8)

NAME
     scselect -- Select system configuration "location"

SYNOPSIS
     scselect [-n] [new-location-name]

DESCRIPTION
     scselect provides access to the system configuration sets, commonly
     referred to as "locations".  When invoked with no arguments, scselect
     displays the names and associated identifiers for each defined "location"
     and indicates which is currently active.  scselect also allows the user
     to select or change the active "location" by specifying its name or iden-
     tifier.  Changing the "location" causes an immediate system re-configura-
     tion, unless the -n option is supplied.

     At present, the majority of preferences associated with a "location"
     relate to the system's network configuration.

     The command line options are as follows:

     -n  Delay changing the system's "location" until the next system boot (or
         the next time that the system configuration preferences are changed).

     new-location-name
         If not specified, a list of the available "location" names and asso-
         ciated identifiers will be reported on standard output.  If speci-
         fied, this argument is matched with the "location" names and identi-
         fiers and the matching set is activated.

SEE ALSO
     configd(8)

HISTORY
     The scselect command appeared in Mac OS X Public Beta.

Mac OS X                       November 4, 2003                       Mac OS X

Comments

I stumbled across this page

I stumbled across this page when searching for a solution to a very similar situation.

I have a fairly involved ssh configuration, and I don't want to maintain two different copies of it when I change something. Since OpenSSH does not support 'includes' in their config files, I made a slight change to your solution that allows this to work.

I place all my config that is the same in ~/.ssh/config.common, and then make location specific files as you describe in your post.

location=$(scselect 2>&1|grep ' \* ' | awk '{print $NF}' | sed 's/(//g;s/)//g')
if [ -f ~/.ssh/config.$location ] ; then
    # WARNING: changes may be lost!  The symlink was safer in this regard.
    rm ~/.ssh/config

    # The most specific config should come first
    cp ~/.ssh/config.$location ~/.ssh/config

    # Add the shared config, if it exists
    if [ -f ~/.ssh/config.common ]; then
        # protect against no newline at EOF
        echo >> ~/.ssh/config
        cat ~/.ssh/config.common >> ~/.ssh/config
    fi
    # Make the config read-only, as a reminder that any changes
    # to it will be lost when the location changes.
    chmod ugo-w ~/.ssh/config
fi

About Consultancy Articles Contact




References Red Hat Certified Architect By Robert de Bock Robert de Bock
Curriculum Vitae By Fred Clausen +31 6 14 39 58 72
By Nelson Manning robert@meinit.nl