Space-limited shared remote storage through SFTP

9 Jan 2018

I know a few groups of people and associations who sometimes need a storage server for sharing big files. With a few hundreds of GB available, it's possible to offer them a secure FTP server and control how much size they can use in a chrooted directory. The end users will just have a login and a password (or a key) to connect to your server with an SFTP client like Filezilla.

Steps:

  1. Setup SFTP-only accounts
  2. Create a file system directly in a file

Set up SFTP-only accounts

Install OpenSSH, and if it does not exist, create the "sftponly" group:

sudo apt-get install openssh-server
sudo addgroup sftponly

Create and add the user who will connect to your FTP server to the sftponly group, here "edmond", and remove its ability to connect through SSH:

sudo adduser edmond  # adduser will create his home directory in /home/edmond
sudo addgroup edmond sftponly
sudo chsh -s /usr/bin/nologin edmond

Now in the SSH daemon config, usually in /etc/ssh/sshd_config, replace the sftp subsystem with "internal-sftp", and add restrictive rules for the sftponly group:

Subsystem sftp internal-sftp

Match Group sftponly
    ChrootDirectory %h
    AllowTcpForwarding no
    X11Forwarding no
    ForceCommand internal-sftp

The "match" block should be placed at the end of the file or the daemon won't be able to understand the config file. You can specify whether or not you want to allow password and public key authentication here with the rules PasswordAuthentication and PubkeyAuthentication set to yes or no. You can also specify where the user will be chrooted with "%h" (her home directory) or e.g. "/srv/jails/%u" where %u is automatically replaced with her user name.

For the chroot to work properly, the target directory needs to be owned by the user root, without write privileges for its group and without any privileges for others. In our example for /home/edmond:

cd /home
sudo chown root:edmond ./edmond
sudo chmod 0750 ./edmond

You should now be able to connect to your server with the new account credentials and end up chrooted in your (almost) empty home directory.

Create a file system directly in a file

To ensure users don't store more data than you want on the server, we will use a self-contained EXT4 file system stored in a file.

# Create an empty file of 10 GB (1M times 10240 bytes, set count to your needs)
sudo dd if=/dev/zero of=/home/edmond.ext4 bs=1M count=10240
# Set secure file permissions
sudo chown root:root /home/edmond.ext4
sudo chmod 0660 /home/edmond.ext4

# Create a file system directly in the file
sudo mkfs.ext4 /home/edmond.ext4
# Finally, mount it on your home directory
sudo mount -t ext4 -o loop /home/edmond.ext4 /home/edmond

Once the home directory is ready, you can create a writeable directory for your users:

# Create a writeable directory for the user
cd edmond
sudo mkdir SharedFiles
sudo chown edmond:edmond SharedFiles
sudo chmod 0770 SharedFiles

# When several people might access these files, it might be a good idea to use
# the setgid flag:
sudo chmod g+s SharedFiles

You should now be able to read and write in this shared folder entirely through your SFTP client, without any other access to the server. The users won't be able to upload more than the size of your EXT4 file system.

This method is probably not the most efficient way to provide secure and limited remote storage but its principles are easy to grasp, so if you're lazy or in a rush to deploy a storage for a specific need, I recommend it :)