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.
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
This configuration requires:
- create a group designated to be chrooted
- add users to the group and deny the user shell access
- create user home directories
- 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/groupsftpusers: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
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
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/useridThe 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 peerThis 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 deniedThis 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>
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
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 varNote 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.
Man pages:
- Sshd configuration file: /etc/sshd_config
- Add a group: groupadd
- Add a user: useradd
- Modify a user: usermod
- SELinux assignment - chroot home directory setting: setsebool