In the past, if I wanted to create a restricted account for a user, to upload files via scp/sftp for example, I normally setup rbash with a defined set of commands. However, it’s possible to break out of an rbash environment quite easily.

Recently, whilst setting up an account for one of the Eirtakon guys to modify their drupal install, I decided to give scponly a whirl. This is a restricted shell that, as the name implies, only allows access to scp and sftp. It also provides a chroot mode (scponlyc) to lock users into a specified directory hierarchy, which I configured for this particular user.

Installation on Debian is simple:

 aptitude install scponly

To enable the chrooted version of scponly, do:

dpkg-reconfigure -plow scponly

Unzip the chroot setup script and make it executable

cd /usr/share/doc/scponly/setup_chroot
gunzip setup_chroot.sh.gz
chmod 755 setup_chroot.sh

If you are on a 64 bit system, scponly is basically broken out of the box. You need to do a couple of things to make it work, the first is to apply this diff to setup_chroot.sh, it adds /lib/ld-2.7.so to the LDSO_LIST variable.

--- setup_chroot.sh     2010-03-24 18:53:15.000000000 +0000
+++ setup_chroot.sh.busted      2010-03-24 18:52:24.000000000 +0000
@@ -79,7 +79,7 @@
 #
 #      we also need to add some form of ld.so, here are some good guesses.
 #
-LDSO_LIST="/lib/ld-2.7.so /lib/ld.so /libexec/ld-elf.so /libexec/ld-elf.so.1 /usr/libexec/ld.so /lib/ld-linux.so.2 /usr/libexec/ld-elf.so.1"
+LDSO_LIST="/lib/ld.so /libexec/ld-elf.so /libexec/ld-elf.so.1 /usr/libexec/ld.so /lib/ld-linux.so.2 /usr/libexec/ld-elf.so.1"
 for lib in $LDSO_LIST; do
        if [ -f $lib ]; then
                LDSOFOUND=1;

You can now run the setup script

 ./setup_chroot.sh

This creates a chrooted user and sets up the necessary environment.

Now set up /dev/null:

 cd ~scponlyuser
 mkdir dev
 cp -a /dev/null dev/

For a 64 bit system, you need to copy across a few more supporting libraries into the chroot:

 cd ~scponlyuser
 cp -p /lib/libncurses.so.5 lib/
 cp -p /lib/libncurses.so.5 lib/
 cp -p /lib/libdl.so.2 lib/
 cp -p /lib/libc.so.6 lib/
 mkdir lib64
 cp -p /lib64/ld-linux-x86-64.so.2 lib64/

To restrict the user to only the path I want them to see, I set their home directory to /home/scponlyuser//drupal. The // has the effect of dropping them into that particular directory once they get chroot’ed, which is /drupal in the chroot environment.

I also wanted to let them have access to /var/www/eirtakon.com/drupal, but without symlinks or other nonsense. This can be done with the bind option in mount:

 mount -o bind /var/www/eirtakon.com/drupal /home/scponlyuser/drupal

To test it out

 sftp scponlyuser@longcat.spoofedpacket.net