1. Home
  2. Tutorials
  3. Chroot sFTP
Yolinux.com Tutorial

sFTP Server Chroot Configuration

This sFTP tutorial covers the configuration required to chroot a user to a home directory for sFTP sessions and deny the user a shell account.

Description:

This configuration will allow a system user to access their home directory using sFTP and to upload and download files with their account. The user will be denied access to the rest of the system as they will be chrooted to the user home directory. Thus users will not be able to snoop around the system to /etc or application directories. User login to a shell account will also be denied.

The ability to chroot an sshd session of sftp has been available since OpenSSH 4.9. This is available with Red Hat Enterprise Linux 6 and Fedora 11 (and later) with OpenSSH 5.1. Ubuntu 11.04 uses OpenSSH 5.8.

Installation:

RHEL 6 packages:
  • openssh-5.3p1-81.el6
  • openssh-clients-5.3p1-81.el6
  • openssh-server-5.3p1-81.el6
  • openssh-askpass-5.3p1-81.el6
  • libssh2-1.2.2-7.el6_2.3
Install: rpm -ivh openssh-5.3p1-81.el6...rpm openssh-clients-5.3p1-81.el6...rpm openssh-server-5.3p1-81.el6...rpm ...

Configuration:

This configuration requires:
  1. create a group designated to be chrooted
  2. add users to the group and deny the user shell access
  3. create user home directories
  4. the ssh daemon will be configured to chroot users of a group designated to be chrooted

1) Define a group of which members will be chrooted:

This is a standard Linux group assignment. The group name is user definable.

Define a group: groupadd sftpusers

Groups are defined in the file /etc/group
sftpusers:x:1002:

2) Add users to the group and deny users shell access:

A non-working shell can be assigned to a user to prevent shell access. Linux includes two shells for this purpose:
  • /sbin/nologin
  • /bin/false
User accounts can be modified after creation: usermod -s /bin/false -g sftpusers userid

The shell can be assigned to a user upon user account creation: useradd -s /bin/false -G sftpusers userid

The user group and shell assignment can be edited in the file /etc/passwd:
From: user1:x:1000:1000:George,,,:/home/user1:/bin/bash
To: user1:x:1000:1002:George,,,:/home/user1:/bin/false

File: /etc/group
Adding users to the "sftpusers" group will have the following results:
sftpusers:x:1002:user1,user2

3) Create user home directories:

The typical user home directory is /home/userid
The use of chroot requires a new root which is not "/". In this configuration we will use /home/sftpusers. All user home directories will have their true physical paths added to the rooted path at /home/sftpusers. Thus the true physical paths will be /home/sftpusers/home/userid but will appear to the user to be at /home/userid

The user "root" must own the rooted directory: chown root.root /home/sftpusers

The user "root" should own the rooted home directory: chown root.root /home/sftpusers/home

The user will own their home path: chown userid.sftpusers -R /home/sftpusers/home/userid

Set appropriate permissions: chmod 755 /home/sftpusers/home/userid/

Tip: Set SELinux rules on home directory: setsebool -P ssh_chroot_rw_homedirs on

4) SSH daemon configuration to chroot a user group:

Edit the sshd configuration file: /etc/ssh/sshd_config
(partial file shown)
...
...

#UsePAM no
UsePAM yes
UsePrivilegeSeparation yes
StrictModes yes
PermitEmptyPasswords no

# change default
# Subsystem     sftp    /usr/libexec/openssh/sftp-server
Subsystem       sftp    internal-sftp

Match Group sftpusers 

ChrootDirectory /home/sftpusers
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

[Potential Pitfall]: You may get the following error:

[user1]$ sftp user1@sftp.megacorp.com
Connecting to 192.121.121.1...
user1@sftp.megacorp.com's password: 
Write failed: Broken pipe
Couldn't read packet: Connection reset by peer
This is typically due to a miss-configuration: Note that sshd will reject sftp connections to accounts that are set to chroot into any directory that has ownership/permissions that sshd doesn't consider secure.

[Potential Pitfall]: You may get the following error:

sftp> put example.sql
Uploading example.sql to /home/user1/example.sql
Couldn't get handle: Permission denied
This is typically due to a directory permissions problem:
/home/sftpusers - owned by root. This will be chrooted.
/home/sftpusers/home - owned by root.
/home/sftpusers/home/user1 - owned by user

After sshd has chrooted to the ChrootDirectory, it will chdir to the home directory as normal.

5) Apache httpd access to user directories:

Note that the httpd web server process will view the user directory from a global perspective and not from a chrooted perspective. Thus reference the full global directory paths. Also note that the default "public_html/" configuration will not work as the user's home directory as defined by /etc/passwd is a chrooted perspective. Shown below is an alternate configuration to solve the "public_html/" dilemma.

Sample httpd configuration file: /etc/httpd/conf.d/megacorp.conf
(partial file shown)
...
<VirtualHost *:80>
  ServerName   www.megacorp.com
...
...
...
   Alias "/user1/" "/home2/sftpusers/home/user1/public_html/"
   <Directory "/home2/sftpusers/home/user1/public_html/">
      Options Indexes MultiViews FollowSymLinks
      AllowOverride All
      Order allow,deny
      allow from all
      Require all granted
   </Directory>
</VirtualHost>
Refer to the users area not via the URL http://www.megacorp.com/~user1/ but by http://www.megacorp.com/user1/

Chrooting individual users:

Example sshd configuration file: /etc/ssh/sshd_config

(partial file shown)
...
...

#UsePAM no
UsePAM yes
UsePrivilegeSeparation yes
StrictModes yes
PermitEmptyPasswords no

Subsystem       sftp    internal-sftp

Match User userx,usery

ChrootDirectory /home/sftpusers
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
Note: This configuration specified a single or comma separated list of users.

Pitfalls:

Always test out a new user's login to make sure the login is functional and chrooted. If you login and see the root file system for a new user you had just added, you know something is wrong!

$ sftp user1@www.domain.com
user1@www.domain.com's password: 
Connected to www.domain.com.
sftp> ls
bin          boot         cgroup       dev          etc          home         home-bak     lib          
lib64        local        lost+found   media        mnt          opt          proc         root         
run          sbin         selinux      srv          sys          tmp          usr          var 

This may be the result of the user not registering as one to be chrooted. Either the user is not in the proper group or the user is not properly configured or registered with sshd.

If it is not the configuration which is in error then it is the sshd daemon process which has not registered the new changes. This can be fixed by re-starting sshd:
sudo service sshd restart

Now the login should look like this:

$ sftp user1@www.domain.com
user1@www.domain.com's password: 
Connected to www.domain.com.
sftp> ls
css          fonts        img          index.html   js
sftp> cd /
sftp> ls
home  var
Note that file protection and umask should NOT allow group (sftpusers) write. If this is a web hosting account, note that the web server runs under user name apache and requires read access to the files served.
  • umask 077 : only user has read/write access. All others have no access.
  • umask 022 : only user has read/write access. All others have read access.
  • umask 002 : only user and group members have read/write access. All others have read access.

Links:

Man pages:

Books:

Amazon book image "Fedora 14 Administration and Security"
by Richard Petersen
Surfing Turtle Press, ISBN# 1936280221
(Jan 6, 2011)

Amazon.com
Amazon book image "Fedora 14 Networking and Servers"
by Richard Petersen
Surfing Turtle Press, ISBN# 1936280191
(Dec 26, 2010)

Amazon.com