Feeds
Articles
Discussions
Root
This script install a chrooted nginx and php environment on a specific folder of the system. Is has been developped and tested on Debian Squeeze 64 bits. It requires that the nginx, php5-cgi, spawn-fcgi packages are installed. In addition, if you want mysql support, install php5-mysql before launching the script.
If you need help, want to report bug or submit improvements, please post a comment at the bottom of the page.
#! /bin/bash
set -e
####
# Isolated Nginx & PHP Installation script
# Julien Vehent - 20110418
# http://wiki.linuxwall.info
# Distributed under GPL V2 licence
####
# The main container. change it to match your configuration.
chroot_container=/var/www/
# this function copies shared libraries from a binary to the chroot
# stolen from nixcraft and then improved a bit ;)
libs_to_chroot(){
local d="$1" # JAIL ROOT
local pFILE="$2" # copy bin file libs
local files=""
local _cp="/bin/cp"
# get rid of blanks and (0x00007fff0117f000)
files="$(ldd $pFILE | awk '{ print $3 }' | sed -e '/^$/d' -e '/(*)$/d')"
for i in $files
do
dcc="${i%/*}" # get dirname only
[ ! -d ${d}${dcc} ] && mkdir -p ${d}${dcc} # create missing dirs
[ ! -e ${d}${dcc}${i} ] && ${_cp} -f $i ${d}${dcc} # copy missing only
# recursively get shared libraries of shared library
libs_to_chroot "${d}" "${i}"
done
# Works with 32 and 64 bit ld-linux
sldl="$(ldd $pFILE | grep 'ld-linux' | awk '{ print $1}')"
sldlsubdir="${sldl%/*}"
#[ ! -f ${d}${sldl} ] && ${_cp} -f ${sldl} ${d}${sldlsubdir}
if [ ! -f ${d}${sldl} ];
then
${_cp} -f ${sldl} ${d}${sldlsubdir}
fi
}
install_env() {
local target="$1"
mkdir -p $chroot_container$target/{etc/init.d,dev,var/log/nginx,var/run,var/www,var/tmp,var/lib/nginx,usr/sbin,usr/bin,usr/share,bin,sbin,tmp,lib/lsb,lib64,usr/lib}
chmod 1777 $chroot_container$target/var/tmp/
mknod -m 0666 $chroot_container$target/dev/null c 1 3
mknod -m 0666 $chroot_container$target/dev/random c 1 8
mknod -m 0666 $chroot_container$target/dev/urandom c 1 9
mknod -m 0666 $chroot_container$target/dev/zero c 1 5
# create a user and a group that have the same name as target
groupadd $target
useradd -d $chroot_container$target/var/www -g $target -M -N -s /bin/false $target
# copy startup program
#cp -f /sbin/start-stop-daemon $chroot_container$target/sbin/
#cp -f /lib/lsb/init-functions $chroot_container$target/lib/lsb/
# copy ln to recreate symbolic links inside the chroot
cp -f /bin/ln $chroot_container$target/bin/
}
install_nginx(){
local target="$1"
local nginx_bin=`which nginx`
cp -f $nginx_bin $chroot_container$target$nginx_bin
cp -fr /etc/nginx $chroot_container$target/etc/
#copy shared libs to target
libs_to_chroot "${chroot_container}${target}" "${nginx_bin}"
cp -f /lib/libnss_compat.so.2 $chroot_container$target/lib/
cp -f /lib/libnsl.so.1 $chroot_container$target/lib/
cp -f /lib/libnss_nis.so.2 $chroot_container$target/lib/
cp -f /lib/libnss_files.so.2 $chroot_container$target/lib/
cp -fr /etc/{nsswitch.conf,services,hosts*,localtime,protocols,ld.so.cache,ld.so.conf,ld.so.conf.d,host.conf} $chroot_container$target/etc/
#we just give the chroot the user it needs, that is root and its own
head -n 1 /etc/passwd > $chroot_container$target/etc/passwd
tail -n 1 /etc/passwd >> $chroot_container$target/etc/passwd
head -n 1 /etc/group > $chroot_container$target/etc/group
tail -n 1 /etc/group >> $chroot_container$target/etc/group
# change user ownership
chown -R $target:$target $chroot_container$target/var/www/
# install basic configuration
echo "user $target $target;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
gzip_disable \"MSIE [1-6]\.(?!.*SV1)\";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
" > $chroot_container$target/etc/nginx/nginx.conf
# install basic virtual host
echo "Nginx can be configured to accept requests from 127.0.0.1 only (coming from a proxy or load balancer)"
echo -n "Do you want to allow 127.0.0.1 only and deny all (can be changed in site config) ? y/n > "
read response
if [ $response == "y" ]
then
echo "server {
listen 127.0.0.1:$nginxport;"> $chroot_container$target/etc/nginx/sites-available/default
else
echo "server {
listen $nginxport;"> $chroot_container$target/etc/nginx/sites-available/default
fi
echo "
server_name $fqdn;
access_log /var/log/nginx/$fqdn.access.log;
root /var/www;
index index.cgi index.php index.html index.htm;">>$chroot_container$target/etc/nginx/sites-available/default
if [ $phpsupport -eq 1 ]
then
echo "
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:$phpport;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
}">> $chroot_container$target/etc/nginx/sites-available/default
fi
if [ $fcgiwrapsupport -eq 1 ]
then
echo "
location ~ \.cgi {
include fastcgi_params;
fastcgi_pass unix:/var/run/fcgiwrap.sock;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
}">>$chroot_container$target/etc/nginx/sites-available/default
fi
echo "
}" >> $chroot_container$target/etc/nginx/sites-available/default
# test the setup
chroot $chroot_container$target/ $nginx_bin -t
echo "nginx setup finished."
}
install_php(){
aptitude install php5-cgi spawn-fcgi
local spawnfcgibin=`which spawn-fcgi`
local php_bin=`which php5-cgi`
if [ ! -x $chroot_container$target$spawnfcgibin ]
then
cp -f $spawnfcgibin $chroot_container$target$spawnfcgibin
libs_to_chroot "${chroot_container}${target}" "$spawnfcgibin"
fi
cp -f $php_bin $chroot_container$target$php_bin
cp -fr /etc/php5 $chroot_container$target/etc/
cp -fr /usr/lib/php5 $chroot_container$target/usr/lib/
cp -fr /usr/share/zoneinfo $chroot_container$target/usr/share/
libs_to_chroot "${chroot_container}${target}" "${php_bin}"
echo "php setup finished."
}
install_mysql(){
aptitude update 1>/dev/null
aptitude install php5-mysql
cp -fr /etc/php5 $chroot_container$target/etc/
cp -fr /usr/lib/php5 $chroot_container$target/usr/lib/
local mysql_lib=`find /usr/lib/php5/ -iname mysql.so`
libs_to_chroot "${chroot_container}${target}" "${mysql_lib}"
find /lib -iname libgcc_s.so* -exec cp -f {} $chroot_container$target/lib/ \;
echo "php5-mysql setup finished."
}
install_fcgiwrap(){
aptitude update 1>/dev/null
aptitude install fcgiwrap spawn-fcgi
fcgiwrap_bin=`which fcgiwrap`
cp -f $fcgiwrap_bin $chroot_container$target$fcgiwrap_bin
libs_to_chroot "${chroot_container}${target}" "${fcgiwrap_bin}"
spawnfcgibin=`which spawn-fcgi`
if [ ! -x $chroot_container$target$spawnfcgibin ]
then
cp -f $spawnfcgibin $chroot_container$target$spawnfcgibin
libs_to_chroot "${chroot_container}${target}" "$spawnfcgibin"
fi
}
install_perl(){
local perl_bin=`which perl`
#copy perl binary
cp -f $perl_bin $chroot_container$target$perl_bin
echo "copying all included perl modules from @INC, be patient (~5/10min)"
for INC in $(perl -e 'foreach(@INC){print "$_\n";}')
do
if [ "$INC" != "." ]
then
if [ -h "$INC" ]
then
DESTLINK=$(readlink -f $INC)
mkdir -p $chroot_container$target$DESTLINK
cp -fr $DESTLINK/* $chroot_container$target$DESTLINK/
chroot $chroot_container$target ln -s $DESTLINK $INC
else
if [ -d "$INC" ]
then
mkdir -p $chroot_container$target$INC
cp -fr $INC $chroot_container$target$INC
for perl_lib in $(find $INC -iname '*.so' -exec ls {} \;)
do
libs_to_chroot "${chroot_container}${target}" "${perl_lib}"
done
fi
fi
fi
done
#copy dynamic libs
libs_to_chroot "${chroot_container}${target}" "${perl_bin}"
echo "perl setup finished."
}
install_mojolicious(){
# install chroot env, then move there and issue mojolicious install
cp $(which bash) ${chroot_container}${target}$(which bash)
libs_to_chroot "${chroot_container}${target}" $(which bash)
cp $(which env) ${chroot_container}${target}$(which env)
libs_to_chroot "${chroot_container}${target}" $(which env)
cp $(which curl) ${chroot_container}${target}$(which curl)
libs_to_chroot "${chroot_container}${target}" $(which curl)
curl -s -L cpanmin.us | perl - Mojolicious --local-lib=/tmp-${target}-mojolicious/
cp -r /tmp/${target}-mojolicious/lib/perl5/* ${chroot_container}${target}/usr/lib/perl5/
cp -r /tmp/${target}-mojolicious/bin/* ${chroot_container}${target}/usr/bin/
rm -rf /tmp/${target}-mojolicious/
echo "mojolicious setup finished."
}
create_supervised_config(){
aptitude update 1>/dev/null
aptitude install daemontools daemontools-run
mkdir -p /etc/sv/spawn-fcgi-$target
echo "#! /bin/bash
CHROOTBIN=/usr/sbin/chroot
CHROOTPATH=$chroot_container$target
SPAWNBIN=`which spawn-fcgi`
PHP5BIN=`which php5-cgi`
PHP5PORT=$phpport
PHP5ADDR=127.0.0.1
USER=$target
exec \$CHROOTBIN \$CHROOTPATH \$SPAWNBIN -n -a \$PHP5ADDR -p \$PHP5PORT -u \$USER -g \$USER -C 3 \$PHP5BIN
" > /etc/sv/spawn-fcgi-$target/run
chmod +x /etc/sv/spawn-fcgi-$target/run
update-service --add /etc/sv/spawn-fcgi-$target spawn-fcgi-$target
}
create_control(){
echo "#! /bin/sh
#
### BEGIN INIT INFO
# Provides: control-$target
# Required-Start: $syslog
# Required-Stop: $syslog
# Should-Start: $local_fs
# Should-Stop: $local_fs
# Default-Start: 2
# Default-Stop: 0 1 6
# Short-Description: starts/stops $target
# Description: starts and stops $target
# a webserver chroot for $fqdn
#
### END INIT INFO
CHROOTBIN=/usr/sbin/chroot
CHROOTPATH=$chroot_container$target
NGINXDAEMON=`which nginx`
NAME=nginx
PHP5SUPPORT=$phpsupport
SPAWNBIN=`which spawn-fcgi`
PHP5BIN=`which php5-cgi`
PHP5PORT=$phpport
PHP5ADDR=127.0.0.1
PHPSUPERVISE=$phpsupervise
FCGIWRAPSUPPORT=$fcgiwrapsupport
FCGIWRAPSOCK=/var/run/fcgiwrap.sock
FCGIWRAPBIN=`which fcgiwrap`
USER=$target
DESC='chroot webserver (nginx/php) for $fqdn'
set -e
. /lib/lsb/init-functions
test_nginx_config() {
if \$CHROOTBIN \$CHROOTPATH -t \$NGINXDAEMON_OPTS >/dev/null 2>&1
then
return 0
else
\$CHROOTBIN \$CHROOTPATH \$NGINXDAEMON -t \$NGINXDAEMON_OPTS
return \$?
fi
}
case \"\$1\" in
start)
echo \"Starting \$DESC ---\"
# launching nginx
test_nginx_config
start-stop-daemon --chroot \$CHROOTPATH --start --pidfile /var/run/nginx.pid \
--exec \$NGINXDAEMON -- \$NGINXDAEMON_OPTS || true
echo -n \"nginx started with pid \"; cat \$CHROOTPATH/var/run/nginx.pid ; echo
if [ \$PHP5SUPPORT -eq 1 ]
then
if [ \$PHPSUPERVISE -eq 1 ]
then
svc -u /etc/service/spawn-fcgi-$target
echo \"spawn-fcgi and php5 started under supervise\"
else
start-stop-daemon --chroot \$CHROOTPATH --start \
--exec \$SPAWNBIN -- -a \$PHP5ADDR -p \$PHP5PORT \
-u \$USER -g \$USER -P /var/run/php5-cgi.pid \$PHP5BIN || true
echo -n \"php5-cgi started with pid \"; cat \$CHROOTPATH/var/run/php5-cgi.pid ; echo
fi
fi
if [ \$FCGIWRAPSUPPORT -eq 1 ]
then
start-stop-daemon --chroot \$CHROOTPATH --start \
--exec \$SPAWNBIN -- -s \$FCGIWRAPSOCK \
-u \$USER -g \$USER -P /var/run/fcgiwrap.pid \$FCGIWRAPBIN || true
echo -n \"fcgiwrap started with pid \"; cat \$CHROOTPATH/var/run/fcgiwrap.pid ; echo
fi
;;
stop)
echo \"Stopping \$DESC ---\"
if [ -e \$CHROOTPATH/var/run/nginx.pid ]
then
kill \`cat \$CHROOTPATH/var/run/nginx.pid\`
if [ \$? -ne 0 ]
then
echo -n \"couldn't kill nginx - found running pid \" ; \`cat \$CHROOTPATH/var/run/nginx.pid\`;echo
else
echo \"stopping nginx\"
fi
else
echo \"nginx is not running, no pid file in /var/run/\"
fi
if [ \$PHP5SUPPORT -eq 1 ]
then
if [ \$PHPSUPERVISE -eq 1 ]
then
svc -d /etc/service/spawn-fcgi-$target
echo \"spawn-fcgi and php5 stopped under supervise\"
else
if [ -e \$CHROOTPATH/var/run/php5-cgi.pid ]
then
ps -p \`cat \$CHROOTPATH/var/run/php5-cgi.pid\` 2>&1 1>/dev/null
if [ $? -ne 0 ]
then
echo \"php5-cgi process not running\"
else
kill \`cat \$CHROOTPATH/var/run/php5-cgi.pid\`
if [ \$? -ne 0 ]
then
echo -n \"couldn't kill php5-cgi - pid=\";\`cat \$CHROOTPATH/var/run/php5-cgi.pid\`;echo
else
echo \"php5-cgi has been stopped\"
fi
fi
else
echo \"no php5-cgi pid file in /var/run/\"
fi
fi
fi
if [ \$FCGIWRAPSUPPORT -eq 1 ]
then
if [ -e \$CHROOTPATH/var/run/fcgiwrap.pid ]
then
ps -p \`cat \$CHROOTPATH/var/run/fcgiwrap.pid\` 2>&1 1>/dev/null
if [ $? -ne 0 ]
then
echo \"fcgiwrap process not running\"
else
kill \`cat \$CHROOTPATH/var/run/fcgiwrap.pid\`
if [ $? -ne 0 ]
then
echo -n \"couldn't kill fcgiwrap - pid=\";\`cat \$CHROOTPATH/var/run/fcgiwrap.pid\`;echo
else
echo \"fcgiwrap has been stopped\"
fi
fi
else
echo \"no fcgiwrap.pid file in /var/run/\"
fi
fi
;;
restart)
echo -n \"Restarting \$DESC: \"
\$0 stop
sleep 1
\$0 start
;;
configtest)
echo -n \"Testing \$DESC configuration: \"
if test_nginx_config
then
echo \"\$NAME.\"
else
exit \$?
fi
;;
status)
status_of_proc -p \$CHROOTPATH/var/run/nginx.pid \"\$NGINXDAEMON\" nginx && exit 0 || exit $?
" >> /etc/init.d/control-$target
if [ $phpsupport -eq 1 ]
then
echo "
status_of_proc -p \$CHROOTPATH/var/run/php5-cgi.pid \"\$PHP5BIN\" php5-cgi && exit 0 || exit $?
" >> /etc/init.d/control-$target
fi
echo "
;;
*)
echo \"Usage: \$0 {start|stop|restart|status|configtest}\" >&2
exit 1
;;
esac
exit 0
" >> /etc/init.d/control-$target
if [ -e /etc/init.d/control-$target ]
then
chmod +x /etc/init.d/control-$target
else
echo "couldn't create control file /etc/init.d/control-$target"
exit 1
fi
}
usage(){
echo "Chroot installation script"
echo "Syntax: $0 <site name>"
echo "example: $0 chroot-example"
echo "this will initiate the creation of $chroot_container/chroot-example"
exit 1
}
[ $# -ne 1 ] && usage
[ $UID -ne 0 ] && echo "You need to be root to launch this program" && usage
target=$1
[ -d $chroot_container$target ] && echo "Target already exist !" && exit 1
echo -n "This is going to install a chroot environment in $chroot_container$target. Do you want to continue ? y/n > "
read response
if [ $response != "y" ]
then
exit 1
fi
# create the environment
install_env "${target}"
# get some information from the administrator before we start
port_available=$(netstat -taupen|grep :50|grep LISTEN|awk '{print $4}'|cut -d : -f 2|sort|tail -n 1)
port_available=$(( $port_available + 1 ))
echo -n "Nginx listening port ($port_available seems available) ? > "
read nginxport
echo -n "What will the FQDN of the server be ? (example.com) ? > "
read fqdn
echo -n "Do you want chrooted php support ? y/n > "
read response
if [ $response == "y" ]
then
phpsupport=1
echo -n "Which port should php cgi listen on ? > "
read phpport
echo -n "Would you like to install php5-mysql support in the chroot ? y/n > "
read response
if [ $response == "y" ]
then
install_mysql "${target}"
fi
else
phpsupport=0
fi
if [ $phpsupport -eq 1 ]
then
install_php "${target}"
echo -n "Would you like to add to supervise php using daemon-tools 'supervise' ? y/n > "
read response
if [ $response == "y" ]
then
phpsupervise=1
create_supervised_config "${target}"
else
phpsupervise=0
fi
fi
echo -n "Do you want chrooted fcgiwrap support ? y/n > "
read response
if [ $response == "y" ]
then
fcgiwrapsupport=1
install_fcgiwrap "${target}"
else
fcgiwrapsupport=0
fi
echo -n "Do you want perl support ? y/n > "
read response
if [ $response == "y" ]
then
install_perl "${target}"
echo -n "Also want Mojolicious ? y/n > "
read response
if [ $response == "y" ]
then
install_mojolicious "${target}"
fi
fi
# call installation functions
install_nginx "${target}"
create_control "${target}"
echo -n "Would you like to add this server to startup runlevel 2 ? y/n > "
read response
if [ $response == "y" ]
then
SAVEPWD=`pwd`
cd /etc/rc2.d
ln -s ../init.d/control-$target S17control-$target
cd /etc/rc6.d
ln -s ../init.d/control-$target K01control-$target
cd $SAVEPWD
fi
echo -n "Would you like to create a logrotate rule for this server ? y/n > "
read response
if [ $response == "y" ]
then
echo "$chroot_container$target/var/log/nginx/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
[ ! -f $chroot_container$target/var/run/nginx.pid ] || kill -USR1 \`cat $chroot_container$target/var/run/nginx.pid\`
endscript
}" > /etc/logrotate.d/$target
fi
echo "The installation of the chroot environment is finished."
echo "To control the environement, use the script located at /etc/init.d/control-$target (outside the chroot)"
exit 0
Discussion
Works fine but I receive an error that makes little sense.
cp: missing destination file operand after `/var/www/xxxxxxx'
This happens after it says there has been a successful installation, I tried looking through the script for some sort of error but I could find none.
I'm using Debian Lenny 6.0 x64
doesn't work, after 'do you want to install perl y/n' it errors:
cp: missing destination file operand after `/var/www/xxxxxxx' (xxx being whatever name you gave it)
then doesn't finish install. tested on squeeze
derr.. ran it as root everything works until:
Nginx can be configured to accept requests from 127.0.0.1 only (coming from a proxy or load balancer) Do you want to allow 127.0.0.1 only and deny all (can be changed in site config) ? y/n > n Chroot installation script Syntax: /usr/sbin/chroot <site name> example: /usr/sbin/chroot chroot-example this will initiate the creation of /var/wwwchroot-example then dies to shell prompt. ??
interesting, can you copy the full log, including the command line arguments please
Hold on a second, YOU are teilnlg ME to wake up???? You better stop drinking the fluoridated kool aid. Yes, race is an important issue, but you obviously dont understand WHY it is. If the jew wipes out white people first, exactly who will they be blending in with at that point? DOH! They cant wipe out their only means of cover. The reason race is important is because its used to divide you and keep you quarreling amongst yourselves. The reason they flood so-called white countries with Arabs is because they know white people will see that as a bigger threat than the jew. So, you waste all your energy trying to fight the wrong opponent. Now that your countries are full of people of different races, you cant see the forest for the trees.
This was a great program, but one cnlomaipt was there was an implication that the mass home ownership that began in the 30s was a major factor in the crisis. The home finance system worked fine (for several decades) until the wave of deregulation of banking and growth of the unregulated shadow banking sector occurred. The large investment banks were allowed to use our money to make their risky bets. Not just in housing securities, but in hedge funds and other risky vehicles. We took most of the risk they took most of the profits. All in the name of removing burdensome government. Had sensible regulations been in place, this mess could not have occurred.