Restricting Users To SFTP Plus Setting Up Chrooted SSH/SFTP (Debian Squeeze)

Version 1.0
Author: Falko Timme
Follow me on Twitter

This tutorial describes how to give users chrooted SSH and/or chrooted SFTP access on Debian Squeeze. With this setup, you can give your users shell access without having to fear that they can see your whole system. Your users will be jailed in a specific directory which they will not be able to break out of. I will also show how to restrict users to SFTP so that they cannot use SSH (this part is independent from the chroot part of this tutorial).

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

I will use the user falko here with the home directory /home/falko. The user falko belongs to the group users. I want to chroot the user to the /home directory.

 

2 Installing OpenSSH

If OpenSSH is not already installed, install it as follows:

apt-get install ssh openssh-server

 

3 Enabling Chrooted SFTP

Enabling SFTP is very easy. Open /etc/ssh/sshd_config...

vi /etc/ssh/sshd_config

... and make sure you have the following line in it:

[...]
Subsystem sftp internal-sftp
[...]

Then add the following stanza at the end of the file (add such a stanza for each user that you want to chroot):

[...]
Match User falko
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand internal-sftp

Instead of adding a stanza for each user, you can also chroot groups, e.g. as follows:

[...]
Match Group users
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand internal-sftp

This would chroot all members of the users group to the /home directory. Please note that all components of the pathname in the ChrootDirectory directive must be root-owned directories that are not writable by any other user or group (see

man 5 sshd_config

). That's why we cannot specify /home/falko, for example, because it is not owned by the user and group root.

Restart OpenSSH:

/etc/init.d/ssh restart

If you chroot multiple users to the same directory, but don't want the users to browse the home directories of the other users, you can change the permissions of each home directory as follows:

chmod 700 /home/falko

Afterwards, you can log in with an SFTP client, such as FileZilla or WinSCP.

Please note that at this point where you have not set up chrooted SSH yet (see the next chapter), the users/groups that you have specified in /etc/ssh/sshd_config will only have SFTP access. SSH will not work for these users because an SSH chroot environment needs some additional files to work (and because we use ForceCommand internal-sftp).

 

4 Enabling Chrooted SSH

Enabling chrooted SSH is a bit more complicated because we must set up a chroot environment with all programs/tools (e.g. /bin/bash, /bin/cp, etc.) that the users should be able to use. This means we must also copy all libraries that these programs need to the chroot jail. You can do this manually with the cp command, and you can find out what libraries a tool needs by using the ldd command, e.g.

ldd /bin/bash

We also have to create some devices such as /dev/null, /dev/zero, /dev/tty, and /dev/urandom inside the chroot jail with the mknod command.

However, this can be a tedious task. Fortunately, there's a script that can do this for us.

First, we need to install some prerequisites:

apt-get install sudo debianutils coreutils

Then we download make_chroot_jail.sh to /usr/local/sbin and make it executable for the root user:

cd /usr/local/sbin
wget http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/make_chroot_jail.sh
chmod 700 /usr/local/sbin/make_chroot_jail.sh

Before we use the script, you might want to add some programs (e.g. such as /usr/bin/vi) to the APPS line of your distribution in that script so that these tools get added to the chroot jail automatically:

vi /usr/local/sbin/make_chroot_jail.sh
[...]
elif [ "$DISTRO" = DEBIAN ]; then
  APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/bin/vi"
else
[...]

Next we add a symlink /home/home that points back to /home:

cd /home
ln -s . home

Now we can already use the script. Usage is as follows:

make_chroot_jail.sh username [/path/to/chroot-shell [/path/to/chroot]]

chroot-shell is a special shell created by the script to chroot users. Since OpenSSH now supports chrooting by default, we don't need the script to create a special shell; instead, we can use /bin/bash or /bin/sh.

It doesn't matter if the user is already existing or not. If he's existing, he will be updated; if not, he will be created.

make_chroot_jail.sh falko /bin/bash /home

This will create/update the user falko with the chroot jail /home.

To update all files/libraries in the chroot jail, run

make_chroot_jail.sh update /bin/bash /home

Now we need to configure OpenSSH which is similar to the SFTP configuration. Open /etc/ssh/sshd_config...

vi /etc/ssh/sshd_config

... and add the following stanza at the end of the file (add such a stanza for each user that you want to chroot):

[...]
Match User falko
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no

Instead of adding a stanza for each user, you can also chroot groups, e.g. as follows:

[...]
Match Group users
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no

This would chroot all members of the users group to the /home directory.

The difference to the SFTP configuration is that this time, we must not use the line ForceCommand internal-sftp in the Match stanzas! This makes that users can still use chrooted SFTP (provided you also have the line Subsystem sftp internal-sftp in /etc/ssh/sshd_config), but also chrooted SSH.

Restart OpenSSH:

/etc/init.d/ssh restart

If you chroot multiple users to the same directory, but don't want the users to browse the home directories of the other users, you can change the permissions of each home directory as follows:

chmod 700 /home/falko

