Unless otherwise noted, articles © 2005-2008 Doug Spencer, SecurityBulletins.com. Linking to articles is welcomed. Articles on this site are general information and are NOT GUARANTEED to work for your specific needs. I offer paid professional consulting services and will be happy to develop custom solutions for your specific needs. View the consulting page for more information.


SSH SFTP in a chroot environment

From SecurityBulletins.com

Jump to: navigation, search

By Doug Spencer ©2006 - Written 11/11/2006

This article was written to demonstrate how SFTP can be used in a chroot while allowing SSH connections to use a standard login. If you just want to run SSH and SFTP in a chroot environment, a derivative of "The easy way" will work fine.

The easy way:

  • Create a chroot environment
  • Copy sshd and sftp-server into the chroot environment
  • Set the chroot version of ssh to allow sftp and listen on a particular IP on the system
  • Disable sftp in the normal ssh

The more complicated way (this method uses one ssh config):

This article details how the Secure File Transfer Protocol, known as SFTP in Secure Shell can be run within a chroot environment, while allowing normal logins to occur outside the chroot.

Since the subsystem in SSH does not seem to allow additional parameters on its command line, we need to move the chroot command to a script similar to the following:

$ cat /usr/local/bin/chsftp 
#!/bin/bash

/usr/bin/sudo /usr/sbin/chroot /chroot/sftp /usr/lib/openssh/sftp-server 

Add an entry like the following to your sudoers by running visudo:

user ALL =(ALL) NOPASSWD: /usr/sbin/chroot /chroot/sftp /bin/bash -c /bin/su user -c /usr/lib/openssh/sftp-server

Next, you specify:

Subsystem sftp /usr/local/bin/chsftp

in sshd_config.

You will also need the libraries in the chroot:

 $ ldd /usr/lib/openssh/sftp-server
       linux-gate.so.1 =>  (0xffffe000)
       libresolv.so.2 => /lib/tls/libresolv.so.2 (0xb7ed4000)
       libcrypto.so.0.9.8 => /usr/lib/i686/cmov/libcrypto.so.0.9.8 (0xb7d9b000)
       libutil.so.1 => /lib/tls/libutil.so.1 (0xb7d97000)
       libz.so.1 => /usr/lib/libz.so.1 (0xb7d83000)
       libnsl.so.1 => /lib/tls/libnsl.so.1 (0xb7d6d000)
       libcrypt.so.1 => /lib/tls/libcrypt.so.1 (0xb7d3e000)
       libselinux.so.1 => /lib/libselinux.so.1 (0xb7d2a000)
       libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0xb7d0e000)
       libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0xb7c90000)
       libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0xb7c6b000)
       libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0xb7c66000)
       libcom_err.so.2 => /lib/libcom_err.so.2 (0xb7c62000)
       libc.so.6 => /lib/tls/libc.so.6 (0xb7b2a000)
       libdl.so.2 => /lib/tls/libdl.so.2 (0xb7b26000)
       libsepol.so.1 => /lib/libsepol.so.1 (0xb7ae7000)
       /lib/ld-linux.so.2 (0xb7f03000)

Additionally, /usr/lib/openssh/sftp-server needs to be copied into the chroot.

The following script should copy the required files to the chroot:

SFTP_LOCATION=/usr/lib/openssh/sftp-server # change this to your sftp location
CHROOTENV=/chroot/sftp # Change to your chroot location
cd / ; ldd ${SFTP_LOCATION} | cut -f2 -d\> | awk '{print $1}' | grep \.so | sed -e 's/^\///g' | xargs tar cf - ${SFTP_LOCATION} \
| ( cd ${CHROOTENV} && tar xvf - )

Be sure to copy in any files pointed to by symlinks if the any of the resulting library files are symlinks. Also copy the Pluggable Authentication Module libraries that are required in the chroot environment.

Here's the successful connection via SFTP to the chroot environment. I have also tested normal SSH connections go to the main/non-chroot environment.

$ sftp remotehost
Connecting to remotehost...
Password: 
sftp> ls
bin  dev  etc  lib  tmp  usr  
sftp>

Here are the files that I have in the chroot environment on a Debian Linux system. There are probably some excess files here that can be pared down for production use.

total 24
drwxr-xr-x 2 root root 4096 Nov 11 17:23 bin
drwxr-xr-x 2 root root 4096 Nov 11 18:35 dev
drwxr-xr-x 4 root root 4096 Nov 11 19:00 etc
drwxr-xr-x 4 root root 4096 Nov 11 18:08 lib
drwxr-xr-x 2 root root 4096 Nov 11 17:05 tmp
drwxr-xr-x 3 root root 4096 Nov 11 15:57 usr

