Script for creating a chroot environment

This script creates a chroot environment for use with php-fpm.

To be called with the chroot directory and a php binary.

./scriptname /dir/to/chroot /usr/bin/php

It copies all libraries needed by php (by using ldd) and it also copies timedata and dns data (or there will be errors when a php script tries to access a hostname in the web).
Make sure to name all chrooted directory different, e.g. /website1 /website 2 etc. or you could run into weird caching issues, like getting a different website then requested.

DIR=$1
mkdir -p $DIR
mkdir -p $DIR/dev
mkdir -p $DIR/var
mkdir -p $DIR/etc
mkdir -p $DIR/usr
mkdir -p $DIR/usr/lib64
mkdir -p $DIR/usr/local/nginx
mkdir -p $DIR/usr/share
mkdir -p $DIR/tmp
chmod -R 770 $DIR/tmp
mkdir -p $DIR/var/tmp
chmod -R 770 $DIR/var/tmp
mkdir -p $DIR/lib64
mkdir -p $DIR/lib
mkdir -p $DIR/var/lib/php/session
/bin/mknod -m 0600 $DIR/dev/null c 1 3
/bin/mknod -m 0400 $DIR/dev/random c 1 8
/bin/mknod -m 0400 $DIR/dev/urandom c 1 9

cp -fv /etc/{prelink.cache,services,adjtime,hosts.deny,localtime,nsswitch.conf,nscd.conf,prelink.conf,protocols,hosts,ld.so.cache,ld.so.conf,resolv.conf,hosts,host.conf} $DIR/etc
cp -avr /etc/{ld.so.conf.d,prelink.conf.d} $DIR/etc

#ssl
mkdir -p $DIR/etc/pki
cp -fvr /etc/pki $DIR/etc

# copy specific libraries (not covered by ldd)
# dns
cp -fv /lib64/libnss* $DIR/lib64
cp -fv /lib/libnss* $DIR/lib
# timezones
cp -frv /usr/share/zoneinfo/ $DIR/usr/share/
# other
cp -fv /lib64/libsoftokn3.so $DIR/lib64

cp -fv /lib64/libcurl* $DIR/lib64
cp -fv /lib64/libssl* $DIR/lib64
cp -fv /lib64/libcrypt* $DIR/lib64
cp -fv /usr/lib64/libnss* $DIR/usr/lib64
cp -fv /usr/lib64/libnsspem.so $DIR/usr/lib64
cp -fv /usr/lib64/libsoftokn3.so $DIR/usr/lib64


# from https://www.cyberciti.biz/files/lighttpd/l2chroot.txt
# iggy ld-linux* file as it is not shared one
FILES="$(ldd $2 | awk '{ print $3 }' |egrep -v ^'\(')"

echo "Copying shared files/libs to $BASE..."
for i in $FILES
do
  d="$(dirname $i)"
  [ ! -d $DIR$d ] && mkdir -p $DIR$d || :
  /bin/cp $i $DIR$d
done

# copy /lib/ld-linux* or /lib64/ld-linux* to $BASE/$sldlsubdir
# get ld-linux full file location 
sldl="$(ldd $2 | grep 'ld-linux' | awk '{ print $2}')"
# now get sub-dir
sldlsubdir="$(dirname $sldl)"

if [ ! -f $DIR $sldl ];
then
  echo "Copying $sldl $DIR$sldlsubdir..."
  /bin/cp $sldl $DIR$sldlsubdir
else
  :
fi

Mainly this approach is used for security, but this solution is difficult to maintain and error-prone. So it might be better to set up SELinux or GRSecurity with restrictive rules instead.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.