|
|
  There was a time, not so very long ago, when we used to enjoy running
an ftp server and locking our users into tiny little chrooted jails.
While we still enjoy denying users their freedom, we now prefer to
do so using a maximum security facility. The sftp file transfer program,
which comes with OpenSSH server, gives users an interactive interface
like ftp but performs transfers over an encrypted ssh transport. In
this day and age, it is not unreasonable to expect users to
start using an ssh client, even if they are running Windows.
If they don't have one already, tell them to download
Putty.
There are also nice commercial clients, and if users are technically
adept and so inclined, they can use openssh over cygwin.
Building a chrooted ssh
By design, OpenSSH does not include the capacity to be chrooted,
as the developers contend such functionality belongs in the OS.
Luckily, a third party patch has been developed.
The patch, a pre-patched openssh tarball, and a good document about
setting up the chrooted sftp are available at http://chrootssh.sourceforge.net.
Download the tarball for openssh, and the chrootssh patch. Untar the openssh sources, then
apply the patch.
[usr-4@srv-3 ssh]$ tar xzf openssh-3.6.1p2.tar.gz
[usr-4@srv-3 ssh]$ cd openssh-3.6.1p2
[usr-4@srv-3 openssh-3.6.1p2]$ patch -p1 < ../osshChroot-3.6.1.diff
patching file session.c
|
Now build the chroooted OpenSSH.
[usr-4@srv-3 openssh-3.6.1p2]$ ./configure --with-md5-password
[usr-4@srv-3 openssh-3.6.1p2]$ make
|
Before you make install, you may want to make a copy of your current ssh
binaries, if they are installed in /usr/local/bin and /usr/local/sbin,
which is where openssh will put them by default. The install will not
overwrite your config files or host keys, though if you're paranoid
like us you'll back them up anyway.
[root@srv-3 openssh-3.6.1p2]# make install
|
This goes swimmingly on my Red Hat 7.3 workstation. Now, you'll need to kill the old
sshd and start the new one. In my case, I have been running sshd from a different
location, /usr/sbin/sshd which is where Red Hat installs it. In order to keep
the rc script working, either change the path to sshd in your sshd rc script,
(/etc/rc.d/init.d/sshd or something like that) or create a link like so:
[root@srv-3 openssh-3.6.1p2]# mv /usr/sbin/sshd /usr/sbin/sshd.old
[root@srv-3 openssh-3.6.1p2]# ln -s /usr/local/sbin/sshd /usr/sbin/sshd
[root@srv-3 ssh]# service sshd stop
Stopping sshd: [ OK ]
[root@srv-3 ssh]# service sshd start
Starting sshd: [ OK ]
|
Make sure you can ssh to your machine from another box. If sshd is
working, we can proceed to my favorite part, setting up the chrooted jail.
Building a Jail
The chrooted environment must contain everything a user needs to copy
files back and forth using sftp. This includes utilities used by sftp,
libraries, a home directory, and even some device files. This will
keep the user safely off the rest of the system. Before you get too
excited, keep in mind that chrooted jails can be broken. But not easily. Referring to the
document at chrootssh.sourceforge.net, we'll build our jail. We're going to
call ours alcatraz.
[root@srv-3 u01]# mkdir alcatraz
[root@srv-3 alcatraz]# mkdir bin dev home lib usr
[root@srv-3 alcatraz]# cd bin
|
Copying the necessary binaries:
[root@srv-3 bin]# cp /bin/bash /bin/cp /bin/ls /bin/mkdir /bin/mv
/bin/rm /bin/rmdir .
[root@srv-3 bin]# ln -s bash sh
|
Determining which libraries are needed and copying them into place:
[root@srv-3 bin]# cd ../lib
[root@srv-3 lib]# ldd ../bin/bash
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4002b000)
libdl.so.2 => /lib/libdl.so.2 (0x40030000)
libc.so.6 => /lib/libc.so.6 (0x40033000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[root@srv-3 lib]# cp /lib/libtermcap.so.2 .
[root@srv-3 lib]# cp /lib/libdl.so.2 .
[root@srv-3 lib]# cp /lib/libc.so.6 .
[root@srv-3 lib]# cp /lib/ld-linux.so.2 .
[root@srv-3 lib]# ldd ../bin/cp
libc.so.6 => /lib/libc.so.6 (0x4002b000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[root@srv-3 lib]# ldd ../bin/ls
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4002b000)
libc.so.6 => /lib/libc.so.6 (0x40030000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
|
And so on. We also need sftp itself.
[root@srv-3 alcatraz]# cd usr
[root@srv-3 usr]# mkdir lib
[root@srv-3 usr]# mkdir -p local/libexec
[root@srv-3 usr]# cp /usr/local/libexec/sftp-server local/libexec/
[root@srv-3 usr]# ldd local/libexec/sftp-server
libutil.so.1 => /lib/libutil.so.1 (0x4002b000)
libz.so.1 => /usr/lib/libz.so.1 (0x4002f000)
libnsl.so.1 => /lib/libnsl.so.1 (0x4003d000)
libcrypto.so.2 => /lib/libcrypto.so.2 (0x40051000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x40117000)
libc.so.6 => /lib/libc.so.6 (0x40144000)
libdl.so.2 => /lib/libdl.so.2 (0x4026b000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[root@srv-3 usr]# cp /lib/libutil.so.1 ../lib/
[root@srv-3 usr]# cp /usr/lib/libz.so.1 lib/
[root@srv-3 usr]# cp /lib/libnsl.so.1 ../lib/
[root@srv-3 usr]# cp /lib/libcrypto.so.2 ../lib/
[root@srv-3 usr]# cp /lib/libcrypt.so.1 ../lib/
[root@srv-3 usr]# cp /lib/libc.so.6 ../lib/
cp: overwrite `../lib/libc.so.6'? n
[root@srv-3 usr]# cp /lib/libdl.so.2 ../lib/
cp: overwrite `../lib/libdl.so.2'? n
|
Now sftp should work. We just need a couple of device files, /dev/null and /dev/zero:
[root@srv-3 usr]# cd ../dev
[root@srv-3 dev]# ls -l /dev/null /dev/zero
crw-rw-rw- 1 root root 1, 3 Apr 11 2002 /dev/null
crw-rw-rw- 1 root root 1, 5 Apr 11 2002 /dev/zero
[root@srv-3 dev]# mknod null c 1 3
[root@srv-3 dev]# mknod zero c 1 5
[root@srv-3 dev]# ls -l
total 0
crw-r--r-- 1 root root 1, 3 Jul 28 15:15 null
crw-r--r-- 1 root root 1, 5 Jul 28 15:15 zero
|
Let's see if the chroot works.
[root@srv-3 root]# chroot /u01/alcatraz /bin/sh
[I have no name!@srv-3 /]# pwd
/
[I have no name!@srv-3 /]# ls
bin dev home lib usr
|
It works! But as you can see, functionality is limited.
If we had an /etc/passwd file, for instance, we'd have a normal root
prompt instead of the identity crisis listed above.
Setting up Users, Refining.
Let's add a user whose home directory is chrooted and test the chroot
functionality of ssh.
[root@srv-3 bin]# useradd -d /u01/alcatraz/./home/usr-3 usr-3
[root@srv-3 bin]# passwd usr-3
Changing password for user usr-3.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@srv-3 bin]# ssh srv-4
root@srv-4's password:
Last login: Mon Jul 28 13:44:49 2003 from srv-3.upthe.com
[root@srv-4 root]# ssh usr-3@srv-3
usr-3@srv-3's password:
bash-2.05a$ pwd
/home/usr-3
bash-2.05a$ cd ../..
bash-2.05a$ ls
bin dev home lib usr
|
Yep, we are definitely in our jail. But lets see what we can do in this jail:
bash-2.05a$ mkdir z
mkdir: cannot create directory `z': Permission denied
bash-2.05a$ cd
bash-2.05a$ pwd
/home/usr-3
bash-2.05a$ mkdir z
bash-2.05a$ ls -l
total 4
drwxr-xr-x 2 548 548 4096 Jul 28 22:39 z
bash-2.05a$ cd ..
bash-2.05a$ rmdir usr-3
rmdir: `usr-3': Permission denied
|
Looks pretty good! The last thing we have to do is lock down little usr-3's shell
so she can use only sftp. We are not allowing interactive logins, chrooted or no.
The easiest way to do this is to use sftp-server as the shell. It's a little ugly,
but it works.
[root@srv-4 root]# ssh usr-3@srv-3
usr-3@srv-3's password:
Last login: Mon Jul 28 15:36:54 2003 from srv-4.upthe.com
Connection to srv-3 closed.
[root@srv-4 root]# sftp usr-3@srv-3
Connecting to srv-3...
usr-3@srv-3's password:
sftp> pwd
Remote working directory: /home/usr-3
sftp> put /etc/group
Uploading /etc/group to /home/usr-3/group
|
The ugly part is that the session just hangs until interrupted when
interactive login is attempted. You can always write a wrapper, but
remember it must work within your chroot environment. Finally, let's
tighten up our jail a little bit more. Let's take away usr-3's write
permissions on her own home directory! Why, you ask? I'll show you.
[usr-4@srv-4 .ssh]$ sftp usr-3@srv-3
Connecting to srv-3...
usr-3@srv-3's password:
sftp> mkdir .ssh
sftp> lcd .ssh
sftp> cd .ssh
sftp> put id_dsa.pub authorized_keys
Uploading id_dsa.pub to /home/usr-3/.ssh/authorized_keys
sftp> exit
[usr-4@srv-4 .ssh]$ sftp usr-3@srv-3
Connecting to srv-3...
sftp>
|
This is fine, if you want to allow the user to write keys and circumvent
the need for a valid password. But if you want to control access via
passwords, lock down the home directory and give them write permissions
on a directory below it.
[root@srv-3 usr-3]# mkdir files
[root@srv-3 usr-3]# chown usr-3:usr-3 files
[root@srv-3 usr-3]# chmod 700 files
[root@srv-3 usr-3]# ls -l
total 12
drwx------ 2 usr-3 usr-3 4096 Jul 28 16:35 files
[root@srv-3 usr-3]# cd ..
[root@srv-3 home]# chown root:root usr-3
[root@srv-3 home]# ls -l
total 4
drwx------ 3 root root 4096 Jul 28 16:35 usr-3
|
That will keep usr-3 from playing her naughty tricks. I'm looking
forward to imprisoning many users with this system. True, there's
no proof they've done anything wrong, but I'm sure they're just
waiting for the opportunity!
|
|