./bin:
total 704
-rwxr-xr-x 1 root root 684724 Mar 22  2006 bash
-rwsr-xr-x 1 root root  25024 Nov 11 17:23 su

./dev:
total 0
-rw-rw-rw- 1 root root 0 Nov 11 02:00 null

./etc:
total 184
-rw-r--r-- 1 root root     1071 Oct 13  2005 bash.bashrc
-rw-r--r-- 1 root root      702 Aug 12 11:10 fstab
-rw-r--r-- 1 root root      814 Jun 12 21:48 group
-rw-r--r-- 1 root root       26 Sep 25  1995 host.conf
-rw-r--r-- 1 root root      886 Aug 20  2005 hosts
-rw-r--r-- 1 root root      677 Sep  5  2004 hosts.allow
-rw-r--r-- 1 root root      901 Sep  5  2004 hosts.deny
-rw-r--r-- 1 root src    103034 Nov 10 13:55 ld.so.cache
-rw-r--r-- 1 root src      1279 Apr 30  2006 localtime
-rw-r--r-- 1 root root    10684 Feb 22  2006 login.defs
-rw-r--r-- 1 root root      453 Nov 11 08:27 mtab
-rw-r--r-- 1 root root      465 Feb  9  2006 nsswitch.conf
drwxr-xr-x 2 root root     4096 Nov 11 19:00 pam.d
-rw-r--r-- 1 root root     1850 Jun 12 21:48 passwd
-rw-r--r-- 1 root root       96 Nov 11 08:00 resolv.conf
-rw-r----- 1 root shadow   1260 Jun 12 21:48 shadow
-rw-r--r-- 1 root root      222 Apr 30  2006 shells

./etc/pam.d:
total 28
-rw-r--r-- 1 root root  392 Sep  5  2004 common-account
-rw-r--r-- 1 root root  436 Sep  5  2004 common-auth
-rw-r--r-- 1 root root 1097 Sep  5  2004 common-password
-rw-r--r-- 1 root root  372 Sep  5  2004 common-session
-rw-r--r-- 1 root root  520 Aug 31  2003 other
-rw-r--r-- 1 root root  820 Jul 29  2004 ssh
-rw-r--r-- 1 root root 2232 May  4  2006 su

./etc/ssh:
total 124
-rw-r--r-- 1 root root 111892 Jul 29  2004 moduli
-rw------- 1 root root    668 Sep  6  2004 ssh_host_dsa_key
-rw------- 1 root root    883 Sep  6  2004 ssh_host_rsa_key

./lib:
total 824
-rwxr-xr-x 1 root root  92260 Apr 14  2006 ld-2.3.6.so
lrwxrwxrwx 1 root root     11 Nov 11 15:57 ld-linux.so.2 -> ld-2.3.6.so
lrwxrwxrwx 1 root root     17 Nov 11 15:57 libcom_err.so.2 -> libcom_err.so.2.1
-rw-r--r-- 1 root root   5792 Nov 11 16:35 libcom_err.so.2.1
-rw-r--r-- 1 root root 268204 Nov 11 17:06 libncurses.so.5
-rw-r--r-- 1 root root  30428 Apr 14  2006 libnss_compat-2.3.6.so
-rw-r--r-- 1 root root  30428 Apr 14  2006 libnss_compat.so.2
-rw-r--r-- 1 root root  30464 Nov 11 17:33 libpam.so.0
-rw-r--r-- 1 root root  30464 Nov 11 17:33 libpam.so.0.79
-rw-r--r-- 1 root root   8216 Feb  6  2006 libpam_misc.so.0
-rw-r--r-- 1 root root   8216 Feb  6  2006 libpam_misc.so.0.79
-rw-r--r-- 1 root root  75220 Mar 22  2006 libselinux.so.1
-rw-r--r-- 1 root root 211424 Mar 22  2006 libsepol.so.1
drwxr-xr-x 2 root root   4096 Feb 24  2006 security
drwxr-xr-x 2 root root   4096 Nov 11 16:35 tls

