I have configured sshd_conf on my centos box as below:

Match group pilots
ChrootDirectory /home/pilots
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no

and the directory /home/pilots like this:

# ls -al /home/pilots
total 12
drwxr-x---. 3 root pilots 4096 Mar 10 14:20 .
drwxr-xr-x. 7 root root     4096 Mar 10 14:10 ..
drwxrwxr-x. 2 root pilots 4096 Mar 10 15:21 data
-rwxrwxrwx. 1 root root        0 Mar 10 14:20 topLevel

If I sftp in as a user in the pilots group WITHOUT the ChrootDirectory Directive enabled, I can cd to the /home/pilots folder (or a subdirectory thereof) and do a ls or get without difficulty. However, if I enable the ChrootDirectory directive, while I can still sftp in, and can cd to data, I can not do a ls or get in either directory. Trying ls, for example, gives a remote readdir("/"): Permission denied error, and trying to get topLevel gives File "/topLevel" not found. I was thinking maybe I wasn't in the directory I was expecting, but the ability to cd data would appear to indicate the chroot did work as intended.

looking at the messages log, I see the following when the ls is denied:

type=1400 audit(1394494944.504:50): avc:  denied  { read } for  pid=22758 comm="sshd" name="pilots" dev=dm-0 ino=400504 scontext=unconfined_u:system_r:chroot_user_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=dir

So there's a record of the denial. Still doesn't tell me why though.

What might I be doing wrong?

Couple of potentially important notes:

  • The users in question exist on a remote LDAP server, accessed via sssd
  • Access control must be by group, as many users will need read access to this same folder. Thus the ownership remaining root.

Edit: On further investigation, it appears this is related to SELinux - doing an echo 0 >/selinux/enforce fixes the issue, albeit in a kludgy, killing an ant with a sledgehammer kind of way. If possible, I'd like to know the "proper" fix.


I found the solution on this page. To summarize, after configuring sftp as per the above configuration, the following two commands needed to be run to allow access with SELinux enabled:

setsebool -P ssh_chroot_rw_homedirs on
restorecon -R /home/$USERNAME

In this case, the second command would be restorecon -R /home/pilots. After this, sftp works as expected, even when chrooted, without having to disable SELinux completely.

  • Unfortunately, this didn't work for me; but disabling SELinux allows it to work. – Matthew Moisen Apr 13 '16 at 5:41
  • 1
    Disabling SELinux should never be a "fix" for configuration issues. – a coder Aug 19 '16 at 16:42
  • This answer (and the supplied link) was helpful - thanks. Just in case the referenced page becomes unavailable, I will repost it as an answer here (acknowledging yours as the correct answer for the question). – a coder Aug 19 '16 at 17:35

Tailing off of @ibrewster's answer (including the external resource he linked to), here is the full set of instructions from that external page, with some added information to make this work with passwordless login and SELinux enforcing.

Reposting here in case the externally linked page happens to go away in the future.

These instructions apply to RHEL7 and CentOS7 (and perhaps other releases):

On the remote system:

First, add and configure the user account to be chrooted:

Note that the external resource used a different path for sftp-server. Be sure you have the correct path on your system or prepare yourself for pain. ;-) The path below works for a minimal install of RHEL7 & CentOS7.

# From command line:

groupadd sftponly    
useradd -d /home/$USERNAME -s /usr/libexec/openssh/sftp-server -M -N -g sftponly $USERNAME
mkdir -p /home/$USERNAME/uploads /home/$USERNAME/downloads /home/$USERNAME/.ssh
chown $USERNAME:sftponly /home/$USERNAME/uploads /home/$USERNAME/downloads /home/$USERNAME/.ssh
chown root /home/$USERNAME
chmod 755 /home/$USERNAME
chmod 700 /home/$USERNAME/.ssh
passwd $USERNAME
echo '/usr/libexec/openssh/sftp-server' >> /etc/shells

While I've set a password above, I will use passwordless login once I know the config works. Onward...

Assuming you have SELinux enabled and enforcing (you should), issue these commands to make it happy:

setsebool -P ssh_chroot_rw_homedirs on
restorecon -R /home/$USERNAME

Now, edit the sshd config as follows:

[root@remote]# vi /etc/ssh/sshd_config
# CHANGE lines: 

# override default of no subsystems
#Subsystem      sftp    /usr/libexec/openssh/sftp-server    # commented out
Subsystem sftp internal-sftp                    # added

# ADD the following at the bottom: 

Match group sftponly
ChrootDirectory %h
AllowTcpForwarding no
ForceCommand internal-sftp

Finally, restart sshd

[root@remote]# systemctl restart  sshd.service

On the client system

First create the same account locally.

[root@client]# useradd -m $USERNAME
[root@client]# passwd $USERNAME
[root@client]# su $USERNAME

Ok now let's set up our RSA key pair.

[$USERNAME@client]# ssh-keygen

I wasn't able to get ssh-copy-id to work with the chroot config above, so I manually created the authorized_keys file with my client's id_rsa.pub text.

[$USERNAME@client]# cat .ssh/id_rsa.pub
---some key here---

Then back on the REMOTE system,

[root@remote]# vi /home/$USERNAME/.ssh/authorized_keys
---past key from right above, then wq---

Don't forget to set permissions on this file:

[root@remote]# chown $USERNAME:sftpusers  /home/$USERNAME/.ssh/authorized_keys

Ready to test

Everything should be in place now. From the client:

[$USERNAME@client]# sftp $USERNAME@remote

This should get you in. If you are prompted for a password (we haven't disabled PasswordAuthentication on the remote just yet), you have a configuration problem on the remote system. Scan your /var/log/secure for details.

If you sign on without being prompted for a password, you're almost finished.

Back on the remote system:

[root@remote]# vi /etc/ssh/sshd_config
# disable PasswordAuthentication
PasswordAuthentication no

# or optionally, just comment that line out

# PasswordAuthentication no
-- save and exit with :wq --

Restart sshd on the remote system:

[root@remote]# systemctl restart  sshd.service

Final test from Client

[$USERNAME@client]# sftp $USERNAME@remote
# in like Flynn?  yay!


You should be set to go with chroot sftp and passwordless login (with SELinux set to enforcing)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.