Afterwards, you can log in with with an SSH client such as PuTTY.

 

5 Restricting Users To Using SFTP Only

This chapter is independent of chrooting, so it has nothing to do with the chapters 3 and 4 - this means you don't have to set up chrooting as described in chapters 3 and 4 to restrict users to SFTP (but if you have set up chrooted SFTP and SSH for a user and want to disable SSH afterwards, the method shown here works as well; if you have set up chrooted SFTP only, but not chrooted SSH, access is restricted to SFTP anyway as mentioned at the end of chapter 3).

It shows what you can do to make a user use SFTP only and disallow SSH usage for that user. All you have to do is change the user's login shell to /usr/lib/openssh/sftp-server ,e.g.:

usermod -s /usr/lib/openssh/sftp-server falko

/usr/lib/openssh/sftp-server must be listed in /etc/shells as a valid login shell, so if it isn't already listed, please add it to /etc/shells as follows:

echo '/usr/lib/openssh/sftp-server' >> /etc/shells

This has to be done only once, not for every user that you want to restrict to SFTP.

 

Share this page:

Suggested articles

12 Comment(s)

Add comment

Comments

By: Anonymous

Hello Falko,

I actually have tried this script "make_chroot_jail.sh" and others (jailkit) to enable chroot ssh only recently before your post. I want to share something here. For "make_chroot_jail.sh" on Debian or Ubuntu, it won't work if you just get that script without any change.

1. You should see such error like:

 ./make_chroot_jail.sh: 428: cannot create : Directory nonexistent

 Please see here how to resolve it:

 http://ubuntuforums.org/showthread.php?t=881562

2. If your system has only few software installed (like my testing machine, nothing but only ssh server install), you will see error like missing "/lib/libcap.so.1" when you do:

make_chroot_jail.sh falko /bin/bash /home

Because the basic Debian install (v6.0.2) didn't have libcap.so.1 at all. You may need to do "apt-get install libcap-dev" to have it, and "ln -s /lib/libcap.so.2 /lib/libcap.so.1" to make it work.

3. After fixing above two, I can remote ssh login, however, that ssh session will be closed immediately once I login. From /var/log/auth.log, it looks like "pam_unix(sshd:session)". If I disable UsePAM in "/etc/ssh/sshd_config", I got "Accept password from user..", but nothing and my connection is still closed without any log or error. I am still working on this.......:-(

Anyway, just my 2 cents for those people following the post & get a quick answer

Hsinan

By: Anonymous

It works also on Squeeze. Just look inside the script and take the appropriate actions, as noted by the author. In some Debian-System (in example 64bit installations) you have to comment in on the end of the script, the two lines mentioned. I can proof that the script works fine here. 

By: ivo

That method kill the connection to my headless server and keep me bussy for half a day, till I recover the damage.

By: Russ

In sshd_config

Match group vhost
  PasswordAuthentication yes
  ChrootDirectory /home/%u
  ForceCommand internal-sftp
  AllowTCPForwarding no

Will chroot them to their home directory rather than /home.

sftp only.

 

By: Paysofts

Hi,

after i did this, than i unable to login to my SSH via PuTTY. Plz advise..

By: huglester

Hello,

I'm running Debian Squeeze (64bit),
in order to fix problem: './make_chroot_jail.sh: 428: cannot create : Directory nonexistent'

I had to change shell in file make_chroot_jail.sh:

from:
#!/bin/sh

to:
#!/bin/bash

All problems solved.
Good luck!

By: Debiandit

Hello Falko,

I have tried your steps but it didn't worked out for me. I run a Debian 64-Bit Webserver with Virtualmin as control panel. I even installed libcap-dev and renamed #!/bin/sh to #!/bin/bash but it doesn't work. I tried it on exiting users and created new users as well. SSH works fine but the user can still access the root directory.

I have tried rbash for the users-accounts. It works great but the user can still list and view the files in the root folder. Is there any solution to offer full SSH-Access just for the user's home directory?

By: JohnnyOh

Thank you for the great Tutorial. It works except one thing:

 

does anyone have a solution for the last question? How can I deny the access for the chroot-user to / of the system? The user should stay in his chroot-area (/home/user) 

By: Vijay Gandla

I like to do jail break/chroot to an AD user or group, does it possible in this way??

By: Jimmy

Hi, the script doesn't crate the new user in the specified "users" group, it creates the user in the same group name as the user is called .

for example :

User Jimmy

Group users

it creates user jimmy, group Jimmy

How can I fix it ?

 

By: drakkan

You can also try SFTPGo

 

https://github.com/drakkan/sftpgo

 

it has chroot support builtin, virtual quota, atomic uploads, bandwidth throttling and many other features.

It can execute configurable custom commands and/or send HTTP notifications on upload, download, delete or rename.

It is written in Go, so no runtime dependencies, and it works on Windows too

By: Michael

Hi,

I got it working, but I have a problem with mc (midnight commander) - the function keys and arrown keys don't work. I've tried many things but can't get it to work. Any ideas?

Thanks,

Michael.