./lib/security:
total 380
-rw-r--r-- 1 root root 12056 Feb  6  2006 pam_access.so
-rw-r--r-- 1 root root  5132 Feb  6  2006 pam_debug.so
-rw-r--r-- 1 root root  2888 Feb  6  2006 pam_deny.so
-rw-r--r-- 1 root root 11672 Feb  6  2006 pam_env.so
-rw-r--r-- 1 root root 10852 Feb  6  2006 pam_filter.so
-rw-r--r-- 1 root root  5508 Feb  6  2006 pam_ftp.so
-rw-r--r-- 1 root root 11456 Feb  6  2006 pam_group.so
-rw-r--r-- 1 root root  6908 Feb  6  2006 pam_issue.so
-rw-r--r-- 1 root root  8592 Feb  6  2006 pam_lastlog.so
-rw-r--r-- 1 root root 16364 Feb  6  2006 pam_limits.so
-rw-r--r-- 1 root root 12704 Feb  6  2006 pam_listfile.so
-rw-r--r-- 1 root root  4620 Feb  6  2006 pam_localuser.so
-rw-r--r-- 1 root root  9660 Feb  6  2006 pam_mail.so
-rw-r--r-- 1 root root 17316 Feb  6  2006 pam_mkhomedir.so
-rw-r--r-- 1 root root  4228 Feb  6  2006 pam_motd.so
-rw-r--r-- 1 root root  5892 Feb  6  2006 pam_nologin.so
-rw-r--r-- 1 root root  3224 Feb  6  2006 pam_permit.so
-rw-r--r-- 1 root root 11372 Feb  6  2006 pam_rhosts_auth.so
-rw-r--r-- 1 root root  3576 Feb  6  2006 pam_rootok.so
-rw-r--r-- 1 root root  7096 Feb  6  2006 pam_securetty.so
-rw-r--r-- 1 root root 11664 Feb  6  2006 pam_selinux.so
-rw-r--r-- 1 root root  5632 Feb  6  2006 pam_shells.so
-rw-r--r-- 1 root root  9840 Feb  6  2006 pam_stress.so
-rw-r--r-- 1 root root 14396 Feb  6  2006 pam_succeed_if.so
-rw-r--r-- 1 root root 10224 Feb  6  2006 pam_tally.so
-rw-r--r-- 1 root root  8748 Feb  6  2006 pam_time.so
-rw-r--r-- 1 root root 53084 Feb  6  2006 pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_acct.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_auth.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_passwd.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_session.so -> pam_unix.so
-rw-r--r-- 1 root root  8608 Feb  6  2006 pam_userdb.so
-rw-r--r-- 1 root root  4248 Feb  6  2006 pam_warn.so
-rw-r--r-- 1 root root  8340 Feb  6  2006 pam_wheel.so
-rw-r--r-- 1 root root 14188 Feb  6  2006 pam_xauth.so

./lib/tls:
total 1452
-rwxr-xr-x 1 root root 1270928 Nov 11 16:35 libc-2.3.6.so
lrwxrwxrwx 1 root root      13 Nov 11 15:57 libc.so.6 -> libc-2.3.6.so
spencer@debian:~$ cat /tmp/allfiles.txt  
.:
total 24
drwxr-xr-x 2 root root 4096 Nov 11 17:23 bin
drwxr-xr-x 2 root root 4096 Nov 11 18:35 dev
drwxr-xr-x 4 root root 4096 Nov 11 19:00 etc
drwxr-xr-x 4 root root 4096 Nov 11 18:08 lib
drwxr-xr-x 2 root root 4096 Nov 11 17:05 tmp
drwxr-xr-x 3 root root 4096 Nov 11 15:57 usr

./bin:
total 704
-rwxr-xr-x 1 root root 684724 Mar 22  2006 bash
-rwsr-xr-x 1 root root  25024 Nov 11 17:23 su

./dev:
total 0
-rw-rw-rw- 1 root root 0 Nov 11 02:00 null

./etc:
total 184
-rw-r--r-- 1 root root     1071 Oct 13  2005 bash.bashrc
-rw-r--r-- 1 root root      702 Aug 12 11:10 fstab
-rw-r--r-- 1 root root      814 Jun 12 21:48 group
-rw-r--r-- 1 root root       26 Sep 25  1995 host.conf
-rw-r--r-- 1 root root      886 Aug 20  2005 hosts
-rw-r--r-- 1 root root      677 Sep  5  2004 hosts.allow
-rw-r--r-- 1 root root      901 Sep  5  2004 hosts.deny
-rw-r--r-- 1 root src    103034 Nov 10 13:55 ld.so.cache
-rw-r--r-- 1 root src      1279 Apr 30  2006 localtime
-rw-r--r-- 1 root root    10684 Feb 22  2006 login.defs
-rw-r--r-- 1 root root      453 Nov 11 08:27 mtab
-rw-r--r-- 1 root root      465 Feb  9  2006 nsswitch.conf
drwxr-xr-x 2 root root     4096 Nov 11 19:00 pam.d
-rw-r--r-- 1 root root     1850 Jun 12 21:48 passwd
-rw-r--r-- 1 root root       96 Nov 11 08:00 resolv.conf
-rw-r----- 1 root shadow   1260 Jun 12 21:48 shadow
-rw-r--r-- 1 root root      222 Apr 30  2006 shells
drwxr-xr-x 2 root root     4096 Nov 11 18:49 ssh

./etc/pam.d:
total 28
-rw-r--r-- 1 root root  392 Sep  5  2004 common-account
-rw-r--r-- 1 root root  436 Sep  5  2004 common-auth
-rw-r--r-- 1 root root 1097 Sep  5  2004 common-password
-rw-r--r-- 1 root root  372 Sep  5  2004 common-session
-rw-r--r-- 1 root root  520 Aug 31  2003 other
-rw-r--r-- 1 root root  820 Jul 29  2004 ssh
-rw-r--r-- 1 root root 2232 May  4  2006 su

./etc/ssh:
total 124
-rw-r--r-- 1 root root 111892 Jul 29  2004 moduli
-rw------- 1 root root    668 Sep  6  2004 ssh_host_dsa_key
-rw------- 1 root root    883 Sep  6  2004 ssh_host_rsa_key

./lib:
total 824
-rwxr-xr-x 1 root root  92260 Apr 14  2006 ld-2.3.6.so
lrwxrwxrwx 1 root root     11 Nov 11 15:57 ld-linux.so.2 -> ld-2.3.6.so
lrwxrwxrwx 1 root root     17 Nov 11 15:57 libcom_err.so.2 -> libcom_err.so.2.1
-rw-r--r-- 1 root root   5792 Nov 11 16:35 libcom_err.so.2.1
-rw-r--r-- 1 root root 268204 Nov 11 17:06 libncurses.so.5
-rw-r--r-- 1 root root  30428 Apr 14  2006 libnss_compat-2.3.6.so
-rw-r--r-- 1 root root  30428 Apr 14  2006 libnss_compat.so.2
-rw-r--r-- 1 root root  30464 Nov 11 17:33 libpam.so.0
-rw-r--r-- 1 root root  30464 Nov 11 17:33 libpam.so.0.79
-rw-r--r-- 1 root root   8216 Feb  6  2006 libpam_misc.so.0
-rw-r--r-- 1 root root   8216 Feb  6  2006 libpam_misc.so.0.79
-rw-r--r-- 1 root root  75220 Mar 22  2006 libselinux.so.1
-rw-r--r-- 1 root root 211424 Mar 22  2006 libsepol.so.1
drwxr-xr-x 2 root root   4096 Feb 24  2006 security
drwxr-xr-x 2 root root   4096 Nov 11 16:35 tls

./lib/security:
total 380
-rw-r--r-- 1 root root 12056 Feb  6  2006 pam_access.so
-rw-r--r-- 1 root root  5132 Feb  6  2006 pam_debug.so
-rw-r--r-- 1 root root  2888 Feb  6  2006 pam_deny.so
-rw-r--r-- 1 root root 11672 Feb  6  2006 pam_env.so
-rw-r--r-- 1 root root 10852 Feb  6  2006 pam_filter.so
-rw-r--r-- 1 root root  5508 Feb  6  2006 pam_ftp.so
-rw-r--r-- 1 root root 11456 Feb  6  2006 pam_group.so
-rw-r--r-- 1 root root  6908 Feb  6  2006 pam_issue.so
-rw-r--r-- 1 root root  8592 Feb  6  2006 pam_lastlog.so
-rw-r--r-- 1 root root 16364 Feb  6  2006 pam_limits.so
-rw-r--r-- 1 root root 12704 Feb  6  2006 pam_listfile.so
-rw-r--r-- 1 root root  4620 Feb  6  2006 pam_localuser.so
-rw-r--r-- 1 root root  9660 Feb  6  2006 pam_mail.so
-rw-r--r-- 1 root root 17316 Feb  6  2006 pam_mkhomedir.so
-rw-r--r-- 1 root root  4228 Feb  6  2006 pam_motd.so
-rw-r--r-- 1 root root  5892 Feb  6  2006 pam_nologin.so
-rw-r--r-- 1 root root  3224 Feb  6  2006 pam_permit.so
-rw-r--r-- 1 root root 11372 Feb  6  2006 pam_rhosts_auth.so
-rw-r--r-- 1 root root  3576 Feb  6  2006 pam_rootok.so
-rw-r--r-- 1 root root  7096 Feb  6  2006 pam_securetty.so
-rw-r--r-- 1 root root 11664 Feb  6  2006 pam_selinux.so
-rw-r--r-- 1 root root  5632 Feb  6  2006 pam_shells.so
-rw-r--r-- 1 root root  9840 Feb  6  2006 pam_stress.so
-rw-r--r-- 1 root root 14396 Feb  6  2006 pam_succeed_if.so
-rw-r--r-- 1 root root 10224 Feb  6  2006 pam_tally.so
-rw-r--r-- 1 root root  8748 Feb  6  2006 pam_time.so
-rw-r--r-- 1 root root 53084 Feb  6  2006 pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_acct.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_auth.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_passwd.so -> pam_unix.so
lrwxrwxrwx 1 root root    11 Nov 11 18:09 pam_unix_session.so -> pam_unix.so
-rw-r--r-- 1 root root  8608 Feb  6  2006 pam_userdb.so
-rw-r--r-- 1 root root  4248 Feb  6  2006 pam_warn.so
-rw-r--r-- 1 root root  8340 Feb  6  2006 pam_wheel.so
-rw-r--r-- 1 root root 14188 Feb  6  2006 pam_xauth.so

./lib/tls:
total 1452
-rwxr-xr-x 1 root root 1270928 Nov 11 16:35 libc-2.3.6.so
lrwxrwxrwx 1 root root      13 Nov 11 15:57 libc.so.6 -> libc-2.3.6.so
-rw-r--r-- 1 root root   21872 Nov 11 16:35 libcrypt-2.3.6.so
lrwxrwxrwx 1 root root      17 Nov 11 15:57 libcrypt.so.1 -> libcrypt-2.3.6.so
-rw-r--r-- 1 root root    9592 Nov 11 16:35 libdl-2.3.6.so
lrwxrwxrwx 1 root root      14 Nov 11 15:57 libdl.so.2 -> libdl-2.3.6.so
-rw-r--r-- 1 root root   80888 Nov 11 16:35 libnsl-2.3.6.so
lrwxrwxrwx 1 root root      15 Nov 11 15:57 libnsl.so.1 -> libnsl-2.3.6.so
-rw-r--r-- 1 root root   67364 Nov 11 16:27 libresolv-2.3.6.so
lrwxrwxrwx 1 root root      18 Nov 11 15:57 libresolv.so.2 -> libresolv-2.3.6.so
-rw-r--r-- 1 root root    9656 Nov 11 16:29 libutil-2.3.6.so
lrwxrwxrwx 1 root root      16 Nov 11 15:57 libutil.so.1 -> libutil-2.3.6.so

./tmp:
total 0

./usr:
total 4
drwxr-xr-x 4 root root 4096 Nov 11 16:35 lib

./usr/lib:
total 888
drwxr-xr-x 3 root root   4096 Nov 11 15:57 i686
lrwxrwxrwx 1 root root     21 Nov 11 15:57 libgssapi_krb5.so.2 -> libgssapi_krb5.so.2.2
-rw-r--r-- 1 root root 113756 Nov 11 16:35 libgssapi_krb5.so.2.2
lrwxrwxrwx 1 root root     18 Nov 11 15:57 libk5crypto.so.3 -> libk5crypto.so.3.0
-rw-r--r-- 1 root root 151252 Nov 11 16:35 libk5crypto.so.3.0
lrwxrwxrwx 1 root root     14 Nov 11 15:57 libkrb5.so.3 -> libkrb5.so.3.2
-rw-r--r-- 1 root root 516648 Nov 11 16:35 libkrb5.so.3.2
lrwxrwxrwx 1 root root     21 Nov 11 15:57 libkrb5support.so.0 -> libkrb5support.so.0.0
-rw-r--r-- 1 root root  14568 Nov 11 16:35 libkrb5support.so.0.0
lrwxrwxrwx 1 root root     13 Nov 11 15:57 libz.so.1 -> libz.so.1.2.3
-rw-r--r-- 1 root root  79684 Nov 11 16:31 libz.so.1.2.3
drwxr-xr-x 2 root root   4096 Nov 11 15:57 openssh

./usr/lib/i686:
total 4
drwxr-xr-x 2 root root 4096 Nov 11 15:57 cmov

./usr/lib/i686/cmov:
total 1240
-rw-r--r-- 1 root root 1262808 Sep  5 17:00 libcrypto.so.0.9.8

./usr/lib/openssh:
total 32
-rwxr-xr-x 1 root root 30704 Mar 31  2006 sftp-server

sshd_config contains the following:

# cat sshd_config
# What ports, IPs and protocols we listen for
Port 22
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 600
PermitRootLogin yes
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile     %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes

# Change to yes to enable tunnelled clear text passwords
PasswordAuthentication no

KeepAlive yes

Subsystem sftp /usr/local/bin/chsftp

UsePAM yes
Personal tools