Setup an sftp-only User in Linux

How to setup a user to access the server via sftp only.

User and Home Directory

For allowing a user to login via password, see http://serverfault.com/questions/154957/set-up-sftp-to-use-password-but-ssh-not-to-use-password. In some cases, we want the ec2-user to be able to login via keypair only, while allowing, e.g. the content-upload wordpress user, to login via password.

Create the user, assign a password, set the user’s default group to www (same as the apache user), and mount the html directory into the user’s home directory (so that it can be accessed without traversing up and then down into the /var/www directory).

Only execute the sudo passwd line if we want the user to login via password rather than via keypair.

sudo adduser username
sudo passwd username
sudo usermod -g www username
sudo mkdir /home/username/www
sudo chown username:username /home/username/www
sudo chown root:root /home/username/
sudo chmod 755 /home/username
sudo mount --bind /var/www /home/username/www

To make the mount survive a reboot, add this line to /etc/fstab:

/var/www /home/username/www none defaults,bind 0 0

sshd_config

These are the lines that need to be added to the end of /etc/ssh/sshd_config. I don’t properly understand the X11Forwarding and AllowTcpForwarding lines, but every example I see has them, so I’m going with it.

If the user should be allowed to login via password, then PasswordAuthentication should be yes. Otherwise, that line can be removed or set to no.

The ChrootDirectory needs to be owned by and only writable by root. %h evaluates to the user’s home directory as defined in /etc/passwd.

Match User username
  PasswordAuthentication yes
  ChrootDirectory %h
  X11Forwarding no
  AllowTcpForwarding no
  ForceCommand internal-sftp

Restart sshd:

sudo service sshd restart

Some helpful insight into sshd and especially ChrootDirectory: