I feel like I've gone through every SFTP/Chroot tutorial on the Internet, and not found what I am looking for (or, at least, none of them have produced the right results). Here's my specifics:
- I will be creating a lot of individual user accounts via script. So any solution that requires me to very delicately hand edit files on a user-by-user basis is not a good one.
- Each of these users will be given a directory in the folder /var/www/html/USER, where USER is their username. They should have total write access to that directory, and be able to create and edit sub-directories, but they should be entirely locked out of any directories that are higher on the file tree (they should not be able to list, much less edit, /var/www/html/ or /var/www/ or /var/, etc.)
That's it. Seems simple, right? And yet most of the examples I have seen are about locking all SFTP users into a single, shared directory, or require you to "jail" your user to their /home/USER directory (which won't work for the web service). I don't want that.
I am doing this on Ubuntu 16.04, on a fresh AWS EC-2 instance.
The two approaches I have tried, in vain:
Setting the user's HOME to /var/www/html/USER, Chroot jailing them to HOME. For whatever reason, this doesn't seem to work — it results in SFTP just refusing to connect.
Setting up a standard HOME directory for the user (e.g. with adduser), creating the user's web directory, Chroot jailing them to the web directory. I've just not managed to get this working despite days of trying — the SFTP accounts still end up tunneling into the HOME directory and that often means they are rejected by the Chroot jail.
What has ended up happening is either users have WAY too much freedom, or they are locked out entirely. I've never managed to get it into a situation where the user can only see the right directory, AND are able to edit it. I have tried every chown setting on that directory (e.g., user:user, user:sftp, root:root), and permission setting, and it seems to have had zero effect. I'm missing something here that is either obvious or deep.
Some added details — here's one of my attempts.
Here are the relevant parts of /etc/ssh/sshd_config:
Subsystem sftp internal-sftp Match Group sftp ChrootDirectory %h X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
Which matches what most guides say you should do.
I create a new user:
adduser --disabled-password -gecos "" --ingroup sftp --shell /usr/sbin/nologin --home /var/www/html/testuser testuser
Adding user `testuser' ... Adding new user `testuser' (1001) with group `sftp' ... Creating home directory `/var/www/html/testuser' ... Copying files from `/etc/skel' ...
And I then give them a password with passwd.
I then try to log in:
sftp testuser@myserver testuser@myserver's password: packet_write_wait: Connection to myserver_ip: Broken pipe Connection closed
Which seems to be due to the Chroot jail setting and not related to any other obvious server setting. If I comment out the ChrootDirectory, it connects fine:
sftp testuser@myserver testuser@myserver's password: Connected to myserver. sftp> pwd Remote working directory: /var/www/html/testuser
But I do that, the sftp user can exit their directory and wander all over the server, doing whatever they please. Not good!
I have also tried setting
And it doesn't change anything that I can see (same "Broken pipe" error as before). (And yes, I am restarting the ssh server every time I make a change.)
These are the current settings for the user folder:
drwxr-xr-x 4 testuser sftp 4096 Aug 29 15:00 testuser
Some instructions say for Chroot to work, you need to
chown root:root /var/www/html/testuser
But I still get the "Broken pipe" error with the ChrootDirectory set. Changing the permissions to 777 doesn't change that, either. (/var/www/html is owned by root:root, as is /var/www/ and /var/)
Other things I have tried with /etc/ssh/sshd_config:
changing it to Subsystem sftp /usr/lib/openssh/sftp-server and commenting out ForceCommand internal-sftp (no perceivable change)
Commenting out UsePAM yes (someone reported this helped, but it just makes sftp server reject all connections immediately -- "closed by remote host")