Lighttpd FasCGI PHP, MySQL chroot jail installation under Debian Linux

by on October 5, 2006 · 79 comments· LAST UPDATED January 12, 2007

in , ,

Lighttpd logo

The instruction mentioned below only applies to Debian and Ubuntu Linux. I am going to document following things:

=> Install lighttpd
=> Prepare the file system for the jail
=> Run FastCGI PHP and MySQL from the jail
=> Add Perl support to the jail
=> Take care of sendmail
=> Run multiple domains (virtual hosting) from chrooted jail etc

Please note that information outlined below is for advanced UNIX users or admins only ;).

Note: If you are using Ubuntu Linux read this howto.

Step # 1: Install lighttpd, php4-cgi and mysql server

Use apt-get command to install packages:# apt-get install lighttpd php4-cgi php4-cli php4-mysql mysql-server Note: If you need other php modules just install them using apt-get command.

Step # 2: Prepare the file system

Create a directory called /webroot:# mkdir /webroot

Create temporary /webroot/tmp directory:# mkdir /webroot/tmp/
# chmod 1777 /webroot/tmp/

Create /etc directory to store php.ini file:# mkdir /webroot/etc

Create a log directory for lighttpd web server:# mkdir -p /webroot/var/log/lighttpd
# chown www-data:www-data /webroot/var/log/lighttpd

Create a cache directory:# mkdir -p /webroot/var/tmp/lighttpd/cache/compress/
# chown www-data:www-data /webroot/var/tmp/lighttpd/cache/compress/

Create a lighttpd home directory for virtual hosting
# mkdir -p /webroot/home/lighttpd
# chown www-data:www-data /webroot/home/lighttpd
# chmod 0700 /webroot/home/lighttpd
# ls -dl /webroot/home/lighttpd
Output:

drwx------  2 www-data www-data 4096 Oct  5 23:15 /webroot/home/lighttpd

A handy shell script (l2chroot [download] ) to copy necessary shared system libraries:

#!/bin/bash
BASE="/webroot"
if [ $# -eq 0 ]; then
  echo "Syntax : $0 /path/to/executable"
  echo "Example: $0 /usr/bin/php5-cgi"
  exit 1
fi
[ ! $BASE ] && mkdir -p $BASE || :
# iggy ld-linux* file as it is not shared one
FILES="$(ldd $1 | awk '{ print $3 }' |egrep -v ^'\(')"
echo "Copying shared files/libs to $BASE..."
for i in $FILES
do
  d="$(dirname $i)"
  [ ! -d $BASE$d ] && mkdir -p $BASE$d || :
  /bin/cp $i $BASE$d
done
# copy /lib/ld-linux* or /lib64/ld-linux* to $BASE/$sldlsubdir
# get ld-linux full file location
sldl="$(ldd $1 | grep 'ld-linux' | awk '{ print $1}')"
# now get sub-dir
sldlsubdir="$(dirname $sldl)"
if [ ! -f $BASE$sldl ];
then
  echo "Copying $sldl $BASE$sldlsubdir..."
  /bin/cp $sldl $BASE$sldlsubdir
else
  :
fi

Put l2chroot in /bin directory and set executable permission:# wget http://www.cyberciti.biz/files/lighttpd/l2chroot.txt
# mv l2chroot.txt l2chroot
# cp l2chroot /bin
# chmod +x /bin/l2chroot

Step 3: Put PHP in the jail

Now you need to copy PHP executable files and necessary extensions (php-mysql) to /webroot directory.
# mkdir -p /webroot/usr/bin
# cp /usr/bin/php4-cgi /webroot/usr/bin/
# cp /usr/bin/php4 /webroot/usr/bin/

Copy /etc/php4/cgi/php.ini file to /webroot/etc/ directory.
# cd /webroot/etc/
# cp -avr /etc/php4 .

Now copy other config files in jail:
# cp /etc/hosts /webroot/etc/
# cp /etc/nsswitch.conf /webroot/etc/
# cp /etc/resolv.conf /webroot/etc/
# cp /etc/services /webroot/etc/
# cp /etc/localtime /webroot/etc/

Copy all php shared libraries used by /usr/bin/php4 and /usr/bin/php4-cgi using your l2chroot script:
# /bin/l2chroot /usr/bin/php4
# /bin/l2chroot /usr/bin/php4-cgi

Now you have all shared libraries in /webroot directory. You can verify this with ls command. There is one more file, which you need to copy manually - /lib/ld-linux.so.2:
# cp /lib/ld-linux.so.2 /webroot/lib

Step 4: Put php MySQL extension in the jail

To access MySQL database server you need to use php4-mysql extension.
Copy php mysql extension from /usr/lib/php4/20050606 directory, use following command to determine exact location of mysql.so file:
# dpkg -L php4-mysqlOutput:

/.
/usr
/usr/lib
/usr/lib/php4
/usr/lib/php4/20050606
/usr/lib/php4/20050606/mysql.so
/usr/share
/usr/share/doc
/usr/share/doc/php4-mysql

Copy /usr/lib/php4/20050606/mysql.so file to /webroot/usr/lib/php4/20050606/mysql.so and related shared libs using /bin/l2chroot script:
# mkdir -p /webroot/usr/lib/php4/20050606
# cp /usr/lib/php4/20050606/mysql.so /webroot/usr/lib/php4/20050606/
# /bin/l2chroot /usr/lib/php4/20050606/mysql.so

Repeat above procedure to copy all your php shared modules such as php-imap (required for webmail), php-gd (GD module for php4 used by wordpress and other softwares), php-memcache etc.

Step # 5: Configure lighttpd to run from chrooted jail

Make sure fastcgi module is enabled:
# lighty-enable-mod fastcgiOutput:

Available modules: auth cgi cml fastcgi proxy simple-vhost ssi ssl trigger-b4-dl userdir
Already enabled modules:
Enabling fastcgi: ok
Run /etc/init.d/lighttpd force-reload to enable changes

Configure lighttpd by editing /etc/lighttpd/lighttpd.conf file:
# vi /etc/lighttpd/lighttpd.conf

The most importat part is server.chroot directive. Open config file:
# vi /etc/lighttpd/lighttpd.conf
Set server.chroot to /webroot:
server.chroot = "/webroot"

Above directive applies chroot() call to directory called /webroot. Once applied no one (except root user) can access file system outside /webroot directory.

Rest of the configuration directives is documented very well in file itself. Start your lighttpd:
# /etc/init.d/lighttpd start

Test jail setup

Create two test php files in /webroot/home/lighttpd

  • db.php : Test MySQL database connectivity, make sure you modify this file for correct MySQL server hostname, username and password.
  • test.php : Test php via phpinfo()

Open a web browser and type url http://yourdomain.com/test.php and http://yourdomain.com/db.php.

Congratulations, if you are able to run both db.php and test.php w/o problem. Always refer to /var/log/message (outside /webroot directory) for troubleshooting purpose. If you see error message that read as follows (tail -f /var/log/message) :

php5-cgi[7325]: segfault at 0000000000001e98 rip 00002ad2cf6bd101 rsp 00007fffdb3f1ed0 error 4

To fix this problem, copy all shared libs from /lib and /usr/lib to /chroot (or /lib64 & /usr/lib if you are using 64 bit Linux) directory. But please do NOT copy any executable files from /bin/ /usr/bin or /usr/sbin directory.
# cp -avr /lib/* /webroot/lib/
# cp -avr /usr/lib/* /webroot/usr/lib/

Follow these instructions for more information.

Size of the /webroot jail

Here is size of webroot jail:
# du -chOutput:

28K     ./var/www
104K    ./var/log/lighttpd
108K    ./var/log
4.0K    ./var/run
4.0K    ./var/tmp/lighttpd/cache/compress
8.0K    ./var/tmp/lighttpd/cache
12K     ./var/tmp/lighttpd
16K     ./var/tmp
160K    ./var
4.0K    ./tmp
5.9M    ./usr/bin
2.7M    ./usr/lib/i686/cmov
2.7M    ./usr/lib/i686
48K     ./usr/lib/php4/20050606
52K     ./usr/lib/php4
7.5M    ./usr/lib
14M     ./usr
1.7M    ./lib/tls
2.0M    ./lib
44K     ./etc/php4/cgi
48K     ./etc/php4
56K     ./etc
16K     ./home/lighttpd
20K     ./home
16M     .
16M     total

As you see our jail only took 16MB disk space. I will address rest of the issues such as perl support and sendmail problem tomorrow :)

Continue reading the rest of Lighttpd series articles.

Updated for accuracy.

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 79 comments… read them below or add one }

1 Mr November 24, 2006 at 10:09 am

Hi, thanks for your great howto but i my phpinfo() i don’t have mysql suppot:

Configure Command: ‘–without-mysql’

why?

Thanks for all.

Reply

2 nixCraft November 24, 2006 at 10:32 am

hi!

Did you install php4-mysql or php5-mysql package? Use apt-get to install php mysql support package. Next copy mysql.so shared object to jail (see above for instruction). Restart lighttpd and test it again with phpinfo()

Reply

3 Mr November 24, 2006 at 12:52 pm

hi nixcraft
thanks to answer, I have done just like you indicate step by step

apt-get install lighttpd

(first i installed lighttpd with unstable and later)

apt-get install php4-cgi php4-cli php4-mysql mysql-server (with stable)

Reply

4 nixCraft November 25, 2006 at 8:39 am

I hope it is working now….

Reply

5 Alexander Girao November 30, 2006 at 5:24 pm

nice work!

a little tip: instead of using the l2chroot script, you could simply do:

# ldd usr/bin/php4* | awk ‘{if ($3 ~ /^[^ (]/) print $3}’ | cpio -pdvuL /webroot

thanks for the nice article!

