I was particularly impressed by Dropbox and its ability to backup, retrieve and share files so easily, but I am quite concerned about the security issues deriving from having your files on a remote, closed-source system. I think that a good remote storage solution should prevent the owner of the storage server from accessing private data. Is it even possible? It is, using the right approach: the client computer must perform encryption when storing remote files, and decryption when retrieving them. I put together a solution for Linux systems using sshfs and encfs.
I used two computers: a server and a client, but for testing purposes just one computer is needed. The server acts as a storage provider, using an ssh server. It can serve multiple users, and each user has a box where he can put anything. A user that connects to the server creates an encrypted space using encfs, and fills the box with private data.
On the server
- Add a user, for example remote_user1
- Prepare a directory that will be the remote_user1 personal box. For example:
# mkdir /srv/boxes
# mkdir /srv/boxes/remote_user1
# chown remote_user1.remote_user1 /srv/boxes/remote_user1
- Install ssh server. On Debian-based systems:
# apt-get install open-ssh-server
- edit /etc/ssh/sshd_config to include the following options (this will prevent the users to use ssh to do anything but file transfer on their personal box):
Subsystem sftp internal-sftp
- Reduce read/write permissions on the root server directory. This is done to prevent the user to mount the root directory and list its contents.
# chmod 711 /srv/boxes
- Restart ssh server, for example:
# invoke-rc.d ssh restart
On the client
- You can add a user, for example user1, or continue with an existing user.
- Install ssh client, sshfs and encfs. On Debian-based systems:
# apt-get install open-ssh-client sshfs encfs
- Add user1 to the fuse group
# adduser user1 fuse
- Log in as user1 (if you are already logged in as user1, log off and log in to render the fuse group effective)
- Create a folder that will contain the encrypted file system mounted through sshfs
$ mkdir ~/.box_enc
- Mount the remote directory, providing remote_user1 password (boxserver is the computer where we created the remote boxes before)
$ sshfs remote_user1@boxserver:remote_user1 ~/.box_enc -o uid=$(id -u) -o gid=$(id -g)
- Create a folder that will contain the unencrypted file system mounted through encfs
$ mkdir ~/box
- Mount the encrypted directory, creating an encfs environment encrypted with a password. After this step, the directory ~/box can be used as any other directory, but everything in it will be encrypted and stored in a remote folder, specifically the /srv/box/remote_user1 folder in your server. If you list the content of that remote folder (that is also the content of ~/.box_enc folder in the client computer) you will only see encrypted content and the xml file that encfs uses to keep the environment settings.
$ encfs ~/.box_enc ~/box
- To unmount the directories, execute, in order:
$ fusermount -u ~/box
$ fusermount -u ~/.box_enc
- You can setup ssh with key authentication instead of password authentication to avoid typing the password every time you want to mount the encrypted remote folder. To do so, on the client side:
$ cp ~/.ssh/id_rsa.pub ~/.box_enc #~/.box_enc must be mounted
On the server side, logged in as remote_user1:
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ cat /srv/boxes/remote_user1/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ rm /srv/boxes/remote_user1/id_rsa.pub
- You can setup encfs to read the password from a file, using for example:
$ read -s -p 'password>' pwd
$ touch ~/.encfs_pwd
$ chmod 600 ~/.encfs_pwd
$ echo "$pwd" >> ~/.encfs_pwd
$ encfs --extpass='cat ~/.encfs_pwd' ~/.box_enc ~/box
- You can use the mounted directory as a backup, and use rsync to synchronize a local folder and your backup folder. For example:
$ #To pull your files from your backup folder:
$ rsync -uav ~/box/ ~/Documents/
$ #To push your files to your backup folder:
$ rsync -uav ~/Documents/ ~/box/
- Then you can schedule a job to keep them synchronized. To run a sync every minute:
$ crontab -e
* * * * * rsync -ua /home/user1/box/ /home/user1/Documents/ && rsync -ua /home/user1/Documents/ /home/user1/box/
- To change the behavior of the server so that only a certain group of users are restricted to the file transfer functionality of ssh, you can use the Match keyword inside the sshd_config file, before the “ChrootDirectory” and “ForceCommand” lines. (see “man sshd_config”)
The security implications of this setup are complicated. Mostly, this setup is as secure as the combination of encfs and your client computer. The remote server cannot see the content of your files unless it knows the encfs password, but it can see the number of files and the directory structure (see http://www.arg0.net/encfsintro and encfs man pages for more details). Theoretically, it could be possible for someone with access to the remote server to understand what kind of files you have on your box. For example, a big 400MB file could be a movie, a compressed file or a CD image; a directory could have a structure that resembles that of a Firefox profile folder.
The setup I just described is quite easy to follow if you know Linux well. It is tricky if you’re not expert. This solution can be automated in some aspects, for example an installation could setup the remote box to mount at login. Moreover, a nice GUI could be developed to do a quick start, to select backup options and security settings. The performance is not so great, since the data must be encrypted two times: one for encfs and one for ssh; it is however faster than I thought (I have not done benchmarks); moreover both sshfs and encfs have options (like cache and compression) that could speed up the file transfer. About the Operating System: this setup works on Linux, but I think it should work also on Mac OS X thanks to the macfuse project that enables, among others, sshfs and encfs. On Windows sshfs is available through Dokan libraries, but I can’t find anything for an encfs port.
This experiment is satisfying from a technical point of view, but it lacks the usability to be considered a full-blown alternative to Dropbox; I think that a better alternative could be Novell’s iFolder. Currently, from what I found, iFolder server kinda works on non-Novell distros, but it needs some hacks and the installation is not straightforward (see http://ubuntuforums.org/showthread.php?t=1163192&page=3), but it’s promising. I think I will try to install a complete setup when I have the time.
I found a blog that reports stability problems with sshfs + encfs setups. I haven’t found the timestamp problem he mentions, but the two computers I used are tightly connected. I didn’t do a “heavy load” stress test either, just syncronizing a directory containing the sources and binaries of a small project.