CentosChrootedSftp

How to configure a chrooted sftp on Centos

This is a rather frequent request: allow users to drop files in web directory through sftp, but do not allow them to connect through ssh or to browse the server file system.

It's not that hard, but it takes a lot of reading and testing.

So, without further ado, here is how to do it on a Centos 6 machine - most of what I show below can also be applied to Red Hat and other Linux. Do spend some time in the See Also section below for more information.

PLEASE NOTE Whatever you do, do not apply the following to your administrator account! ;-)

1. Disable SE Linux:

Let's face it SE Linux is a piece of ____, and probably an NSA backdoor anyway... Get rid of it! ;-)

This is how your SE Linux configuration should look like:

# less /etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled                                                         <--- That's the line you want!
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 

Now, reboot your machine, and double-check with the following command:

# sestatus -v
SELinux status:                 disabled

Whew! SE Linux is now completely disabled. You can proceed with the rest of the instructions shown below.

If you'd like to keep SE Linux on your server, please refer to the ''See Also'' section below for a more detailed explanation on how to create a rule within SE Linux to allow chrooted sftp.

2. Update your SSH configuration:

Change the following in the file /etc/ssh/sshd_config:

# override default of no subsystems
Subsystem       sftp    internal-sftp

And add the following at the end of the file:

# #########################################################
# #
# # CONFIG SSHD CHROOT FOR USER SURFER
# #
# #########################################################

Match Group sftponly
	ChrootDirectory %h
	AllowTcpForwarding no
	X11Forwarding no
	ForceCommand internal-sftp 

3. Modify the user configuration

If we have a user named ''surfer'', let's change its login shell to /sbin/nologin as follows:

# grep -i surfer /etc/passwd
surfer:x:496:496:Silver Surfer Account:/home/surfer:/sbin/nologin

The above means that, whenever surfer connects to the Centos server, he/she will only be able to use sftp to transfer files.

Make sure surfer belongs to the sftponly group we mentioned in the ssh configuration:

# grep -i sftponly.*surfer /etc/group
sftponly:x:502:surfer

Don't forget to create the sftponly group if it does not exist on your machine!

# groupadd sftponly

Finally, apply the chrooting to its user home directory:

# chown -Rv root:sftponly /home/surfer
# chmod -Rv u+rwx,g-w,o-rwx /home/surfer

The correct permissions on /home/surfer should be the following:

# ls -dalhF /home/surfer
drwxr-x--- 6 root sftponly 4.0K Feb 11 16:51 /home/surfer

Now, surfer is not allowed to connect except through sftp, and cannot get out of its /home... What a good start!

4. Create the directory for writing:

Create it directly in /home/surfer:

# mkdir -v /home/surfer/web
mkdir: created directory `/home/additiv/web'

Mount the target directory in the home (check the permissions first):

# mount --bind /var/www/html/cms/surfer /home/surfer/web

Make that mount operation permanent in /etc/rc.local:

# #########################################################
# #
# # CONFIG SFTP CHROOT
# #
# #########################################################
mount --bind /var/www/html/cms/surfer /home/surfer/web

5. Restart the ssh server:

Theoretically, everything should be OK and the user should be able to read its /home and write into web:

gil@GALINUX:~> sftp surfer@192.168.0.220
surfer@192.168.0.220's password: 
Connected to 192.168.0.220.
sftp> ls
web  
sftp> cd web
sftp> ls
world_domination
sftp> put TARGET_LIST
Uploading TARGET_LIST to /web/TARGET_LIST
TARGET_LIST                                                                                          100%   78     0.1KB/s   00:00    
sftp> ls
TARGET_LIST                               world_domination            
sftp> rm TARGET_LIST
Removing /web/TARGET_LIST
sftp> quit

As you can see above, surfer can sftp into its directory, enter the web directory and put a file there, then delete it.

Takes a little while, but it's worth it.

IMPORTANT

If you get messages such as:

sftp> cd subdir
Couldn't canonicalise: Permission denied

Check the owners and permissions - they should be as shown above!!

Hope this helps!

See Also: