7

I am in the process of setting chroot for sftp and have used a combination of tutorials (source1, source2) and have ended up with the following configuration in /etc/ssh/sshd_config:

Match Group sftpusers
      ForceCommand internal-sftp
      ChrootDirectory /var/sftp/
      PermitTunnel no
      AllowAgentForwarding no
      AllowTcpForwarding no
      X11Forwarding no

The sftp base folder is /var/sftp and the user was created as follows:

groupadd sftpusers

adduser myuser01
mkdir -p /var/sftp/myuser01
usermod -a -G sftpusers myuser01
chown myuser01:myuser01 /var/sftp/myuser01
systemctl restart sshd

Now when I try a login I end up in the /var/sftp folder, which demonstrates login works.

Since I want users to end up in the /var/sftp/<userid> folder, I try setting the following config is sshd_config, under the Match Group line :

ChrootDirectory /var/sftp/%u

When I do that I get an error client_loop: send disconnect: Broken pipe on a login attempt. According to the man page for ssh_config the variable should be accepted, per:

ChrootDirectory accepts the tokens %%, %h, and %u.

Any ideas?

Env:

  • OS: Ubuntu 18.04.4 LTS
  • sshd: OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017

4 Answers 4

12
chown myuser01:myuser01 /var/sftp/myuser01
...
ChrootDirectory /var/sftp/%u

The OpenSSH SSH server's ChrootDirectory directive requires that the chroot directory and its parent directories be owned by root:

ChrootDirectory
Specifies the pathname of a directory to chroot(2) to after authentication. At session startup sshd(8) checks that all components of the pathname are root-owned directories which are not writable by any other user or group. After the chroot, sshd(8) changes the working directory to the user's home directory.

I haven't tested this, but I think that if you create a /etc/passwd file within the chroot environment, containing a line for the user in question, then sshd will honor the home directory field in that line as the user's home directory within the chroot environment. If this actually works, then you could use this to have the user's session start with its working directory somewhere other than the chroot directory.

7
  • Both /var & /var/sftp are owned by root
    – Andre M
    Jul 15, 2020 at 14:21
  • 1
    /var/sftp/myuser01 is the directory that you're trying to use as the chroot directory, and it's not owned by root.
    – Kenster
    Jul 15, 2020 at 14:22
  • Changing ownership to root changes the login issue, but now the user can't upload a file, since they don't own the folder. What do I deal with that one?
    – Andre M
    Jul 15, 2020 at 14:34
  • 1
    You create directories within the chroot directory with permissions/ownership that allow the user to create files.
    – Kenster
    Jul 15, 2020 at 15:18
  • ok, so I just created an 'uploads' folder with ownership on the user and that works - thanks, though it does mean you example is probably not correct. The chown there would need to be root, with a folder inside belonging to the user.
    – Andre M
    Jul 15, 2020 at 16:03
3

In your example, /var/sftp and /var/sftp/usero1 needs to be owned by root and not writable by any other user

your issue is likely that you did this:

chown myuser01:myuser01 /var/sftp/myuser01

instead it should be owned by root:root and chmod 755

sudo mkdir /var/sftp
sudo mkdir /var/sftp/myuser01
sudo chown -R root:root /var/sftp
chmod -R 755 /var/sftp

Now that the user directory is owned by root:root and not writable by others, your user should be able to be logged into it and chrooted via the sshd internal-sftp

ForceCommand internal-sftp
ChrootDirectory /var/sftp/

So, to put it all together:

sudo groupadd sftpusers

sudo mkdir /var/sftp
sudo mkdir /var/sftp/myuser01
sudo chown -R root:root /var/sftp
chmod -R 755 /var/sftp

sudo adduser -h /var/sftp/myuser01 myuser01
sudo usermod -a -G sftpusers myuser01

edit your /etc/ssh/sshd_config and add this to the end:

Match Group sftpusers
      ForceCommand internal-sftp
      ChrootDirectory /var/sftp/%u
      PermitTunnel no
      AllowAgentForwarding no
      AllowTcpForwarding no
      X11Forwarding no

Then after saving restart sshd

systemctl restart sshd

My issue with this was that it meant that the user "myuser01" would not have any write access to their base directory... so in my case this isn't too bad - I actually needed "myuser01" to have a www directory which they needed access to - I solved this by

sudo mkdir /var/sftp/myuser01/www/
sudo chown myuser01:myuser01 /var/sftp/myuser01/www/

(changed names to follow your naming convention here)

This will work if all you want is to make an SFTP chroot jail for that user - they will only be able to use SFTP but you don't need to go and build a whole chrooted set of commands and libs for them to use... Otherwise you need to go and add the needed commands to their bin directory as well as needed libs to their /lib directory, and I think a local copy of /etc/passwd and /etc/group with the needed group and user entries (I've not tested this myself yet as I just needed an SFTP chroot jail)

3
  • This is the REAL answer. chroot directory will NOT work if is owned by user, needs to be owned by root. Dec 21, 2022 at 13:28
  • what is -h switch for in adduser command? seems typo Mar 3 at 21:44
  • khalidmehmoodawan The -h is for home directory. I'll admit it was a while ago when I wrote this and perhaps it was a typo - you could use --home in place of my -h Mar 6 at 21:18
0

The ChrootDirectory must contain the necessary files and directories to support the user's session. For an interactive session this requires at least a shell, typically sh(1), and basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4), and tty(4) devices. For file transfer sessions using SFTP no additional configuration of the environmentis necessary if the in-process sftp-server is used, though sessions which use logging may require /dev/log inside the chroot directory on some operating systems (see sftp-server(8) for details).

0

The following worked for me. Below is just an example.

  • Edit /etc/ssh/sshd_config and modify and enable this line as below
    Subsystem sftp internal-sftp
    
  • Then go to end of file (or modify if already existing). SFTP base folder will be /home/sftp
    Match Group sftpusers
        ChrootDirectory /home/sftp
        ForceCommand internal-sftp
        X11Forwarding no
        AllowTcpForwarding no
    
  • Save the file and restart ssh service
    systemctl restart sshd
    

Then execute the following commands. sftpuser will be our user; sftpusers will be our group, so in future

  • just create new user for SFTP and add to sftpusers.
    useradd -d /home/sftp -s /bin/false -g users -G sftpusers sftpuser
    
  • set the password of sftpuser
    passwd sftpuser
    
  • execute the following lines
    chown root:root /home/sftp
    #rights for group & others chmod go+rx /home/sftp
    mkdir /home/sftp/{upload,download}
    chown sftpuser:users /home/sftp/{upload,download}
    chown sftpuser:sftpusers /home/sftp/{upload,download}
    

Now, you can verify SFTP from any remote server or SFTP client:

sftp [email protected]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .