Random Dev Articles

latest | archive | lights on

SSH File System

Share, copy, deploy stuff to a remote folder over ssh.
Tuesday, 09 October 2018

Dig deep!

XKCD Documents

Get this article read to you.

Contents

Goal

A couple of weeks ago I found myself setting up an e-books server that was supposed to store my ever growing “Books I’d like to but I’ll rarely find the time to read” collection. That imposed an interesting network problem I had to solve. I had a large external drive connected to another machine that I wanted to utilize, however, setting up a Samba server wasn’t something I wanted to spend several cups of coffee on and NFS wasn’t an option for me either. It occurred to me that I should be able to achieve my goal using SSH.

The SSH File System

First, I must say, I just love this idea. Using SSH as means to provide seamless file I/O operations and access control via asymmetric crypto is something I’ll always consider from now on. The tool behind this is sshfs. It’s being frequently updated and one may be sure to find it in their package manager.

However, there are a couple of things to consider.

  1. It’s expected that SSH transfers will be slower due to crypto (and of course network) operations, although sshfs does use caching and multi-threading to address this. In any case, this does not seem to be an issue for me in a local network over a wired ethernet connection.
  2. sshfs leads to some very interesting user management cases, but this may quickly get too complex to handle. I’d say that using this within a complex access permissions scenario could be painful.

User Access Workflow

Here’s a simplified workflow on what happens behind the scenes.

SSHFS User Access

Setup

I have prepared two setup use cases - one based on Linux that I’m currently using and another one for macOS, which I mostly did for research purposes. It is most certainly possible to use sshfs on Windows, however, I have not done any setup research in that direction.

Debian Linux

Install sshfs on Server A via aptitude:

sudo apt-get install sshfs

Install FUSE (Filesystem in Userspace) via aptitude:

sudo apt-get install fuse

You would need to load the fuse module via:

modprobe fuse

Check if the module is loaded via:

lsmod | grep fuse

Run ssh-keygen on Server A to generate a key pair.

Copy the public key in $HOME/.ssh/id_rsa.pub from Server A and paste it to $HOME/.ssh/authorized_keys on Server B. Or just use scp to copy the file over.

Create a target mount point and mount it to Server A, e.g.,

mkdir $HOME/mountpoint
sshfs bob@server-b:/var/storage $HOME/mountpoint

You now have access to Server B’s storage space. To unmount run:

fusermount -u $HOME/mountpoint

Mount via systemd.service

It’d be great to have this run as a service, so if Server A reboots, the mount point gets setup automatically. For systems using systemd we can do that the following way:

Create a mount file in your $HOME (or any other accessible) directory.

#!/bin/sh


CMD="$1"
MNT="/home/mountpoint"
TARGET="/var/storage/"


start() {
  exec sshfs bob@server-b:$TARGET $MNT
}


stop() {
  fusermount -u $MNT
}


case $1 in
  start|stop) "$1" ;;
esac

As a root user, create a bob-mount.service file in /lib/systemd/system and add the following inside:

[Unit]
Description=Server B Mount Service
After=network.target


[Service]
User=alice
Group=alice
Type=forking
ExecStart=/home/alice/mount start
ExecStop=/home/alice/mount stop


[Install]
WantedBy=multi-user.target

Start and stop the service via:

systemctl start bob-mount
systemctl stop bob-mount

Enable the service to run at boot time:

systemctl enable bob-mount

macOS

Installation on macOS is pretty similar. Use brew to install the following:

brew install Caskroom/cask/osxfuse
brew install Caskroom/cask/sshfs

You should see FUSE for macOS in your System Preferences afterwards. To mount a share run:

mkdir $HOME/mountpoint
sshfs bob@server-b:/var/storage $HOME/mountpoint

To unmount just run:

unmount $HOME/mountpoint

An easy way to mount after reboot is to create a mount script and put it in the crontab.