Chroot

From MLDonkey
Jump to: navigation, search

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.

  1. Decide where to chroot your mldonkey, preferably on a dedicated disk or partition. In this example: /home/mldonkey/
  2. Take care that the partition you chose for chroot is not mounted with option nodev
  3. Edit the /etc/passwd for user mldonkey to reflect the location above for the homedir entry. Remember the uid number.
  4. 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.
  5. 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
  6. 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/
  1. 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 = ""
    
  2. 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:

  1. put the setuidgid binary into /home/mldonkey/
  2. make an /home/mldonkey/etc/ directory containing fake passwd and group files and to get name resolution, hosts, resolv.conf and nsswitch.conf
    etc/passwd:
    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.

  3. 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.
    See also UsingDaemonTools
    • 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:

  1. First, I created the user and modified:
    adduser mldonkey
  2. edit /etc/passwd:
    mldonkey:x:1050:1050::/home/mldonkey/./home/mldonkey:/usr/sbin/jk_chrootsh
  3. I created the directory:
    mkdir /home/mldonkey
    chown root:root /home/mldonkey
  4. 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
  5. I created the chroot:
    jk_init -v -j /home/mldonkey basicshell mldonkey
  6. New /home/mldonkey/etc/passwd:
    mldonkey:x:1050:1050::/home/mldonkey:/bin/bash
  7. and new /home/mldonkey/etc/group:
    mldonkey:x:1050:
  8. We need a tmp dir writable for mldonkey, then I did:
    chmod 1777 /home/mldonkey/tmp
  9. Also, I had to set permissions for dev/null:
    chmod 777 /home/mldonkey/dev/null
  10. 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 mldonkey
should 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:

  1. 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)
  2. Check the needed files with the following commands:
    lsof -P -T -p MLNET_PID
    and
    ldd /path/to/mldonkey
  3. 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
  4. 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
  5. 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
  6. 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

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox