Chroot SFTP - Possible to allow user to write to current (chroot) directory

I currently have a WORKING SFTP login, using a private key for login and the user is chroot'ed into their home directory.

Goal: Keep the user chroot but allow WRITE access to the relative chroot directory, without having to specific any path or cd anywhere.

In other words, when the sftp user logs in, I don't want them to have to cd to another path in order to upload a file.

Due to the chroot directory requiring full root ownership (due to chroot design), I'm not certain if this is even possible.

In /etc/passwd:

sftpuser:x:1006:1006:,,,:/home/sftpuser:/bin/false

The users login pubkey is in:

/home/sftpuser/.ssh/authorized_keys

Chroot rules in sshd_confg:

Match User sftpuser
    ChrootDirectory /home/sftpuser
    ForceCommand internal-sftp
    AllowTCPForwarding no
    X11Forwarding no

Home dir permissions:

# ls -l /home/ |grep sftpuser
drwxr-xr-x 5 root      root     4096 May  4 11:24 sftpuser

# ls -l /home/sftpuser/
total 4
drwxrw-r-x 3 sftpuser sftpuser 4096 May  4 11:23 sftp_share

Example current workflow:

Connected to sftp.example.com.
sftp> ls
sftp_share

sftp> put testfile.txt
Uploading testfile.txt to /testfile.txt
remote open("/testfile.txt"): Permission denied

sftp> cd sftp_share

sftp> put testfile.txt
Uploading testfile.txt to /sftp_share/testfile.txt
testfile.txt

Desired workflow:

Connected to sftp.example.com.
sftp> put testfile.txt
Uploading testfile.txt to /testfile.txt
testfile.txt

Is there any way to allow the upload (put) to the default directory, without having to chdir first?

I do have flexibility to move these directories around. For example, the sftp chroot dir doesn't have to be in the users home directory, I can even change around the users home dir (but the user must still be able to use authorized_keys to login).

Please note: I do understand many SFTP clients, and the command line SFTP client allows for defining a relative path at login. That is out of scope for this question, I'm desiring this config be done server-side and the client simply just needs to login.


Solution 1:

Hey @emmdee It took me forever to realize there is a simple and nice trick to that. You just have to make root the owner of a parent folder to where you wanna sFTP, then use force command to tell a specific user to load a specific DIR inside the CHROOT directory.

In your case in case you want /home/sftpuser to be the writtable directory, you will have to make root the owner of /home directory then go ahead and Force Command he /sftpuser as a landing directory for that user or a group.

Your /etc/ssh/sshd_conf will look like this:

Match User sftpuser
    ChrootDirectory /home
    ForceCommand internal-sftp -d /sftpuser
    AllowTCPForwarding no
    X11Forwarding no

Once that is done you have to give the right permissions as said earlier, the root should own the parent(chroot) directory /home while the user should own the final(-d) directory /sftpuser. I am goin to assume that you have an sFTP users group called sftpusers, if not; just ommit the group from the next commands or replace it with the users instead (root in the first and sftpusers in the second). As we are using -R in the command line for inheritance, you will have to start with the root ownership before the user ownership as follows:

sudo chown -R root:sftpusers /home

then for the user you can run:

sudo chown -R sftpuser:sftpusers /home/sftpuser

I am not certain that this is needed but you can always restart sshd service to make sure that all settings are reloaded again:

sudo systemctl restart sshd.service

This should work like a charm hopefully, I had a similar problem and the solution was there looking at me in the eyes most of the time.

Cheers!

Solution 2:

I know its been a couple of years, but this post got me 98% of the way there. after searching for a long time.

To make it so that I can have users chrooted and automatically get them into their own directory with write permissions I used the method that African Idiot suggested, and also made the original chroot directory owned by root user and the ftp group.

But the key for me to keep them in that folder and not be able to .. and attempt to browse other users' folders, was to make the folder chmod 710 (rwx--x---) so that the ftp group had execute to do the internal-sftp -d /%u (ie cd into the users subdirectory) and now if I attempt to cd .. into the upper directory, because there's no read for anyone but root, it fails.

drwx--x---  6 root        sftpusers   uarch  6 Feb 19 15:34 ./
drwxr-xr-x  5 root        root        uarch  5 Feb  4 09:13 ../
drwxrwx---  3 anotheruser anotheruser uarch  3 Feb 24 15:34 anotheruser/
drwxrwx---  3 ftpuser     ftpuser     uarch 12 Feb 25 10:55 ftpuser/

hope this helps someone else too.