Chroot
Contents |
General information
To run mldonkey chrooted is a rather simple procedure. This means that after some initial procedures mldonkey will lock itself into it's homedir and throw away the key. After that the executable cannot alter anything outside the directory, if there are no security holes at kernel level. Thus, it gives, if correctly configured, a very high level of security. But beware!!! a badly setup chroot might even be a security hole itself!! Use jailkit http://olivier.sessink.nl/jailkit/ to setup the jail if you want to be sure to have a secure jail.
- Decide where to chroot your mldonkey, preferably on a dedicated disk or partition. In this example: /home/mldonkey/
- Take care that the partition you chose for chroot is not mounted with option nodev
- Edit the /etc/passwd for user mldonkey to reflect the location above for the homedir entry. Remember the uid number.
- Install all mldonkey files into /home/mldonkey/ or make a copy from your current installation. You must use a static build, or else you'll have to copy all dependant libs into your new root. jk_cp from jailkit can automatically copy the dependencies.
- create /dev/null and /dev/urandom in the chroot, example for Linux:
- mkdir /chroot/dev
- mknod /chroot/dev/null c 1 3
- mknod /chroot/dev/urandom c 1 9
- Move the temp, the incoming and the shared directories to /home/mldonkey/ if you didn't do that allready. Nothing can be accessed above /home/mldonkey/
- If you didn't make a fresh install, edit your downloads.ini to reflect the new root:
incoming_directory = incoming temp_directory = temp shared_directories = [ shared1; shared2; shared3] run_as_user = ""
- execute the following as root or with sudo, replace UID with the uid number for the mldonkey user in /etc/passwd:
export MLDONKEY_CHROOT=/home/mldonkey ./mldonkey -run_as_useruid UID > chlog &
Much more secure is to use jk_chrootlaunch from jailkit to start the daemon. It does a safe chroot, checks for any possible problems, and then changes user id to the corect user and starts the daemon.
For troubleshooting add "-stdout true" and look at your log file. Note that you need to fire it up as root. Note also that you cannot use the option "run_as_user", instead you need to "run_as_useruid". This is because mldonkey cannot reach /etc/passwd anymore.
Comments
Chroot REQUIRES root access.
The setuidgid is available at http://cr.yp.to/ in the daemontools package. setuidgid does not chroot nor jail the process, it only sets the uid of the process. Since it is not setuid itself (it must not have the setuid bit set), it must be run as root. Therefore 'setuidgid root' is a no-op. (note: almost a no-op, setuidgid throws away supplementary groups, but this seems almost irrelevant in this example as the euid root does not require supplementary group membership to 0Wn your server;) again jk_chrootlaunch from jailkit (http://olivier.sessink.nl/jailkit/) is much better because it can do both things, and it will refuse to chroot() to a badly configured chroot jail.
It is only required, if you do not trust mldonkey to correctly setuid itself. If you are really paranoid follow on:
Replace step 8 with:
- put the setuidgid binary into /home/mldonkey/
- make an /home/mldonkey/etc/ directory containing fake passwd and group files and to get name resolution, hosts, resolv.conf and nsswitch.conf
root:*:0:0:Charlie &:/root:/bin/false mldonkey:*:65530:65530:edonkey Daemon:/home/mldonkey:/bin/false
etc/group:
wheel:*:0:root mldonkey:*:65530:
Your mileage may vary depending on the os used. Make sure the uid/gid is the right one used for the real /home/mldonkey dir.
Maybe you'll need libc.so and ld-elf.so in /home/mldonkey/usr/lib and libexec on FreeBSD to run dynamic binary.
- your start script may then look like this (/home/mldonkey/run):
#!/bin/sh cd /home/mldonkey exec chroot . ./setuidgid mldonkey ./mldonkey.static >mldonkey.log 2>&1
Make sure its executable bit is set (chmod 700 run). It must be run as root, since chroot and setuidgid require root privileges. These privileges are dropped immediately and mldonkey is started as user 'mldonkey' confined to /home/mldonkey/.
-
- Now (since you installed daemontools :) make a symlink from /home/mldonkey to /service/mldonkey and supervise will fire up your client. This won't work for nfs mounted filesystems, see 9b then.
- If you prefer the sysV way, alternatively a start script in your rc.d could then look like this:
#!/bin/sh case "$1" in start) /usr/home/mldonkey/run & ;; stop) ( echo "auth MYPASSWORD" ; echo "kill" ) || nc -w 1 127.0.0.1 4000 ;; esac
_White FrosT: I had to used 'expect' to control the telnet daemon. Try 'man expect' if you are unformiliar with this command._
Thats it.
Note: Beware about the environment inherited from the parent. Like ulimit, umask, etc. Easier than to change the file and directory creation mask from umask 022 to a more restrictive one will be to setup the downloads.ini options create_dir_mode and create_file_mode to avoid permission problems when the core creates new directories.
Freebsd Jail
FreeBSD has a nice feature called jails. A jail is a semi-virtualized computer in which the program runs. Even the root user in the jail is much degraded in what He can do. Setting up a jail for MLDonkey is straightforward. First read the manpage jail(8). It tells you how to build a world and put the code into the jail location. Next it tells you how to start up a jail with a distinct IP.
Once you have the jail up and running, it is straightforward to create a user inside the jail with no privileges whatsoever, let him run the mldonkey binary with:
./mldonkey -allowed_ips <your-jail-ip>
Afther that the telnet daemon should be able to connect to mldonkey, providing a neat and convenient inteface to the backend.
JailKit
I found a simple and secure way to chroot MLDonkey thanks to Jailkit.
When you get it ready. Preparing the Jail:
- First, I created the user and modified:
- adduser mldonkey
- edit /etc/passwd:
- mldonkey:x:1050:1050::/home/mldonkey/./home/mldonkey:/usr/sbin/jk_chrootsh
- I created the directory:
- mkdir /home/mldonkey
- chown root:root /home/mldonkey
- Add this to /etc/jailkit/jk_init.ini:
- [mldonkey]
- comment = MLDonkey P2P
- libraries = /lib/libnss_files.so.2, /lib/libc.so.6, /lib/ld-linux.so.2, /lib/libnss_dns.so.2, /lib/libresolv.so.2
- regularfiles = /etc/nsswitch.conf, /etc/resolv.conf, /etc/hosts
- devices = /dev/urandom, /dev/null
- emptydirs = /tmp
- I created the chroot:
- jk_init -v -j /home/mldonkey basicshell mldonkey
- New /home/mldonkey/etc/passwd:
- mldonkey:x:1050:1050::/home/mldonkey:/bin/bash
- and new /home/mldonkey/etc/group:
- mldonkey:x:1050:
- We need a tmp dir writable for mldonkey, then I did:
- chmod 1777 /home/mldonkey/tmp
- Also, I had to set permissions for dev/null:
- chmod 777 /home/mldonkey/dev/null
- And set owner to our home directory:
- chown mldonkey:mldonkey -R /home/mldonkey/home/mldonkey
- chmod 755 /home/mldonkey/home/mldonkey
We have the Jail ready for whatever, we have copied almost each needed library, that were added in jk_ini.ini (mldonkey profile).
su mldonkeyshould login in a minimalistic bash. If it does not work, check /var/log/daemons.log, /var/log/auth.log or /var/log/syslog.
Now we are ready to put mldonkey inside. I did it compiling it by myself, precompiled binary should work too.
For any problems or suggestions go to: Forum:Chrooting mldonkey (jailkit) [not a problem]
Startup Script, check chrootuidWithSysV
Chrootuid is your friend
After searching google extensively for ways to SU and CHROOT at the same time, I found a really spiffy program to do it all at once. Will not only perform as chroot, but it will also set the uid of the program mlnet.
The command puts mldonkey in background but the terminal needs to be keep online:
chrootuid /path/to/chroot/jail mlnet_username mlnet &
chrootuid also works with other methods. See HowToStartMLdonkey.
The command puts mldonkey in background and keep it running even after detaching the terminal:
nohup chrootuid /path/to/chroot/jail mlnet_username mlnet &
Or in a screen session, just detach with Control-a d and will keep it running:
screen chrootuid /path/to/chroot/jail mlnet_username mlnet
Find chrootuid here: [1]
It is, however, basically the same as jk_chrootlaunch, which is even a bit better because it checks for the chroot security as well.
Here's a link to a wiki page on how to use it with sysV style init script that I wrote
Adding libraries to the chrooted jail
In some cases there are more libraries needed, even if the mlnet was compiled staticly. I've found out that for example the bittorent module does not work correct if there are no DNS related libraries loaded, because of design choices by glibc devs. Here's how to find out which libraries are needed in the chroot jail with the use of the lsof command:
- First run mlnet in a not chrooted jail. Connections to the outside world are not necessary. Enable all the clients which are needed (in this case bittorent)
- Check the needed files with the following commands:
lsof -P -T -p MLNET_PID
- and
ldd /path/to/mldonkey
- Take note of the /lib files which show up and copy these files in the chroot jail /lib directory I had to copy the following files with the 'cp -p' command:
- /lib/libnss_files.so.2
- /lib/libc.so.6
- /lib/ld-linux.so.2
- /lib/libnss_dns.so.2
- /lib/libresolv.so.2
- In the case of DNS there are also support files needed, make the /etc in the chroot jail and copy resolv.conf, hosts and nsswitch.conf files to the chroot directory /etc with passwd and group files (see above).
- etc/hosts:
127.0.0.1 localhost localhost.localdomain
- etc/resolv.conf:
nameserver your_nameserver_ip
- Create a /tmp directory inside the chroot, and give at least to the mldonkey user, write, read and execute privileges.
- mkdir tmp
- chmod 1775 tmp
- Restart the mlnet client and check with a recent torrent file if the construction is working. Look for errors at the terminal output and the mlnet.log file.
Currently for mldonkey-2.9.0.static.i386-Linux_glibc-2.3.2.tar.bz2 these libraries with their symbolic links will be enought. These files can be found in many packages.
$ ls -l lib/ -rwxr-xr-x 1 root root 85420 Nov 5 2003 ld-2.2.5.so lrwxrwxrwx 1 root root 11 Jul 27 21:33 ld-linux.so.2 -> ld-2.2.5.so -rwxr-xr-x 1 root root 1344152 Nov 5 2003 libc-2.2.5.so lrwxrwxrwx 1 root root 13 Jul 27 21:33 libc.so.6 -> libc-2.2.5.so -rwxr-xr-x 1 root root 85262 Nov 5 2003 libnsl-2.2.5.so lrwxrwxrwx 1 root root 15 Jul 27 21:33 libnsl.so.1 -> libnsl-2.2.5.so -rwxr-xr-x 1 root root 16023 Nov 5 2003 libnss_dns-2.2.5.so lrwxrwxrwx 1 root root 19 Jul 27 21:33 libnss_dns.so.2 -> libnss_dns-2.2.5.so -rwxr-xr-x 1 root root 42897 Nov 5 2003 libnss_files-2.2.5.so lrwxrwxrwx 1 root root 21 Jul 27 21:33 libnss_files.so.2 -> libnss_files-2.2.5.so -rwxr-xr-x 1 root root 44383 Nov 5 2003 libnss_nisplus-2.2.5.so lrwxrwxrwx 1 root root 23 Jul 27 21:33 libnss_nisplus.so.2 -> libnss_nisplus-2.2.5.so -rwxr-xr-x 1 root root 64733 Nov 5 2003 libresolv-2.2.5.so lrwxrwxrwx 1 root root 18 Jul 27 21:33 libresolv.so.2 -> libresolv-2.2.5.so
For character conversion to work its support files also are needed:
$ ls -l usr/lib/gconv/ -rwxr-xr-x 1 root root 5412 Jul 11 13:32 ISO8859-1.so (or your language encoding library) -rwxr-xr-x 1 root root 6516 Jul 11 13:33 UNICODE.so -rw-r--r-- 1 root root 43774 Jul 11 13:33 gconv-modules -rw-r--r-- 1 root root 20666 Jul 11 13:33 gconv-modules.cache
$ ls -l usr/share/i18n/charmaps/ -rw-r--r-- 1 root root 3150 Nov 5 2003 ISO-8859-1.gz -rw-r--r-- 1 root root 229052 Apr 7 2007 UTF-8.gz
Please, notice that character conversion may not work even when creating the usr/bin usr/lib usr/share tree and files.
You also may need some files from usr/share/i18n/locales/ and usr/lib/locale/
You can check from within the chrooted jail that this works, and look with ldd for the files used by iconv as shown above in step 2:
echo "ñ" | iconv -f iso8859-1 -t utf-8
See Also
- How to start MLdonkey
- Screen
- You dig unix and like elegant solutions: Controlling, logging and automatically relaunching MLdonkey UsingDaemonTools
- Using startup or control scripts (StartingSysVStyle, chrootuidWithSysV).
- Ulimit