|
This How-To details the procedure for setting up a chroot'ed account which only has access to the server via SFTP.
The main features of this approach are:
- chroot login : Users are jailed in their home directory using the systems chroot
system call.
- small footprint: No need for a full shell with executables as this setup uses
busybox for the shell.
- secure: Users access the server using SSH, all portions of the
data transfer is encrypted. This setup is easy to audit as it involves very few
components.
-
Users don't end up having shell access to the server.
Note: This setup was developped on RedHat 8.0, but should work exactly the same
way on other Linux distributions (may also work on the *BSDs). The only thing which
may need to be tweaked is the library paths and the sftp paths.
Step 1. Create the chroot shell /bin/chroot-shell:
#!/bin/bash
if [ "$1" = "-c" ]; then i=0; PARAMS=""; for param in $*; do if [ $i -gt 0 ]; then PARAMS="$PARAMS $param"; fi let i++; done; exec sudo /usr/sbin/chroot $HOME /bin/su - $USER -c "$PARAMS" else exec sudo /usr/sbin/chroot $HOME /bin/su - $USER fi;
Make it executable:
chmod +x /bin/chroot-shell
Step 2. Create the chroot environment
mkdir /test; cd /test; mkdir -p etc lib usr/libexec/openssh home
Step 3. Download/Compile busybox http://www.busybox.net/
tar xvfz busybox-X.tar.gz
cd busybox-X
make menuconfig Here are the options you'll need when compiling busybox:
General Config:
[*] Use the devpts filesystem for Unix98 PTYs
[*] Support for SUID/SGID handling
[*] Runtime SUID/SGID configuration via /etc/busybox.conf
[*] Suppress warning message if /etc/busybox.conf is not readable
Build Options:
[*] Build BusyBox as a static binary (no shared libs)
[*] Build with Large File Support (for accessing files > 2 GB)
(-O6) Any extra CFLAGS options for the compiler?
Installation Options:
[*] Don't use /usr
Coreutils:
[*] chmod
[*] chown
[*] chroot
[*] cp
[*] dirname
[*] ls
[*] Enable filetyping options (-p and -F)
[*] Enable symlinks dereferencing (-L)
[*] Enable recursion (-R)
[*] Sort the file names
[*] Show file timestamps
[*] Show username/groupnames
[*] mkdir
[*] mv
[*] pwd
[*] pwd
[*] realpath
[*] rm
[*] rmdir
--- Common options for cp and mv
[*] Preserve hard links
Login/Password Management Utilities:
[*] Use internal password and group functions rather than system functions
[*] su
Another Bourne-like Shell
Choose your default shell (ash)
[*] Standalone shell
[*] Standalone shell -- applets always win
make dep; make; cp busybox /test/bin; ln -s /test/bin/busybox /test/bin/su
Step 4. Prepare the SFTP environment
You have two choices here, if your sftp-server binary is statically
compiled, you can simply copy it over. To figure out if your sftp-server is statically compiled:
ldd /usr/libexec/openssh/sftp-server
not a dynamic executable
(statically compiled)
OR
ldd /usr/libexec/openssh/sftp-server
libresolv.so.2 => /lib/libresolv.so.2 (0x4001b000)
libutil.so.1 => /lib/libutil.so.1 (0x4002e000)
libz.so.1 => /usr/lib/libz.so.1 (0x40031000)
libnsl.so.1 => /lib/libnsl.so.1 (0x4003f000)
libcrypto.so.2 => /lib/libcrypto.so.2 (0x40055000)
libkrb5.so.3 => /usr/kerberos/lib/libkrb5.so.3 (0x40129000)
libk5crypto.so.3 => /usr/kerberos/lib/libk5crypto.so.3 (0x40187000)
libcom_err.so.3 => /usr/kerberos/lib/libcom_err.so.3 (0x40198000)
libc.so.6 => /lib/i686/libc.so.6 (0x42000000)
libdl.so.2 => /lib/libdl.so.2 (0x4019a000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
(dynamically compiled)
A) Statically compiled steps:
cp /usr/libexec/openssh/sftp-server /test/usr/libexec/openssh/sftp-server
B) Dynamically compiled steps:
In order to get the executable to work properly, all libraries which
are linked to sftp-server must be available to the executable at run time. This
means you have to copy all the libraries from the output of ldd
to the chroot jail's library folder.
cp /usr/libexec/openssh/sftp-server /test/usr/libexec/openssh/sftp-server
cp /lib/libc.so.6 /lib/libdl.so.2 /lib/libnsl.so.1 /lib/libresolv.so.2 \
/lib/libutil.so.1 /lib/ld-linux.so.2 /usr/kerberos/lib/libcom_err.so.3 \
/usr/kerberos/lib/libk5crypto.so.3 /usr/kerebos/lib/libkrb5.so.3 \
/usr/lib/libz.so.1 /lib/libcrypto.so.2 /test/lib/
Ideally, I would suggest recompiling sftp-server as a static
binary.
Step 5. Create a user
useradd -s /bin/chroot-shell -d /test test-sftp
passwd test-sftp
**********
Step 6. Get the UID/GID for this newly created account
id test-sftp
uid=508(test-sftp) gid=511(test-sftp) groups=511(test-sftp)
Step 7. Create a 'fake' passwd and group file (putting the appropriate UID/GID values):
echo -e "root:x:0:0::/:/bin/false\n" >/test/etc/passwd
echo -e "test-sftp:x:508:511::/home:/usr/libexec/" >>/test/etc/passwd
echo -e "openssh/sftp-server" >>/test/etc/passwd
echo -e "root:x:0:\ntest-sftp:x:511:" >/test/etc/group
Step 8. Make sure the permissions are correct
chown -R root.root /test
chown -R test-sftp.test-sftp /test/home
chattr -R +i /test/etc /test/bin /test/usr /test/lib
Step 9. Add the user to /etc/sudoers
echo -e "test-sftp ALL = NOPASSWD: /usr/sbin/chroot /test /bin/su - test-sftp*" \
>>/etc/sudoers
That's it, you now have a working user who can only access the server using SFTP.
Here's how it all fits together:
In order for a user to be able to login to a system, first we need to have a system
account with a valid shell. In this case, we don't want the user to have shell access,
instead we only want him to be able to access the system by SFTP.
To achieve this, we create a small 'fake' shell (/bin/chroot-shell) who's job
is simply to temporarily become root using sudo, them issue the chroot
call which jails the user to the filesystem hierarchy we have setup.
Once the user is jailed, we switch back from root to the original user. At
this point, the user's root directory is /test, and the only executables
available to the user are busybox and sftp-server. During the login process,
the 'fake' password file (/test/etc/passwd) is read and the user's shell is
executed (sftp-server). This approach could also be used to provide users with a chrooted shell by changing the entry in the 'fake' passwd, I don't recommend it however, as allowing your users shell access has many security implications.
See also:
http://www.kegel.com/crosstool/current/chrootshell.c |