Read-Write Blog

Read the doc, write the code...

My Guide for SSHFS

| Comments

Introduction

The SSH (Secure Shell) protocol provides multiple extensions like SCP (Secure Copy), SFTP (Secure File Transfer Protocol), or SSHFS (Secure Shell File System). This guide shows how to use SSHFS in order to mount a remote directory as a volume on your file system.

Every serious FTP client software provides SCP/SFTP protocols implementation, but why to use third-party software when it is all about UNIX? I tried several apps which handle SSHFS and provide mount support, but I encountered many issues mainly like the instability of the Finder.

The way I found to get this working (stable) with an easy setup is using fuse4x, sshfs and few Applescript to automatize the process.

Requirements

This guide assumes that you already have an access on a running SSH server, configured with key exchange authentication (passwords are bad because transferred in plain text). Instructions below are available for Mac OS X 10.6 and higher.

Installation

So, to run SSHFS on Mac OS X, you must install several components:

fuse4x

fuse4x is an implementation of FUSE (File System in Userspace) for Mac OS X. Download it here and install the package.

sshfs

sshfs is the file system client based on SSH protocol we will use to mount a remote directory. There are several ways to install sshfs on your system:

  • Manually, using the Terminal (recommended):

    1. Download sshfs
    2. Untar: tar -xzvf sshfs-fuse-2.3.tar.gz
    3. Change directory: cd sshfs-fuse-2.3
    4. Configure: ./configure
    5. Compile: make
    6. Install: sudo make install
  • Using Macport:

    • sudo port install sshfs
  • Using Homebrew:

    • brew install fuse4x sshfs

I recommend the manual installation because it works perfectly for sshfs 2.3 version. Package managers like Macports and Homebrew are as sexy as confused and yet, why to use third-party software when it is all about UNIX?

To test if your installation successfully worked, open a new shell, and try the following command: sshfs -h. You should see the sshfs help message. If not, have a look to the References section at the bottom of this article, maybe you can found a little help.

How-to use

To mount a remote directory from a SSH host you need a dedicated local directory. So, on your local computer, open a Terminal and type:

mkdir ~/RemoteHome

Now, you will use sshfs to mount your remote directory to the newly local directory:

sshfs -p 22 user@example.net:/home/user/ ~/RemoteHome -oauto_cache,reconnect,defer_permissions,negative_vncache,volname=RemoteHome

If you go to ~/RemoteHome, you should see the content of /home/user/ at example.net.

To unmout the volume, use:

umount ~/RemoteHome

Tuning

By default, Mac OS X also writes “.DS_Store” files into your remote directories. It exists two ways to get rid of this issue:

  • Using the noappledouble option (specified remote volume):

    • sshfs -p 22 user@example.net:/home/user/ ~/RemoteHome -oauto_cache,reconnect,defer_permissions,noappledouble,negative_vncache,volname=RemoteHome
      
  • Telling to the system to not write these such files (for every remote volumes…):

    • defaults write com.apple.desktopservices DSDontWriteNetworkStores true
      

To remove previously created “.DS_Store” files, use the following command:

find /path/to/share -name .DS_Store -exec rm {} \;

Automatize

Now, I would like to use SSHFS without typing any command line in the Terminal. I made a little script, using Applescript, to automatize the mounting of several directories in one click.

To use the script:

1. Open "Script Editor.app" and paste the script below
2. Adjust SSH parameters: sshHostname, sshPort and sshLogin
3. Adjust SSHFS parameters: remotePaths, localPaths and volumeNames
4. Save the script as an application
5. Run the newly created application!

The script here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  -- SSH parameters
  set sshHostname to "example.net"
  set sshPort to 22
  set sshLogin to "user"

  -- SSHFS parameters
  set remotePaths to {"/home/user/Documents", "/home/user/Downloads"}
  set localPaths to {"~/Desktop/Documents", "~/Desktop/Downloads"}
  set volumeNames to {"Documents", "Downloads"}

  repeat with x from 1 to count of remotePaths
      set remotePath to item x of remotePaths
      set localPath to item x of localPaths
      set volumeName to item x of volumeNames
  
      -- Try to unmount
      UnmountVolume(localPath)
  
      -- Check local directory path
      CheckVolumeDirectory(localPath)
  
      -- Try to mount
      MountVolume(sshHostname, sshPort, sshLogin, sshPassword, localPath, remotePath, volumeName)
  end repeat

  -- Function: Create directory if not exists
  on CheckVolumeDirectory(aPath)
      tell application "System Events"
          if exists file aPath then
          else
              try
                  do shell script "mkdir " & aPath
              end try
          end if
      end tell
  end CheckVolumeDirectory

  -- Function: Unmout volume at path
  on UnmountVolume(aPath)
      try
          do shell script "/sbin/umount " & aPath
          log "Unmount SSHFS Volume: " & aPath
      end try
  end UnmountVolume

  -- Function: Mout volume at path
  on MountVolume(sshHostname, sshPort, sshLogin, sshPassword, localPath, remotePath, volumeName)
      try
          set sshURL to sshLogin & "@" & sshHostname
      
          do shell script "/usr/local/bin/sshfs -p" & sshPort & " " & sshURL & ":" & remotePath & " " & localPath & " -oauto_cache,reconnect,defer_permissions,noappledouble,negative_vncache,volname=" & volumeName
          log "Mount SSHFS Volume: " & localPath
      end try
  end MountVolume

References

Comments