Remote SSH Filesystems on OSX

Developers, particularly web developers, have a need to work on external computers, often not within their local networks.  Over the years I've employed everything from FTP to SFTP/SCP to Samba to NFS to VPNs to cranky Novell networks.  All have their downsides, particularly with regard to security.

I have a MacPro and originally ran NFS to connect to machines on my LAN.  But as Apple released new versions of OSX it became more hostile to NFS, to the point where it because unusable with my Ubuntu-hosted web server.  I retreated back to Samba but it was always a PITA because every time I rebooted the Mac I had to manually remount those network shares.   Half the time they wouldn't appear in Finder so I'd have to do it again.

When I got my new MacBook I decided to spend some extracurricular time sorting out this problem.  My research led me to OSXFUSE.   OSXFUSE is a library that allows foreign filesystems to integrate with OSX's own.  One of those is SSHFS, a GitHub project that allows foreign filesystems to be mounted over a secure socket layer.  This sounded exactly like what I wanted.  There was virtually no setup required on the host other than a functioning SSH account.   While I doubted that it would be a particularly fast filesystem, I'm not streaming media with it, mostly just pushing files through my programming editor which unfortunately lacks SFTP support of its own.

The first step was to set up password-less SSH account on the remote.   That's outside the scope of this post but there are excellent directions here, with one nit: you'll probably need to run ssh-keygen -t dsa if you want to use DSA files instead of the default RSA.   It doesn't matter much which file format you choose.  Just remember that you copy the id_XXX.pub file to the remote host. Afterwards, test your login to make sure it's truly password-less.  What follows won't work if this doesn't.

One thing that impressed me about OSXFUSE was that OSX Mavericks was released just a week ago and the developer had already incorporated the changes needed to make it compatible withOSX 10.9.  Installation was as simple as it gets.  Just download the latest version (2.6.1 at this time), accept the defaults and install, but be aware that it's just a library.  There are no UI or applications associated with it so don't expect anything to appear in your Applications folder.

The same is mostly true of SSHFS as well.  Installation was simple and direct and you won't see anything pop up on your desktop.  But you'll see it if you open Terminal.  The core of SSHFS is a binary, /usr/local/bin/sshfs, which works much like /sbin/mount.

I wanted to get these details out of the way so I can focus on how to use this.  The web was particularly sparse of coherent SSHFS tutorials, at least on Mac platforms.

Let's test it.  Using your remote host (where you've successfully installed a password-less SSH login), the process is pretty straightforward.  You need to create a local mount point for the remotefilesystem on your Mac.  Then you want to mount a remote filesystem on it.  Since all Unix systems have a /tmp directory readable and writable by everyone, try this:

mkdir /Volumes/tmp
/usr/local/bin/sshfs USER@HOST.COM:/tmp /Volumes/tmp -ovolname=stevem,reconnect -ocache=no -onolocalcaches

Now cd /Volumes/tmp and see if you can access that foreign filesystem.



if all looks fine, unmount it with umount /Volumes/tmp.  Now you're ready to move on to the next step: mounting the filesystems you actually need.  Bear in mind that if you don't have permissions to read or write a filesystem on the remote while SSH'd into it normally, you won't with SSHFS either.  I know I shouldn't have to say this but I will.



The problem is that you don't want to have to run these commands from the shell every time you reboot your computer.   You could write a Bash script to do it, and that's essentially what we're going to do here.  But you would still have to do a Terminal login.



Fortunately, OSX has a rich set of automation features that will save us that drudgery.  One is Launchctl, which can be programmed to run a shell script based on some external event, like a login.  I chose not to use it because I want the flexibility of not having my laptop automatically attempt to mount filesystems when it might not even have a net connection.  I wanted a button to mount thosefilesystems on demand.



OSX has a utility called Automator which has a very handy feature in its Application mode: Run Shell Script.  What we're going to do is write a shell script to load all of our shares and have Automatorcreate a nice little OSX-friendly interface for it.  Here's the Bash script:

#!/bin/bash
# Load SSHFS filesystems on remote Linux box.

$USER=YOUR_LOGIN_ACCOUNT
$HOST=REMOTE_HOST_NAME

notify ()
{
    terminal-notifier -message "$1" -title "Mount SSHFS Filesystems"
}

open_volume ()
{
    VOLUME=$1           # local mount point
    SOURCEDIR=$2    # remote server directory
    NAME=$3               # descriptive name

    # See if volume directory already exists.
    if [ -d "$VOLUME" ]; then
        # See if volume is currently mounted.
        if mount | grep $VOLUME; then
            notify "$VOLUME is mounted. Unmounting..."
            umount $VOLUME
        fi

        sleep 1

        # Remove the volume directory if umount failed to do so.
        if [ -d "$VOLUME" ]; then
            rmdir $VOLUME
        fi
    fi

    mkdir $VOLUME
    /usr/local/bin/sshfs $USER@$HOST:$SOURCEDIR $VOLUME -ovolname=$NAME,reconnect -ocache=no -onolocalcaches

    notify "$VOLUME mounted."
}

# Add your shares here.
open_volume /Volumes/web /usr/local/web/sources web
open_volume /Volumes/tmp /tmp tmp
open_volume /Volumes/$USER /home/$USER home



Load Automator, select New and then Application.  From the long pulldown menu double click on Run Shell Script.  Then copy and paste this script to the window and save it with a name like MountSSHFS.  But before you run it, you're going to need another piece of open source software.  I wanted the script to report its status to the desktop.  The standard /bin/echo wont do this because there's no STDOUT for it to talk to. I wanted one of those nifty status popup sliders in OSX. To accomplish this I installed a Ruby utility, terminal-notifier.  Instructions for downloading and installing it are on OSXDaily.com



Now you can run it.  Providing you've got your Finder preferences set up to show Connected Servers you should see those folders appear on your desktop and in Finder as well.



To add the script to your general applications folder, use the File -> Move To.. option in Automator.