Reply

6 nixCraft November 30, 2006 at 6:57 pm

Alexander,

Nice and dirty one-liner / shell pipe :)

Appreciate your post.

Reply

7 contundax December 9, 2006 at 12:27 am

I am not sure what happened here:

/etc/init.d/lighttpd start
* Starting web server lighttpd Duplicate config variable in conditional 0 global: fastcgi.server
2006-12-08 16:25:02: (configfile.c.827) source: /etc/lighttpd/conf-enabled/10-fastcgi.conf line: 27 pos: 1 parser failed somehow near here: (EOL)
2006-12-08 16:25:02: (configfile.c.827) source: /usr/share/lighttpd/include-conf-enabled.pl line: 2 pos: 1 parser failed somehow near here: (EOL)
2006-12-08 16:25:02: (configfile.c.827) source: /etc/lighttpd/lighttpd.conf line: 161 pos: 1 parser failed somehow near here: (EOL)
[fail]

Reply

8 nixCraft December 9, 2006 at 12:49 am

Hello,

You have config directive error.

What versions of OS/distro, and lighttpd do you use?

Reply

9 contundax December 9, 2006 at 2:31 am

OK, I backed up the original lighttpd.conf and copied the one provided above. Now the db.php link provides:

Fatal error: Call to undefined function: mysql_connect() in /home/lighttpd/db.php on line 5

Reply

10 contundax December 9, 2006 at 2:39 am

sorry you asked for my distro and version information as well:

d# apt-show-versions | grep lighttpd
lighttpd/edgy uptodate 1.4.13~r1370-1ubuntu1

Reply

11 nixCraft December 9, 2006 at 10:03 am

PHP5 mysql support is not loaded. Try as follows:

Make sure dir /webroot/etc/php4 exists with php.ini file

Make sure following files are also copied to /webroot/etc/ directory
cp /etc/hosts /webroot/etc/
cp /etc/nsswitch.conf /webroot/etc/
cp /etc/resolv.conf /webroot/etc/
cp /etc/services /webroot/etc/

Make sure you run l2chroot command on mysql.so mysqli.so and ld.so files located in /webroot/usr/lib/php4/2005xxxx directory
cd /webroot/usr/lib/php4/2005xxxx
/bin/l2chroot gd.so
/bin/l2chroot mysql.so
/bin/l2chroot mysqli.so

Restart lighttpd and it should work :).

I have actually updated this tutorial and retested all instructions for Ubuntu Linux 64 bit. It is recommended that you just remove all files from /webroot and just follow tutorial again. Let me know…

Reply

12 HostingGeek December 19, 2006 at 1:19 am

If your /etc and /webroot/etc are on the same partition, you can also create hardlinks to the files inside the chroot jail. This would be helpful if you ever needed to change the resolv.conf or other files.

Reply

13 nixCraft December 19, 2006 at 1:25 am

Hello,

No they are not on same partition, this is done for security reason.

Appreciate your post!

Reply

14 amir January 12, 2007 at 6:15 pm

Why this errors occurs:

