SFTP server within a chroot jail

The SSH File Transfer Protocol or SFTP is a network protocol that provides file transfer, and is typically used with the SSH-2 protocol to provide secure file transfer.  Traditional FTP sends your username and password in clear text, and a malicious person could conceivably intercept your login details and the data you send and receive from your FTP server.  More detailed information: http://en.wikipedia.org/wiki/SSH_file_transfer_protocol

Installation steps:

1. Change the default configuration of /etc/ssh/sshd_config:

Under the #Authentication section, make the following changes:

#Authentication:
LoginGraceTime 1m # must log in within 1 minute of session start
PermitRootLogin no # disable root’s ability to fstp to this server

2. Get hold of the rssh installation rpm. I used rssh-2.3.2-1.1.el3.rf.i386.rpm, which can be found on Dag Wieers’ web site, but you should of course choose the correct one for your distribution:

http://dag.wieers.com/rpm/packages/rssh/rssh-2.3.2-1.1.el3.rf.i386.rpm

3. Install rssh:

# rpm -ivh rssh-2.3.2-1.1.el3.rf.i386.rpm

4. Make sure that rssh is added to /etc/shells. This is so that later on you can assign rssh as the shell for SFTP users you will create:

# echo /usr/bin/rssh >> /etc/shells

5. Edit the /etc/rssh.conf file, mainly to allow fstp and for setting up the chroot directory. In this example I used /home as the chroot directory, but you can conceivably use another directory of your choice:

# set the log facility. “LOG_USER” and “user” are equivalent
logfacility = LOG_USER

# Uncomment to allow sftp
allowsftp

# set the default umask
umask = 022

# Set the chroot path
chrootpath = /home

6. To set up the chroot environment, you have to copy some files to chrootpath, to “mirror” those files within the chroot environment, since the sftp user won’t be able to access any files outside of the chroot jail. Create the following directory structure inside chrootpath:

# cd /home
# mkdir etc
# mkdir -p lib/i686/
# mkdir -p usr/bin
# mkdir -p usr/kerberos/lib
# mkdir usr/lib
# mkdir -p usr/libexec/openssh

7. Now you need to populate the directory structure you created in the previous step:

# pwd
/home

# cp /etc/passwd etc
# cp /etc/ld.so.cache etc
# cp /etc/ ld.so.conf etc

# cp /usr/bin/rssh usr/bin/rssh
# cp /usr/bin/scp usr/bin/scp
# cp /usr/bin/sftp usr/bin/sftp
# cp /usr/libexec/rssh_chroot_helper usr/libexec/rssh_chroot_helper
# cp /usr/libexec/openssh/sftp-server usr/libexec/openssh/sftp-server

8. And then you need to copy the dependencies of the files copied in the previous step. Use the ldd command to find each of the above files’ dependencies, and copy them into the corresponding directory in the chroot environment:

Do this for the following files copied in the previous step:
rssh, scp, sftp, rssh_chroot_helper, and sftp-server.

For example, for rssh:

# ldd /usr/bin/rssh
libc.so.6 => /lib/i686/libc.so.6 (0×002b1000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×00685000)

Now copy /lib/i686/libc.so.6 and /lib/i686/libc.so.6 into /home/lib/i686/ and /home/lib/ respectively.

9. To clarify, here is the output for my chroot environment’s structure

# ls -lR /home/etc/
/home/etc/:
total 52
-rwxr-xr-x 1 root root 41688 Jun 15 10:31 ld.so.cache
-rwxr-xr-x 1 root root 68 Jun 15 10:32 ld.so.conf
-rwxr-xr-x 1 root root 47 Jun 15 11:30 passwd

