Mount a remote filesystem via sshfs

SSHFS

SSHFS is a filesystem with a FUSE implementation. It provides users with a means to work on files on a remote system by mounting a directory on a remote system on a local mount point. These remote files are accessed in a secure way over SSH.

We assume you already have installed SSH on the remote system and on the local system where you want to mount the remote filesystem. On the local system we install sshfs. SSHFS is a Filesystem in USErspace or short FUSE.

For more information on what FUSE is, I'll quote the libfuse2 debian package documentation.

Note

FUSE (Filesystem in Userspace) is an interface for userspace programs to export a filesystem to the Linux kernel. The FUSE project consists of two components: the fuse kernel module (maintained in the regular kernel repositories) and the libfuse userspace library (maintained in this repository). libfuse provides the reference implementation for communicating with the FUSE kernel module.

A FUSE file system is typically implemented as a standalone application that links with libfuse. libfuse provides functions to mount the file system, unmount it, read requests from the kernel, and send responses back. libfuse offers two APIs: a "high-level", synchronous API, and a "low-level" asynchronous API. In both cases, incoming requests from the kernel are passed to the main program using callbacks. When using the high-level API, the callbacks may work with file names and paths instead of inodes, and processing of a request finishes when the callback function returns. When using the low-level API, the callbacks must work with inodes and responses must be sent explicitly using a separate set of API functions.

apt install sshfs fuse

The setup is rather easy. If the server/remote side already has SSH, you don't need any additional setup on the server/remote side. To mount the remote filesystem on the local machine, you need to login into the remote system with SSH.

Create a mountpoint, as root or with sudo in my case, you can use sshfs as a user as well:

mkdir /mnt/myserver

Use sshfs to mount the system, again root or use sudo:

sshfs <remote_machine>:/var/www/ /mnt/myserver

Mount as user

You can allow users to mount sshfs shares. You would need to create the mountpoint in a directory where your user has read and write rights, for instance:

mkdir /home/myuser/mnt/myserver

Then mount the directory from the remote system:

sshfs <remote_machine>:/home/myuser/ /home/myuser/mnt/myserver
    or
sshfs <myuser>@<remote_machine>:/home/myuser/ /home/myuser/mnt/myserver

To unmount the directory you might have to use sudo, root or fusermount as otherwise you will get a permission denied message.:

fusermount -u /home/myuser/mnt/myserver

Interesstingly, the sshfs Debian documentation says the following:

cat /usr/share/doc/sshfs/README.Debian
...
sshfs for Debian
----------------

Please note that the simplest way to allow mounting of sshfs shares is to
add the user to the fuse group (which will be created by the fuse-utils
package).

To add user 'foo' to the 'fuse' group type the following command (with root
privileges):

    adduser foo fuse

This failed on my end, no fuse group. Anyway, the fuse group doesn't seem necessary to mount shares as a user as demonstrated above. Just an oversight on the documentation it seems.


Extra options

Check out the FUSE options you can add to the sshfs command. Some interesting ones:

allow_other: allow access to other users

allow_root: allow access to root

default_permissions: enable permission checking by kernel

idmap=user: the files owned on the remote system will probably have a different user id. This setting
    makes the files owned by the remote user also owned by the local user

If you want to use allow_other, you will also need to set this /etc/fuse.conf:

vi /etc/fuse.conf
...
# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other

If you need to use a keyfile to connect to the remote system, and would want to use options as well, this is how your command might look:

sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa <myuser>@<remote_machine>:/home/myuser/ /home/myuser/mnt/myserver

Making the mount persistent

You can make the mount persistent my editing /etc/fstab. The mount directory will need to be persistent between reboots in order to mount the remote file system. In order to automatically mount our first example:

vi /etc/fstab
...
# Add to the bottom of the file
user@<remote_machine>:/home/myuser/  /home/myuser/mnt/myserver   fuse.sshfs user,idmap=user,allow_other,noauto  0    2

You can then mount the remote directory as user:

mount /home/myuser/mnt/myserver

If you get the following error when trying to list files on the newly mounted directory, you probably messed up something with the permissions. Try to login to the remote machine with the same user as specified in fstab.

Error

ls: cannot access 'myserver': Transport endpoint is not connected


Additional info and usecases

There are some interesting tidbits and usecases in the sshfs FAQ . zcat is your friend:

zcat /usr/share/doc/sshfs/FAQ.gz

An interesting one is how to mount a usb on the client on the server. To quote the FAQ (nr 19 at the time of writing):

Note

You want to mount a USB thumb drive onto a file server that is rather remote.

Assuming this is difficult because the laptop with the thumb drive is sitting behind NAT, firewalls, etc. then you need to create a port-forward:

client$ ssh -R 2222:localhost:22 server

server$ sshfs -p 2222 localhost:/media/usb1 myusb1

On the ability to debug the FAQ has this to say:

Also logs with debugging output can be useful for diagnosing the problem.
Try running sshfs with the following options:

    sshfs -odebug,sshfs_debug,loglevel=debug ...

Doing strace on the application which fails may also sometimes help:

    strace -f -o /tmp/strace application args ...

It might be necessary to create the fuse device node:

If you don't use udev, you may get this error message:

fusermount: failed to open /dev/fuse: No such device or address

Before loading the fuse kernel module, create the device node
manually:

  mknod -m 666 /dev/fuse c 10 229