linux:/home/amir# /bin/l2chroot /usr/bin/php5
(0xffffe000) /lib/tls/libcrypt.so.1 /usr/lib/libz.so.1 /usr/lib/libpanel.so.5 /lib/libncurses.so.5 /usr/lib/i686/cmov/libssl.so.0.9.8 /usr/lib/libpcre.so.3 /usr/lib/libdb-4.4.so /lib/libbz2.so.1.0 /lib/tls/libresolv.so.2 /lib/tls/libm.so.6 /lib/tls/libdl.so.2 /lib/tls/libnsl.so.1 /usr/lib/libgssapi_krb5.so.2 /usr/lib/libkrb5.so.3 /usr/lib/libk5crypto.so.3 /lib/libcom_err.so.2 /usr/lib/libxml2.so.2 /lib/tls/libc.so.6 /usr/lib/i686/cmov/libcrypto.so.0.9.8 /usr/lib/libkrb5support.so.0
cp: cannot stat `(0xffffe000)': No such file or directory
linux:/home/amir#

need helps

Reply

15 nixCraft January 12, 2007 at 7:45 pm

amir,

0xffffe000 (related to /lib/ld-linux.so.2 file) is not file so you see the error but script has copied other files. You need to copy /lib/ld-linux.so.2 (32 bit linux) to /webroot/lib directory (see above for cp command).

I have updated script to fix these warning.
http://www.cyberciti.biz/files/lighttpd/l2chroot.txt
Enjoy!

Reply

16 TECK April 17, 2007 at 2:26 am

I’m trying to run this tutorial on CentOS.
Everything looks ok, except that the spawn-fcgi cannot be created, even if the /tmp folder is chmomded 777.
Do I need to apply any patches to lighty? Hope not.
If you want me to paste my install steps, let me know.

The funiest part is that you cannot find on Google any other tutorials similar to this one. The CentOS and Lighty forums are totally absent, related to this vital information (setting the chroot).

Reply

17 nixCraft April 17, 2007 at 9:11 am

TECK,

For CentOS/Fedora/RHEL you need to use different package name and options. If you are using stable 1.4.xx no need to patch up init.d script. For 1.5.xx you need to patch up the init.d script to work.

Also make sure php compiled or installed as FastCGI (php –v). Let me know if you need detailed instructions regarding CentOS.

HTH

Reply

18 ali April 17, 2007 at 11:28 am

Thanks Vivek for the tutorial, that’s just what I need.

I have got a question in my mind about accessing my chrooted server trough FTP. I have set up an FTP server (Pure-FTPd) but I can’t cd to the /webroot/home/lighttpd directory because of its permissions. Since it has CHMOD’ed to 0700 only the owner (www-data) can view, write and execute files inside the directory.

Seems like I have two alternatives to overcome this issue;
I can configure Pure-FTPd to run as www-data and connect directly with the user www-data. Alternatively, after configuring Pure-FTPd to run as www-data, I may also create a virtual user chroot’ed to /webroot/home/lighttpd as home directory.I can CHMOD /webroot/home/lighttpd to 755, and can access files inside directory via FTP with my unix account.
Which one is more secure? Or, is any of these solutions rational at all? :)

Reply

19 ali April 18, 2007 at 4:26 pm

Another idea;

I can add my unix user account to group www-data, and CHMOD the /webroot/home/lighttpd to 750. Then I can connect via FTP with my user name and password and can read&write the content inside.

How about this? :)

PS: Sorry for the messy formating of my previous comment. I have actually used the ul and li tags, but seems like WordPress stripped them.

Reply

20 nixCraft April 18, 2007 at 6:28 pm

ali,

There are many ways

Method # 1: Add a user to www-date, and chroot jail the user, use ftpd umask for correct permission

Method # 2: Use Linux ACL + FTPD chroot jail

>Which one is more secure?
ftp Chroot jail, IMPO.

HTH

Reply

21 ali April 20, 2007 at 7:27 am

Thanks for your help Vivek, appreciated. I’ve decided to use your “Method # 1″, which sounds easier to implement.

Reply

22 mastr May 8, 2007 at 4:51 pm

great article, there are way too few chroot howto’s on the web and hard finding good information about it.

Reply

23 magnus June 1, 2007 at 2:28 pm

I’ve followed this tutorial to the letter multiple times, and I’ve received the same result:

2007-06-01 10:36:50: (mod_fastcgi.c.1042) the fastcgi-backend /usr/bin/php-cgi failed to start:
2007-06-01 10:36:50: (mod_fastcgi.c.1046) child exited with status 9 /usr/bin/php-cgi
2007-06-01 10:36:50: (mod_fastcgi.c.1049) if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.
You can find out if it is the right one by executing ‘php -v’ and it should display ‘(cgi-fcgi)’ in the output, NOT (cgi) NOR (cli)
For more information check http://www.lighttpd.net/documentation/fastcgi.html#preparing-php-as-a-fastcgi-program
2007-06-01 10:36:50: (mod_fastcgi.c.1351) [ERROR]: spawning fcgi failed.
2007-06-01 10:36:50: (server.c.849) Configuration of plugins failed. Going down.

Recently, lighttpd has been running flawlessly on my system. It’s only when I attempt to jail it that I receive these errors.

Reply

24 nixCraft June 1, 2007 at 9:12 pm

Did you installed php4-cgi or php5-cgi package? If not plz install the same. If it is installed open lighttpd file find line
/usr/bin/php-cgi
and replace it with
/usr/bin/php4-cgi

Reply

25 magnus June 3, 2007 at 10:47 pm

I’m using the php5-cgi package. I replaced /usr/bin/php-cgi with /usr/bin/php5-cgi and I still receive the same error.

Reply

26 TECK June 12, 2007 at 7:28 pm

Hi Vivek,

>> Let me know if you need detailed instructions regarding CentOS.
You can give me some guidance, no need to be super detailed. Basically is the same like your tutorial except you use php instead of php and /modules instead /20050606…

Let me know what other steps you take. Thanks.

Reply

27 nixCraft June 12, 2007 at 8:41 pm

TECK,

Only path and file names are changed so if you have a little experience with Linux, you should able to chroot php

Reply

28 Zoran June 13, 2007 at 7:35 pm

Hi,

I also get error msg when testing db.php:

Fatal error: Call to undefined function: mysql_connect() in /var/www/db.php on line 5

I followed all steps, but no luck for mysql.

btw I cannot find file mysqli.so ? where it should be?

Reply

29 radeone July 3, 2007 at 1:52 am

how would you configure rails with this type of setup because im having a hard time getting it to work.

Reply

30 Shoghi August 13, 2007 at 10:21 pm

I have used this procedure on fedora core 4 using php5 and worked ok!

I just changed the lighttpd configuration file to point to the actual directory of php-cgi.

I got the PHP error about the fcgi, after a while I used strace to get some answers. The error was mysql.so unable to load the mysql client library. I made a soft link to the mysql client library in the lib directory (inside the webroot jail of course, l2chroot copied it to the /webroot/usr/lib/mysql) and the problem was fixed.

Reply

31 tomcat August 21, 2007 at 10:32 pm

I got always this Error:
Warning: mysql_select_db() [function.mysql-select-db]: Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (40) in /home/lighttpd/db.php on line 6

I Try to let php/lighttpd use TCP and noch Socket but it dosnt work :(

Reply

32 J2S September 23, 2007 at 7:50 am

Hi Vivek, first let me say thank you for all your hard work, it has helped me in abundance :).

My problem is I am trying to chroot on CentOS 4.5 and have adapted your tutorial somehwat however when I reach finding mysql.so it can’t be found because I’m using php5 and apparently mysql extension is noy bundled with php anymore. I do have mysql installed however as I installed from source but still there is no mysql.so.

Is it possible to get some advice here and if you have time CentOS tutorial? Many thanks.

Reply

33 nixCraft September 24, 2007 at 3:42 am

J2S,

Under CentOS you need to install php-mysql binary package

Reply

34 Zeng October 12, 2007 at 6:35 pm

I have the same error as the person above:

Warning: mysql_pconnect() [function.mysql-pconnect]: Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)

Mysql is running in its own chrooted environment. Is there any solution except creating a hardlink?

Reply

35 nixCraft October 12, 2007 at 7:17 pm

Zeng,

My MySQL also run in chrooted jail and I connect it via loopback IP 127.0.0.1 port 3306.

HTH

Reply

36 twinrix November 3, 2007 at 9:07 am

Hi nice howto!

I am running a Debian Etch amd64 distri and did exactly the same as in this howto. Ok I admit I used php5. :)

The db.php works fine if I use my local mysql server, but if I try to connect to another server, I get the following error message:

Warning: mysql_connect() [function.mysql-connect]: Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111 in /home/lighttpd/db.php on line 5

Futhermore, I am having trouble with DNS; which means if I use example.com it will not find it.

And yes I have copied all necessary files.

It would be great if anyone had an idea.

Cheers

Reply

37 nixCraft November 3, 2007 at 2:27 pm

twinrix,

I don’t have problem connecting mysql hosted on pnet (private IP on same network but w/o public connectivity). Make sure resolv.conf and binary libs are copied. Also if you have problem run strace from chroot to debug exact problem.

Reply

38 twinrix November 3, 2007 at 4:44 pm

hi vivek,

thank you soooo much!!!
I was able to detect a couple of missing libs and just copied them by hand.

Cheers

Reply

39 Dougal November 5, 2007 at 9:06 pm

I get:

Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’

when I try to run db.php

When I tried following the instructions in the strace from chroot link, all I got is “php command not found”.

Can anyone suggest anything? I’m a bit of a newbie :/

Reply

40 Dougal November 5, 2007 at 11:01 pm

Oops, I solved that little problem, then, by running the command with php5 instead of php, but now I’m not sure what to do with the output of debug.txt…

There are lots of libraries being listed and most of them seem to be in webroot already.

Reply

41 nixCraft November 6, 2007 at 9:20 am

Dougal,

Use l2chroot to copy all shared libs.

HTH

Reply

42 Dougal November 6, 2007 at 7:37 pm

thanks, but I’m not sure how to do that? I already tried following the instructions in the tutorial for copying shared libs. How do I know what other libs are shared?

Reply

43 Dougal November 6, 2007 at 9:04 pm

I think I have all the libraries copied, but I still get “lost connection” when connecting…

Warning: mysql_connect() [function.mysql-connect]: Lost connection to MySQL server during query in /home/lighttpd/dgraham.net/public/db.php on line 5

Reply

44 Dougal November 6, 2007 at 9:37 pm

when running strace it says:

Fatal error: Call to undefined function mysql_connect()

And no libs appear to be missing except for libnss_db.so.2, but that can’t be the problem because I just don’t have that lib at all, and the script runs fine outside of chroot.

Reply

45 Arnaud D December 3, 2007 at 12:37 am

Installation went fine on CentOS, I didnt know that was so simple to chroot myslq php like that just by copying libs, great tut

Reply

46 Arnaud D December 3, 2007 at 12:15 pm

I just have one trouble using chroot on CentOS, each time I stop the service its FAILED for stopping the lighttpd pid, but it stops the spawn-fcgi process correctly, any idea what do I need to upgrade ?
Im using the modded init.d/lighttpd

start() {
echo -n $”Starting $prog: ”
daemon $lighttpd -f $LIGHTTPD_CONF_PATH
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
/usr/local/bin/spawn-fcgi -s /chroot/tmp/heap.socket -f /chroot/usr/bin/php-cgi -u heapoverflow.com -g heapoverflow.com -C 5 -P /tmp/spawn-fcgi.pid
chmod 0777 /chroot/tmp/heap.socket
return $RETVAL
}

stop() {
echo -n $”Stopping $prog: ”
# MYPID=`cat “/tmp/lighttpd.pid” 2>/dev/null `
# /bin/kill “$MYPID” >/dev/null 2>&1
killproc $lighttpd
killproc php-cgi
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
[ -f /tmp/heap.socket ] && /bin/rm -f /tmp/heap.socket || :
[ -f /tmp/spawn-fcgi.pid ] && /bin/rm -f /tmp/spawn-fcgi.pid || :
chmod 0777 /chroot/tmp/heap.socket
return $RETVAL
}

Please help

Reply

47 Arnaud D December 3, 2007 at 4:21 pm

Ok I have fixed several probs with CentOS,

If you use spawn-fcgi you will have to:

mkdir /webroot/bin
cp /bin/sh /webroot/bin/
l2chroot /webroot/bin/sh

This has been discussed here

http://forum.lighttpd.net/topic/23711

and so PHP is looking for the mysql.sock file in /var/lib/mysql/mysql.sock

so open my.cnf

just change the line

socket = /var/lib/mysql/mysql.sock

to socket = /webroot/var/lib/mysql/mysql.sock

then

mkdir -p /webroot/var/lib/mysql/
chown mysql:mysql /webroot/var/lib/mysql/
/etc/init.d/mysqld restart

and modify in /etc/init.d/lighttpd the spawn-fcgi line to have the option “-c /chroot”

After that I still need help here because I can start services , but when stopping lighttpd and php-cgi are reported [FAILED] and I can only killall manually wich is boring, thanks :)

Reply

48 Arnaud D December 3, 2007 at 5:26 pm

Ok good news , I fixed the start/stop problem, just make sure the pids are in the /var/run directory, not much , and edit the init.d/lighttpd script by renaming the spawn-fcgi.pid occurence to php-cgi.pid because the living process is recognized under “php-cgi” name :)

Reply

49 Arnaud D December 4, 2007 at 2:36 pm

To note that if you have the /bin/sh problem to put in the /chroot jail this has been fixed in svn 2026

instead of to use spawn-fcgi -f [binary] put -f [binary]at the end of the line and replace -f by —

http://trac.lighttpd.net/trac/ticket/1428

Reply

50 Ulrich December 7, 2007 at 9:04 pm

Thanks for this great tutorial. Works perfectly with Ubuntu + PHP5 + Perl. But I have one question:
The lighttpd executable is not called from the jail. Would it be possible for an attacker to exploit lighttpd directly (not PHP or Perl) and gain access to the system?

Reply

51 Piotr January 23, 2008 at 7:31 pm

Great article!

On some Debian servers you need to copy also library:

cp /lib/libnss_dns.so.2 /webroot/lib/

Without that your chrooted apps (including php) won’t be able to access host by hostnames:

————————————————
/webroot/var# chroot /webroot curl -I “www.yahoo.com”
curl: (6) Couldn’t resolve host ‘www.yahoo.com’
————————————————

Best regards
Piotr

Reply

52 gawwdotnet March 26, 2008 at 10:53 pm

I took this tutorial, and made a script out of it. Thought I would share since it was very helpful. You can alter /etc/php5 and re-run the script, it will update the dir, etc..

From a fresh Ubuntu install, after installing the appropriate packages and running this script I find all I need to do is setup the lighttpd home directories. :)

See my script – webroot-fresh.sh

Reply

53 daddelkopp April 10, 2008 at 6:39 am

I used this tutorial with Debian Etch rc3 and PHP5. It works fine until I want to use php fastcgi. After enable FASTCGI with “lighty-enable-mod fastcgi”, I changed /etc/lighttpd/conf-enabled/10-fastcgi.conf:

FROM:"bin-path" => "/usr/bin/php4-cgi",
"socket" => "/tmp/php.socket",

TO:"bin-path" => "/webroot/usr/bin/php5-cgi",
"socket" => "/webroot/tmp/php.socket",

After restart lighttpd I get an error message:
“unix: /webroot/tmp/php.socket could not be found or is not writeable”

The folder /webroot/tmp is chmood 1777 and owned by root:root. What did I do wrong? I performed this howto twice with a fresh debian installation. The folder /webroot is a partition mapped by fstab. Could that be the problem?

Reply

54 nixCraft April 10, 2008 at 6:42 am

daddelkopp,

Under chroot jail you cut /webroot dir as it is changed to / – so try as follows and restart lighttpd:
"bin-path" => "/usr/bin/php5-cgi",
"socket" => "/tmp/php.socket",

Reply

55 daddelkopp April 10, 2008 at 7:00 am

Thanks for your fast replay vivek. In this case lighttpd report 4 errors. It could not start/find 4 .pdo files (mysql,mysqli…). Because Iam not at home, I could not write the correct error message. I will try it in the evening again.

Thanks for your time and work
daddelkopp

Reply

56 daddelkopp April 10, 2008 at 7:32 pm

The last error was, that I forgot to copy some php libs. Everything is fine now :)

Reply

57 Mike April 30, 2008 at 1:11 pm

Hi,

I’m getting this:

~# dpkg -L php5-mysql
/.
/usr
/usr/lib
/usr/lib/php5
/usr/lib/php5/20060613+lfs
/usr/lib/php5/20060613+lfs/mysql.so
/usr/lib/php5/20060613+lfs/mysqli.so
/usr/lib/php5/20060613+lfs/pdo_mysql.so

I guess I can just adapt it with the given names above? Are there other little hitches on a current Debian Etch system? Is it possible to put 'Tomcat' in jail too? Thank you so much for this great website!!

Reply

58 Mike April 30, 2008 at 1:30 pm

The step when you create ‘/var/www/’ and ‘/var/run/’ within webroot is missing.

I’m getting this after step 5:

/etc/init.d/lighttpd start
Starting web server: lighttpd2008-04-30 03:24:03: (configfile.c.1114) base-docroot doesn't exist: /webroot/var/www/
2008-04-30 03:24:03: (server.c.564) setting default values failed
failed!

Reply

59 nixCraft April 30, 2008 at 1:53 pm

Mike,

Yes, you need to use current path:

/usr/lib/php5/20060613+lfs/mysql.so
/usr/lib/php5/20060613+lfs/mysqli.so

You can run almost anything in jail including tomcat, python and other stuff. All you have to do is copy required to jail.

> base-docroot doesn’t exist: /webroot/var/www/

You need to follow modified lighttpd.conf file. In jail /webroot/var/www becomes /var/www only. This tutorial changes /var/www to /home/lighttpd/domain1.com. Refer config file.

Reply

60 Mike April 30, 2008 at 2:03 pm

Ahhh…now I see. The step where you have to create the ‘/var/www’ and the ‘/var/run’ within the /webroot is missing in this tutorial. Thanks for the fast reply! However, if I start lighty I get a bunch of errors (spawning fcgi etc.), I’m now very insecure, I guess i leave it alone as I’m not enough experienced to adapt it to Debian Etch 4, MySQL5, PHP5 and Tomcat5 (in the end I make somewhere a mistake and it’s not more secure then before). :-(

Reply

61 Mike April 30, 2008 at 2:51 pm

Hmmm…I guess I got it. I had to copy the ‘pdo.so’ file to, which was not showing with ‘dpkg -L php5-mysql’ :-)

Reply

62 Mike April 30, 2008 at 4:14 pm

Question: What about the ‘*.pid’ files? Can they stay where they are or do I have to copy them into the jail too?

Reply

63 mdev July 20, 2008 at 11:59 am

Thanks although some things do not work when using your tutorial and need changes I got it running and learned alot on trial and error.

Reply

64 niyo March 18, 2009 at 2:35 am

hi

Can this chrooted setup be managed by cpanel or ispconfig?

rgds
Niyo

Reply

65 nixCraft March 18, 2009 at 8:19 am
66 Janez Dolinar April 17, 2009 at 10:13 am

(i know this is an old reply but I had the same problem)

@magnus: make sure, you copied files correctly. In my case I had /webroot/lib64 as a file!

Reply

67 L1ttl3J1m April 30, 2009 at 9:53 am

For $DEITY’s sake, don’t approve that last one :) Try this one instead.

I had some trouble getting it to work, but here’s some stuff I worked out.

For missing libraries (blahblah.so.whatever) you can do this;

ldd ./ – Which you can find by looking in the PHP error log. I found it especially good for this one;

PHP Startup: Unable to load dynamic library ‘blahblah.so’ – File not found in Unknown on line 0

So do an LDD on that file (ldd ./ (be in the directory where the file is, of course)) and it outputs the libraries that that extension needs to run – scatter those around in the jail versions of /lib, /opt/lib, usr/lib, /usr/local/lib, and those errors stop happening.

For the ones that it didn’t make go away (I’m looking at you, MySQL!), doing;

ldconfig -p | grep (name of broken process**)

will give you a few more to copy across.

The thing that I was wondering about though, is how to go about securing that tmp folder. I don’t like the idea of having a world-executable folder on my server, no matter how jailed it is.

Any ideas?

*Make sure you don’t forget to set that one to a path that’s inside the jail, too, otherwise PH can’t write to it and you’ll never see these handy-dandy helpful messages. ***

** MySQL, grep bz for bzip & bzip2, for example – one for each extension that’s in your PHP.ini file, basically.

*** That’s sarcasm, by the way. File not found in Unknown at line 0, yeah that’s helpful!

Reply

68 maxBirdy November 9, 2009 at 1:35 am

i run through this whole tutorial

i make sure that /home/lighttpd/ is the root dir

and that /webroot is the chroot jail

then i restart lighty

all is good, and it restarts without any errors

then i type in, 127.0.0.1, or 192.168.1.8, firefox goes “Firefox can’t establish a connection to the server at x.x.x.x” my port 80 is forwarded, but when i go to canyouseeme.org, it says port 80 is not in use.

i run ps aux in bash shell, i see nothing that says “lighttpd”

im using php5, mysql 5.1, and lighttpd 1.4.23

wtf is wrong with my setup, just because my software is newer shouldnt change anything right?

the.conf files for lighty on this site, and mine, are identical, in configuration, but mine has a few other settings that are commented out so i just leave them be.

i have even checked my error logs, not a damn thing is in them

and ive checked my network configuration, all is well there too.

plllleeeeeeeaaaaaaaasssssseeeeeeeeeee help, im really lost and frustrated.

Reply

69 mandible January 5, 2010 at 12:45 am

this website sucks, typical linux users who dont give a shit about noobies who need help, this tutorial doesnt work. install latest debian, and use php5 instead of 4, and follow this tutorial, it doesnt work.

Reply

70 grand wazoo January 29, 2010 at 4:39 pm

If you’re a “noobie who need[s] help,” then you shouldn’t be preparing an externally facing chroot’ed security-critical linux web server installation. Pay someone to do this for you. Security is really, really, really hard. Buck up.

Reply

71 SilentHunter March 12, 2010 at 4:51 pm

Sorry but again to this problem:

————————————————————————————————————
I used this tutorial with Debian Etch rc3 and PHP5. It works fine until I want to use php fastcgi. After enable FASTCGI with “lighty-enable-mod fastcgi”, I changed /etc/lighttpd/conf-enabled/10-fastcgi.conf:

FROM:
“bin-path” => “/usr/bin/php4-cgi”,
“socket” => “/tmp/php.socket”,

TO:
“bin-path” => “/webroot/usr/bin/php5-cgi”,
“socket” => “/webroot/tmp/php.socket”,

After restart lighttpd I get an error message:
“unix: /webroot/tmp/php.socket could not be found or is not writeable”
————————————————————————————————————–

Is there a better solution than cutting the /webroot? I get the same error with the socket but without the /webroot it wouldn’t work anyway….

Reply

72 james April 12, 2010 at 9:52 am

Hi. I have followed carefully each steps and I received this error when starting lighttpd:

(mod_fastcgi.c.1042) the fastcgi-backend /usr/bin/php-cgi failed to start:
(mod_fastcgi.c.1046) child exited with status 9 /usr/bin/php-cgi
(mod_fastcgi.c.1049) if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.
You can find out if it is the right one by executing ‘php -v’ and it should display ‘(cgi-fcgi)’ in the output, NOT (cgi) NOR (cli)

lighttpd has been working fine before I wanted to put it in jail. whenever I comment out the server.chroot line. everything works ok.

i have set correctly /usr/bin/php-cgi correctly to /usr/bin/php5-cgi but still the same error.

Reply

73 lfitz June 16, 2010 at 1:31 am

hi, i get 403 – forbidden errors for db.php and test.php, how can i fix this?

Reply

74 Julien August 29, 2010 at 7:58 pm

Thanks for the howto, I used it as a based to my own script that chroot nginx and php on Debian. I believe it might be of interest to some of the readers here, so here is the link.

Reply

75 Christoph December 6, 2010 at 5:14 pm

nice tutorial

The default path of the compress cache directory in Debian is now “/var/cache/lighttpd/compress/”.

So the diretory “/webroot/var/cache/lighttpd/compress/” should exists to work (instead of the directory in the tutorial). ;)

Reply

76 jh December 16, 2010 at 2:49 am

Followed the guide to put my lighttpd server into jail. All working fine except DNS resolution not working in chroot jail. Turn out I have to copy both libnss_dns.so.2 and libnss_dns-2.7.so from /lib to /webroot/lib. Great guide.

Reply

77 maximebuy April 13, 2011 at 10:48 pm

I followed the instruction and got 400 error also. Then I made the following changes:
1. change the base dir in /etc/lighttpd/lighttpd.conf from /var/www to /home/lighttpd
2. change the cache dir from /webroot/var/tmp/lighttpd/cache/compress/ to /webroot/var/cache/lighttpd/compress/
3. change the /etc/lightpd/conf-enablede/10-fastcgi.conf, where /usr/bin/php-cgi to /usr/bin/php5-cgi

Then I can open the db.php and test.php, my system is “PHP Version 5.2.6-1+lenny10″.

After these three steps, there are still some error in output of db.php, just see the log file in /webroot/var/log/lighttpd/error.log and check the errors.

Reply

78 none-101 October 17, 2011 at 3:01 pm

Where do you put the static web files that one wishes to serve?
I have these on /www/ Is it possible, using your set-up above to still server from /www. These are on different partitions.

Regards.

Reply

79 Nguyen Thanh Binh June 5, 2013 at 9:32 am

Thanks for your the article… It’s very great.

Reply

Leave a Comment

Previous post:

Next post: