Saturday, December 24, 2011

Mounting Remote Directories With SSHFS

How you can mount a directory from a remote server on the local server securely using SSHFS.
SSHFS (Secure SHell FileSystem) is a filesystem that serves files/directories securely over SSH, and local users can use them just as if the were local files/directories. On the local computer, the remote share is mounted via FUSE (Filesystem in Userspace).

1. Login to the server as root:
$ sudo su

2. Installing SSHFS:

On the local system, SSHFS must be installed as follows:
$ apt-get install sshfs

3. Using SSHFS As root:

Mount the remote directory /home/backup to the local /backup directory as the local root user:

First add root to the fuse group:
$ adduser root fuse

Create the local /backup directory and make sure it's owned by root:
$ mkdir /backup
$ chown root /backup

Then mount the remote /home/backup directory to /backup:
$ sshfs -o idmap=user root@ /backup

Note: You can use a full path for the remote system, as shown above, or a relative path, like this:
$ sshfs -o idmap=user root@ /backup

If you use a relative path, this path is relative to the remote user's home directory, so in this case it would be /root/backup. You can even leave out the remote directory, as follows:
$ sshfs -o idmap=user root@ /backup

This would then translate to the remote user's home directory - /root in this case.

-o idmap=user makes that it does not matter if the local and the remote system use different user IDs - files owned by the remote user are also owned by the local user. If you don't use this, you might get permission problems.

If you connect to the remote host for the first time, you will see a warning about the authenticity of the remote host (if you have connected to the remote host before using ssh or scp, you will not see the warning). In any case, you will be asked for the root password for the remote server:

root@server1:~# sshfs -o idmap=user root@ /backup
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is a2:38:f3:df:7a:6c:b6:3c:d6:c3:9c:88:93:e2:f0:63.
Are you sure you want to continue connecting (yes/no)? <-- yes
root@'s password: <-- server2 root password 

Let's check if the remote directory got mounted to /backup:
$ mount

root@server1:~# mount
/dev/mapper/server1-root on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /boot type ext2 (rw)
root@ on /backup type fuse.sshfs (rw,nosuid,nodev,max_read=65536)

$ df -h

root@server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
                       29G 1015M   27G   4% /
udev                  238M  4.0K  238M   1% /dev
tmpfs                  99M  212K   99M   1% /run
none                  5.0M     0  5.0M   0% /run/lock
none                  247M     0  247M   0% /run/shm
/dev/sda1             228M   24M  193M  11% /boot
                       29G 1019M   27G   4% /backup

Looks good!

To unmount the share, run:
$ fusermount -u /backup

3.1. Creating A Private/Public Key Pair On local server
Of course, we don't want to type in a password every time we try to mount the remote share. Therefore we create a private/public key pair and transfer the public key to server2 so that we will not be asked for a password anymore.

local server:
Create a private/public key pair on
$ ssh-keygen

root@server1:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): <-- ENTER
Enter passphrase (empty for no passphrase): <-- ENTER
Enter same passphrase again: <-- ENTER
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/
The key fingerprint is:
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|  o . . S        |
|.o = . = o       |
|.o= . o + .      |
|=.+o . .         |
|@*E.. o.         |

It is important that you do not enter a passphrase otherwise mounting will not work without human interaction so simply hit ENTER!

Next, we copy our public key to
$ ssh-copy-id -i $HOME/.ssh/ root@

Now check on the remote server if local server's public key has correctly been transferred:

remote server:
$ cat $HOME/.ssh/authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnz2RwCZLLqBtB1rZKyN9XVfdAdt+PSpbGeLn+vlG/5nQvCSJhkRM3vpdmHPFrcYgJGtIU4gTCg6VDox2AxzJdGsrZN6zsLCndhgbs/r7N56ucuhdKSdeM/gLocnxkdQ86EECQqq42DaXgtqz3d8Q/Z+1KxYR82p7XK5ZoQG9vovNQNx9qhxIhsYIXMAbEv61bD1e0pBP9k9c1GfrZ79iRQrV+4UhHs/+Bca1YNby4gRmKIZK4FkzOYRUWYnIKVMMteC+lNho+ZMkKioo4CR3Z02hOV7ELFapqFY+6g7sj9cpLaM9gMY3rOd4EDARU+45U9yHBPsmIlA3zh4VkdnG/

Now back to local server, try to mount the remote share again (make sure it's unmounted before you run the command):

local server:
$ sshfs -o idmap=user root@ /backup

If all goes well, you should not be prompted for a password:

root@server1:~# sshfs -o idmap=user root@ /backup

3.2 Mounting The Remote Share Automatically At Boot Time:

local server:

If you don't want to mount the remote share manually, it is possible to have it mounted automatically when the system boots. Normally we would modify /etc/fstab to achieve this, but unfortunately the network isn't up yet when /etc/fstab is processed in the boot process, which means that the remote share cannot be mounted.

To circumvent this, we simply add our mount command to /etc/rc.local, which is the last file to be processed in the boot process, and at that time the network is up and running:

$ vi /etc/rc.local

#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.

/usr/bin/sshfs -o idmap=user root@ /backup
exit 0

You can test this by simply rebooting your system:
$ reboot

After the reboot, you can check with the following commands, if the remote share got mounted:
$ mount
$ df -h

4. Using SSHFS As A Regular User

local server:

I want to use the local user flaca now and mount the remote directory /home/someuser/backup, owned by someuser, to the local directory /home/flaca/backup.

Create the user flaca, if it doesn't exist:
$ adduser flaca

remote server:

On the remote server, create the user someuser, if it does not exist:
$ adduser someuser

Then become someuser...
$ su someuser

... and go to someuser's home directory where you create the backup (/home/someuser/backup) directory - make sure it's owned by someuser:
$ cd
$ mkdir ~/backup
$ chown someuser ~/backup

local server:

First add flaca to the fuse group:
$ adduser flaca fuse

Now go to the flaca account:
$ su flaca

Create the local /home/flaca/backup directory and make sure it's owned by flaca:
$ cd
$ mkdir ~/backup
$ chown flaca ~/backup

Then mount the remote /home/someuser/backup directory to /home/flaca/backup (still as user flaca) - you can either use a relative or the full path for the remote directory:
$ sshfs -o idmap=user someuser@ ~/backup


$ sshfs -o idmap=user someuser@ ~/backup

From here, you can use the rest of the process as explained at the beggining (for root user).

I hope this was usefull for you!