You are here:  HowtosLinux chrooting guide >

Contact

skype me
  email

Feeds

Neverslair RSS Feed
Neverslair RDF Feed
Neverslair ATOM03 Feed
Neverslair ATOM1 Feed

Sitemap

html sitemap
Sitemap XML

Valid XHTML 1.0 Transitional


[Valid RSS]


powered by typo3



Linux chrooting guide

short explanation of chroots:

a chroot is a "box within a box", meaning, if you have a program, a process
or maybe even a user, which should have only access to a certain part of the
system, you could either do that by patching the programm, so it can only
access a certain part of the system, thats the hard way. now we do have a weapon called chroot, that makes it possible to have that possibility without the need to rewrite parts of the program. a very popular example for a chrooted daemon would be bind, what do we need for that to work:

first thing were going to do is creating a user which bind is going to run under:

adduser named

then we open the /etc/passwd file, and edit the line for the user:

named:x:200:200:Nameserver:/chroot/named:/bin/false

the most important entries here are the :x:, the :/chroot/named and the :/bin/false.

what does this do?

:x: tells us, that we are using a shadow for passwords, this should be already understood before you even think about setting up a chroot;)

the second important part tells, where we want our bind to reside, as the example implies, this is where the game is going to be played.

the third part tells us, that the user bind wont be able to login like a normal user, cause he wont get a shell.

next we have to create a group for our new user:

addgroup named

this will create an entry in /etc/group which looks like this one:

named:x:200:

next thing we need to set is the directory structure for our bind chroot, a typical chroot for bind looks like the following:

/chroot
    +-- named
         +-- dev
         +-- etc
         |    +-- namedb
         |         +-- slave
         +-- var
              +-- run

next thing, install the bind provided with your linux distribution, for debian:

apt-get -f install bind

then we are going to place our things into the chroot:

cp -p /etc/bind/named.conf /chroot/named/etc/
  cp -a /var/bind/* /chroot/named/etc/namedb/
  rm /var/named/etc/namedb/named.conf

(and yes, i know, there better ways, but this was a short to explain).

next we are gonna set a few permission things:

first we need to allow bind to access its config informations:

chown -R named:named /chroot/named/etc

then we need to make sure that the daemon is able to access its temp file:

chown named:named /chroot/named/var/run

ok, like most programs that are running on linux, bind needs to access a few basic devices, so lets make them within the chroot:

mknod /chroot/named/dev/null c 1 3
  mknod /chroot/named/dev/random c 1 8
  chmod 666 /chroot/named/dev/{null,random}

to get right timings on zonefiles, youll need one more file within the chroot:

cp /etc/localtime /chroot/named/etc/

now, since we dont want to loose our holy bind logs, were gonna tweak

the /etc/init.d/sysklogd script a lil bit:

just change the entry

SYSLOGD="" into SYSLOGD="-m 0 -a /chroot/named/dev/log".

now just restart sysklogd and the base things are done.

next we will need to take care of the access permissions on the chroot, so that no other user can access it at all:

"security is a two sided sword."

chown root /chroot
  chmod 700 /chroot
  chown named:named /chroot/named
  chmod 700 /chroot/named

now lets have a look at the init.d script, this is a modified version

targetting our new needs:

#!/bin/sh
  PATH=/sbin:/bin:/usr/sbin:/usr/bin
  # for a chrooted server: "-u bind -t /var/lib/named"
  # Dont modify this line, change or create /etc/default/bind9.
  OPTIONS="-u bind -t /chroot/named"
  test -f /etc/default/bind9 && . /etc/default/bind9
  test -x /usr/sbin/rndc || exit 0
  case "$1" in
      start)
          echo -n "Starting domain name service: named"

          modprobe capability >/dev/null 2>&1 || true

          # dirs under /var/run can go away on reboots.
          mkdir -p /var/run/bind/run
          chmod 775 /var/run/bind/run
          chown root:named /var/run/bind/run >/chroot/dev/null 2>&1 || true

          if [ ! -x /usr/sbin/named ]; then
              echo "named binary missing - not starting"
              exit 1
          fi
          if start-stop-daemon --start --quiet --exec /usr/sbin/named
                  --pidfile /var/run/bind/run/named.pid -- $OPTIONS; then
              if [ -x /sbin/resolvconf ] ; then
                  echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo
              fi
          fi
          echo "."
      ;;

      stop)
          echo -n "Stopping domain name service: named"
          if [ -x /sbin/resolvconf ]; then
              /sbin/resolvconf -d lo
          fi
          /usr/sbin/rndc stop
          echo "."
      ;;

      reload)
          /usr/sbin/rndc reload
      ;;

      restart|force-reload)
          $0 stop
          sleep 2
          $0 start
      ;;

      *)
          echo "Usage: /etc/init.d/bind {start|stop|reload|restart|force-reload}" >&2
          exit 1
      ;;
  esac

  exit 0


easy, eh;)

next we will need to change a few things in the bind configuration "directory","pid-file", "statistics-file".

erm, but why dont set /chroot in front of the things?

simple answer, since bind wont see the dirs outside the chroot, itll "think"

that this chroot dir is his root "/".

now just restart your bind, and have some phun with this lil hack.

ps: this howto is loosely based on the chroot-bind howto, which can be found (for example) here:

http://www.losurs.org/docs/howto/Chroot-BIND-4.html

second part, make a user chroot jail, the easy (debian) way:

the idea behind this is pretty much the same as with bind, but our

target now is bash.

we just start off with creating our subsystem:

apt-get -f install debootstrap
  debootstrap woody /debian

this will create a debian woody base install under /debian.

next step, to get all network names resolved the right way, we need

to copy the existing resolv.conf to the newly created system:

cp /etc/resolv.conf /debian/etc/resolv.conf

next step would be the admin "sneak" on your new subsys:

chroot /debian su -

before youre going to do anything else, give linux its access

to the process informations on the sys:

mount -t proc none /proc

now you may want to do the base configurations on the subsys:

base-config

want to run a program from within the chroot at the startup?

add this line to your /etc/init.d/bootmisc.sh

chroot /debian su -c /etc/init.d/startup-chroot -

just customize the script you wanna call...

now the more tricky part, setting up the user homes:

first thing we want to use is a wrapper, which "forwards" the user

to the chrooted bash in case of his login, either you write one

by yourself, or use an existing one, a very good example for such a wrapper is

http://www.weidner.ch/download/chrlogin.c

now for the base idea...

open /etc/shells and insert a new line into it:

/usr/local/sbin/chrlogin

now do the obvious adduser:

adduser parisc

then open /etc/password, and change the new users line:

parisc:x:1000:1000:pour RiSC:/debian/home/parisc:/usr/local/sbin/chrlogin

the uid and gid doesnt need to be changed in this case, you get the idea...

next we chroot into our chrootjail again as root type:

chroot /debian

there we add the same user as above:

adduser parisc

and edit the /etc/password within the chroot to show the following:

parisc:x:1000:1000:pour RiSC jailed:/home/parisc:/bin/bash

this time we have especially to take care about the uid and gid, they need to be the same as outside of the jail.

then we are going to edit the chrootshell.c file, and change the following

lines to fit our needs:

first of all, which shell should our users get by default:

#define SHELL "/bin/bash"

next we have to tell the chrlogin wrapper where to find the users homes:

#define CHROOT_LEVEL 2

more information about the options can be found in the c source of the file.

finally we need to compile the file, move it into the place, and

set the right permissions on it:

gcc -Wall -O2 -s chrlogin.c -o chrlogin

cp chrlogin /usr/local/sbin (create the dir, if it doesnt exist)

chown root /usr/local/sbin/chrlogin
  chmod 4755 /usr/local/sbin/chrlogin

an absolute must, in case you dont want mr. evil hacker to leave his chrootjail via a race condition or exploit for example, you have to remove all suidbits from files within the chroot environment, to find out which files do have the suid bit set on your /debian dir, run the following command:

find /debian -type f ( -perm -04000 -o -perm -02000 ) -exec ls -lg {} ;

with a chmod -s filename you may remove the suidbit, and dont worry, those arent needed to run the typical programs i could think of.

if youre really paranoid like me, you might want to take a look at the linux grsec kernel patch, which can be found on http://www.grsecurity.net

this is it, i hope you enjoyed it as i did, stay tuned for even more fine system tricks.