# ls -lR /home/lib
/home/lib:
total 2804
drwxr-xr-x 2 root root 4096 Jun 14 17:27 i686
-rwxr-xr-x 1 root root 106532 Jun 14 17:28 ld-linux.so.2
-rwxr-xr-x 1 root root 971612 Jun 14 17:25 libcrypto.so.4
-rwxr-xr-x 1 root root 1555716 Jun 14 17:28 libc.so.6
-rwxr-xr-x 1 root root 14728 Jun 14 17:27 libdl.so.2
-rwxr-xr-x 1 root root 91368 Jun 14 17:25 libnsl.so.1
-rwxr-xr-x 1 root root 76468 Jun 14 17:24 libresolv.so.2
-rwxr-xr-x 1 root root 12564 Jun 14 17:25 libutil.so.1

/home/lib/i686:
total 1524
-rwxr-xr-x 1 root root 1555716 Jun 14 17:28 libc.so.6

# ls -lR /home/usr
/home/usr:
total 16
drwxr-xr-x 2 root root 4096 Jun 15 10:25 bin
drwxr-xr-x 3 root root 4096 Jun 14 17:26 kerberos
drwxr-xr-x 3 root root 4096 Jun 14 17:25 lib
drwxr-xr-x 3 root root 4096 Jun 14 17:20 libexec

/home/usr/bin:
total 124
-rwxr-xr-x 1 root root 23623 Jun 14 17:15 rssh
-rwxr-xr-x 1 root root 32844 Jun 15 10:25 scp
-rwxr-xr-x 1 root root 59448 Jun 14 17:15 sftp

/home/usr/kerberos:
total 4
drwxr-xr-x 2 root root 4096 Jun 14 17:26 lib

/home/usr/kerberos/lib:
total 460
-rwxr-xr-x 1 root root 5572 Jun 14 17:26 libcom_err.so.3
-rwxr-xr-x 1 root root 63880 Jun 14 17:26 libk5crypto.so.3
-rwxr-xr-x 1 root root 385220 Jun 14 17:26 libkrb5.so.3

/home/usr/lib:
total 60
-rwxr-xr-x 1 root root 52584 Jun 14 17:25 libz.so.1

/home/usr/libexec:
total 28
drwxr-xr-x 2 root root 4096 Jun 14 17:21 openssh
-rwxr-xr-x 1 root root 23384 Jun 14 17:16 rssh_chroot_helper

/home/usr/libexec/openssh:
total 28
-rwxr-xr-x 1 root root 27416 Jun 14 17:21 sftp-server

10. Now restart the sshd service:

# service sshd restart

11. Now you must create a SFTP user account, and make sure that you set the new user’s shell to be rssh:

# useradd username -s /usr/bin/rssh -p password

12. Test your new SFTP server, from the server itself, or from another machine. You could, of course, also use an FTP client application that supports SFTP, such as FileZilla. Take note that you have to configure your FTP client application to connect to the SFTP server using port 22, and not the regular FTP port 21:

# sftp username@servername
Connecting to localhost…
user@server’s password:
sftp> ls
.
..
.Xauthority
.bash_logout
.bash_profile
.bashrc
.gtkrc
.kde
sftp>

13. Now, what I’ve subsequently done, is to remove all other entries from my /home/etc/passwd file, so that the file now looks like this:

# cat /home/etc/passwd
user:x:502:503::/home/user:/usr/bin/rssh

This was purely because I don’t quite want SFTP users to be able to read the “original” passwd file copied from /etc.

But if you subsequently want to add SFTP users, you will possibly have to manually edit this file, then manually create the new users’ home directories, and assign the appropriate permissions to those home directories. Alternatively, you could add new users any way you wish, copy over /etc/passwd to /home/etc, and then delete the entries in that file that you don’t want your SFTP users to be able to view.

UPDATE:

It seems that you don’t need to copy the file /etc/passwd to /home/etc/ at all.  Works fine without doing that.

To prevent a user from cd-ing outside of his own home directory, do the following:

# cd /home
# cp -r etc username/
# cp -r lib username/
# cp -r usr username/

Modify /etc/rssh.conf, and add similar entries for each FTP user on your system:

user=username:011:00010:”/home/username”  # sftp with chroot

%d bloggers like this: