A few years ago all the projects I worked on were served on a shared hosting environment. It was quite common that a client had ftp access to server to upload some files. A control like Cpanel or Plesk made it really easy to create some ftp accounts.

Fast forward to today. Most projects are hosted on their separate DigitalOcean droplets provisioned by Forge. Even the smallest droplet has a whopping 20 GB of diskspace. An ftp-server is not installed by default. That's probably a good thing because ftp is an insecure and antiquated protocol. In this post I'd like to explain how you can help a client that wants ftp-like functions.

Our goal is to give a client read and write access to a single directory. We will make sure that the client cannot go outside that directory. We'll also prohibit the client from executing any shell commands. Instead of ftp we're going to use a more secure protocol: sftp. Let's do this!

The first thing you'll have to is to add a unix user. In the remainder of this post we'll assume that our client is named Bob.

sudo adduser bob

You will be prompted for a password and some general user information. After completing this command the homedirectory for Bob will have been created at /home/bob.

Next up we are going to make sure that this user is not allowed to use a shell:

sudo usermod -s /bin/false bob

If Bob will try to login via ssh he will immediately be logged out.

Now we are going to "chroot" Bob. This is the wikipedia definition:

Chroot is an operation that changes the apparent root directory for the current running process and their children. A program that is run in such a modified environment cannot access files and commands outside that environmental directory tree. This modified environment is called a chroot jail.

Chrooting Bob will make sure that when he logs in he will not see that he's in /home/bob directory. Bob will see that directory as his root. He will be able to create files and directories in only that directory. He will see nothing outside of it.

Here are the commands to set the permissions necessary to chroot Bob and to allow him full access to an uploads directory.

sudo chown root:bob /home/bob
sudo chmod 755 /home/bob

sudo mkdir /home/bob/uploads
sudo chown bob:bob /home/bob/uploads
sudo chmod 755 /home/bob/uploads

Right now Bob cannot login, we made sure of that by setting his shell to /bin/false Let's enable sftp for poor little Bob.

Inside /etc/ssh/sshd_config you should comment out this line by adding a "#" before it:

Subsystem sftp /usr/lib/openssh/sftp-server

Add these lines at the bottom of the same file:

#Enable sftp
Subsystem sftp internal-sftp

Match User bob
   #set the homedirectory as root
   ChrootDirectory %h

   ForceCommand internal-sftp
   X11Forwarding no
   AllowTCPForwarding no

   #enable loging with a password
   PasswordAuthentication yes

Reboot ssh to activate those changes:

sudo service ssh restart

Aaaaand we're done. Now Bob can use an application that has support for sftp (on OSX I highly recommend Transmit) to login with username bob and the chosen password.

Happy uploading!