I am using a Debian box with the sid(sarge) distribution, so some of this stuf is Debian specific. This involves some extra libraries being included and isn't much of an obstacle to this working on another distribution. This also assumes you have PAM set up and working properly.
First off I got hold of pam_chroot.
#apt-cache search libpam-chroot
libpam-chroot - Chroot Pluggable Authentication Module for PAM
#apt-get install libpam-chroot
Next go to /usr/share/doc/libpam-chroot/examples. There is a stack of information there. There are two things that need to be done:
- Create a chrooted environment (the jail).
- Modify PAM to chroot the session.
Creating the Jail
This section should work for setting up any chrooted environment. In the examples directory mentioned above, there is a script named setup-chrootdir-shell.sh, this is a good place to start. What it does is take a directory name as a parameter and attempt to hardlink a minimal set of libraries and binaries with a minimal device list. This gave me three problems. The first was that my home directories are on a seperate partition to my root filesystem and so I recieved a "ln: creating hard link `randomfile' to `randomfile': Invalid cross-device link" error as hardlink only work between files on the same partition, or more correctly, device. So I modified the script to copy the files instead. The second problem was that the minimal set of libraries it copied across didn't work for the precompiled bash on my Debian system, and did not provide library functions for basic username lookup from the passwd file. The third is not a problem but rather a lacking features; the script does not create an etc directory, it does not set permissions and it doesn't set up the home directory nicely from /etc/skel. Thus I present my own kludge of a script. This takes two arguments; the name of the directory to be created, and the username of the user this is for, e.g.:./setup-chrootdir-shell.sh /home/naughty naughty
This will create the directory /home/naughty with the following directory structure:
drwxr-sr-x 2 root root 168 2005-03-28 18:50 bin/
drwxr-sr-x 2 root root 264 2005-03-28 18:50 dev/
drwxr-sr-x 2 root root 96 2005-03-28 18:50 etc/
drwxr-sr-x 3 root root 72 2005-03-28 18:50 home/
drwxr-sr-x 2 naughty naughty 160 2005-03-28 18:50 home/naughty/
drwxr-sr-x 2 root root 936 2005-03-28 18:50 lib/
By default this has the bash shell, ls, pwd and true/false and is a pretty minamalist jail. Any other functionality will require the binary, necessary configuration files, and required libraries to be copied across. You can figure these out with a combination of ldd, strace and the man page. Alternativley you could look at the source code but sometimes a strings works well too. Remember to update your passwd and groups files too (unless you have linked them). You can test your jail by typing 'chroot /the/directory /the/shell'. This will put you in the jail and you can experience what the user would.
Sometimes isolating a problem requires narrowing down the problem, to this end the bind option of mount can be usefull. For example 'mount -o bin /dev /home/naughty/dev' will mount your /dev into the chroot. This will help you figure out if your jail is missing a device or if it is something else.
After all of this, create the user or change the user's home directory to the new jail and the shell to one of the shells you have made available in your jail. This script assumes you will be making a jail for each user, if you want a common jail for a bunch of users, then you can run the script for the first user and manually add new home directories.
Makejail
There is a much easier another way of creating the chroot with a utility called makejail, it should be in your favourite repository. Makejail has cool configuration files and looks to be a far better another way of managing multiple jails, complex jail and jails over time. I haven't played with it yet.
Makejail is alright, but it has its problems. The best part of makejail is that it can install Debian packages for you. I have made a makejail near equivalent of my script above. In this script I have instructed makejail to include the coreutils package in the chroot. The script is run as root with:
makejail ./makejail-user.py
Remember to change all usernames from naughty to something else, and unmount /proc afterwards. Other makejail examples can be found in /usr/local/share/docs/makejail/examples.
Modifying PAM
After setting up the jail this part is easy. There are two files that need to be modified. The first is /etc/security/chroot.conf which requires a line to say which user should go to jail, go directly to jail and not pass go, and where the jail is. This is one line, of the form (continuing from our above example):
naughty /home/naughty
That was easy. Now /etc/pam.d/login needs to be edited to instruct it to use the chroot module for the session setup. Which file you actually add this line to depends on what you are trying to. I wanted the user to be chrooted for everything that supports PAM (console, smb, ssh, ftp etc.) so I modified the /etc/pam.d/common-session file. This file is a common set of session modules that is included in every pam conf file. For example the /etc/pam.d/login file modifies the behaviour of login service, while /etc/pam.d/ssh will modify ssh and /etc/pam.d/samba will modify windows filesharing behaviour, you get the idea, but they all include the common-* files. The line that is required is:
session required pam_chroot.so debug
The 'debug' is only needed initially for troubleshooting. Once everything is working you can remove it, or if you like the log verbosity leave it in.
That should be all. Try and ssh in as the new (test) user while keeping an eye on your syslog or auth.log. Not all chroot erros become apparant from manual chroot testing and some modification of your jail may be required. It took me a while to realise that libnss_files was required to read the passwd and group file.
Summary
Ok now for the process. When a user logs on PAM will go through its list of modules defined in the relevant /etc/pam.d/ file. The session is set up last. Here PAM will look at /etc/security/chroot.conf to see if the logging on user matches any of the usernames or regexp's in that file. If a match is found, PAM will look to see what directory has been specified as the jail. PAM will then chroot the user to that environment (jailing them) , drop privledges and invoke the relevant service e.g. /bin/bash.
I hope this is useful to someone.
UPDATE: added makejail description and files.
Tracked: May 27, 04:16