Install chrooted lighttpd under Ubuntu Linux 64 bit version

This is a common question and it is asked again and again:

How do you install & configure secure chrooted lighttpd under Ubuntu 64 bit version? I need to configure:

* PHP 5
* MySQL 5 Server via localhost ( TCP/IP
* Lighttpd latest version
* Perl
* php mail() support
* etc

Following are instructions for php5, MySQL 5 database and latest lighttpd in chrooted jail under 64 bit Ubuntu Linux.

You will learn how to configure and install secure lighttpd server along with PHP5 and MySQL server version 5. Instruction mentioned below also work with 32 bit version. See original article for more information.

#1: Install lighttpd

# apt-get install lighttpd

#2: Install MySQL server 5

#apt-get install mysql-server
PHP will talk to mysql using TCP/IP socket. By default Ubuntu MySQL server is configured to accept connections from localhost 🙂

#3: Install php5, php5 mysql, gd support

# apt-get install php5-cgi php5-mysql php5-gd php5

#4: Now create a chrooted enviorment in /webroot directory

# mkdir /webroot
# mkdir /webroot/tmp/
# chmod 1777 /webroot/tmp/
# mkdir /webroot/etc

#5: Copy files to /webroot /etc directory

Following file ensure that DNS name quires work from chrooted lighttpd server.
# 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/

#6: Create other directories

# mkdir -p /webroot/var/log/lighttpd
# chown www-data:www-data /webroot/var/log/lighttpd
# mkdir -p /webroot/var/tmp/lighttpd/cache/compress/
# chown www-data:www-data /webroot/var/tmp/lighttpd/cache/compress/
# mkdir -p /webroot/home/lighttpd
# mkdir -p /webroot/var/www
# chown www-data:www-data /webroot/home/lighttpd
# chown www-data:www-data /webroot/var/www
# chmod 0700 /webroot/home/lighttpd
# ls -dl /webroot/home/lighttpd

#7: Copy l2chroot script

Copy l2chroot script to bin directory. This script will install required shared libs in /webroot directory for php5-cgi executable and other shared libs:
# cd /bin
# wget
# mv l2chroot.txt l2chroot
# chmod +x l2chroot

#8: Install PHP in the jail

# mkdir -p /webroot/usr/bin
# cp /usr/bin/php5-cgi /webroot/usr/bin/
# cd /webroot/etc/
# cp -avr /etc/php5/ .
# /bin/l2chroot /usr/bin/php5-cgi

Copy linux 64 bit /lib64/ld* lib:
# mkdir /webroot/lib64
# cp /lib64/ /webroot/lib64

NOTE: If you are using 32 bit Ubuntu linux put ld libs in /lib directory:
# cp /lib/ /webroot/lib

#9: Copy and Install php5 mysql and gd support:

Find out php extension support directory name.
# dpkg -L php5-mysql


Note down /usr/lib/php5/20051025 directory name and create the same in /webroot. Next copy and libs to /webroot/usr/lib/php5/20051025:
# mkdir -p /webroot/usr/lib/php5/20051025/
# cp /usr/lib/php5/20051025/ /webroot/usr/lib/php5/20051025
# cp /usr/lib/php5/20051025/ /webroot/usr/lib/php5/20051025
# cp /usr/lib/php5/20051025/ /webroot/usr/lib/php5/20051025

Install shared lib support in chrooted jail:
# /bin/l2chroot /usr/lib/php5/20051025/
# /bin/l2chroot /usr/lib/php5/20051025/
# /bin/l2chroot /usr/lib/php5/20051025/

#10: Make sure fastcgi module is enabled

# lighty-enable-mod fastcgi

Open /etc/lighttpd/conf-enabled/10-fastcgi.conf file
# vi /etc/lighttpd/conf-enabled/10-fastcgi.conf
Set bin-path to PHP5 from PHP4:
"bin-path" => "/usr/bin/php5-cgi"

Save and close the file. Now open /etc/lighttpd/lighttpd.conf and setup chroot to /webroot directory:
server.chroot = "/webroot"

Save and close the file.

#11: Copy /lib64 and /usr/lib directories

This ensures that outgoing DNS quires or php XML support is loaded on fly i.e. it will copy required all shared directories:
# cp -avr /lib64/* /webroot/lib64/
# cp -avr /usr/lib/* /webroot/usr/lib/

If you are using 32 bit version:
# cp -avr /lib/* /webroot/lib/
# cp -avr /usr/lib/* /webroot/usr/lib/

#12: Restart lighttpd

And you are done! Just restart Lighttpd:
# /etc/init.d/lighttpd restart

# 13: Test jail setup

Create two test php files in /webroot/var/www directory:
=> 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()
# cd /webroot/var/www
# wget
# wget
# mv test.php.txt test.php
# mv db.php.txt db.php

Open db.php file:
# vi db.php
Set MySQL username and password:
$link = mysql_connect("", "root", "SET-PASSWORD");
Save and close the file. Fire a web browser and type url and

See all lighttpd related articles.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 21 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf duf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Modern utilitiesbat exa
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg glances gtop jobs killall kill pidof pstree pwdx time vtop
Searchingag grep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
21 comments… add one
  • Juke Dec 23, 2007 @ 23:34

    Nice howto, thanks! My problem: lighttpd quits without leaving an entry in error.log when i try to execute a php file through the webserver. The bin path to php is set correctly. Any ideas?

  • Mathias Jan 11, 2008 @ 3:29

    Great guide, but I have a couple of small problems, that you may have a solution for…

    1. Even though I have made a copy of hosts and resolv.conf to /webroot/etc/ I still cant use localhost to connect to the db. Works fine with, so its not really a big problem. And I have checked the hosts file, and localhost is in it.

    2. I would like to install phpMyAdmin to manage the MySQL, but since I have never installed anything in a chroot jail before, I dont know how. I assume the apt-get install phpmyadmin will do me no good, since the web-server is not where it normally should be.

    THX for the guide, tested on Ubuntu 7.10 (minimal) to be a complete no-brainer to follow. Just shut down your brain and copy-paste 😉

  • 🐧 nixCraft Jan 11, 2008 @ 3:37

    > I would like to install phpMyAdmin to manage the MySQL, but since I have never installed anything in a chroot jail before, I dont know how.
    install it under /webroot/var/www/phpmyadmin. Don’t forget to password protect phpmyadmin directory. If you are going to set large number of vhosts use /webroot/home/lighttpd/ /webroot/home/lighttpd/ directory structure.

  • Mathias Jan 12, 2008 @ 6:16

    THX for the reply vivek, it got me thinking that I could just install it with the package and the move it 🙂
    I even got i connecting and all, but there is one problem. I get the error

    Cannot load mcrypt check your PHP configuration

    But, mcrypt is installed and i have moved all the files that i could find with mcrypt in their name, to the same locatio under /webroot, but with no effect. Anyone got a suggestion.
    I am using the phpmyadmin so apperantly its not that bad, but it would be nice not to have errors in the setup 😉

  • morphey May 20, 2008 @ 21:42

    Hello everyone,

    in the latest version of ubuntu (hardy) is an error before restarting lighttp (with the basic configuration):

    2008-05-20 08:13:50: (server.c.908) Configuration of plugins failed. Going down.
    2008-05-20 23:34:55: (log.c.75) server started
    2008-05-20 23:34:55: (mod_compress.c.185) can't stat compress.cache-dir /var/cache/lighttpd/compress/ No such file or directory

    To resolve simply run:

    mkdir /webroot/var/cache/
    mkdir /webroot/var/cache/lighttpd/
    mkdir /webroot/var/cache/lighttpd/compress/

    and then start lighttpd:

    /etc/init.d/lighttpd start

  • james Nov 1, 2008 @ 8:03

    hey, thanks. It works for me, but could you provide a step to sync folders and files above so that we who still in development stage will benefit from it… (rsync maybe?)

  • james Nov 2, 2008 @ 9:34

    hmm.. after more research i can sync it but strange,mysql shows * Checking for corrupt, not cleanly closed and upgrade needing tables.
    every time i restart it. and I can’t install wordpress, phpmyadmin etc. the error said the database server is not responsive or cannot make connection. But, I can connect just fine with above test and I can connect too from command line. please help

  • james Nov 2, 2008 @ 9:37

    I’m using intrepid ibex ubuntu

  • 🐧 nixCraft Nov 2, 2008 @ 9:47


    Database cannot be just synced using rsync or cp command. You need to dump mysql using mysqldump and import using mysql

  • jared Feb 11, 2009 @ 17:06

    Thanks for this article. I’m a little confused on one point:

    I thought one of the main advantages of chrooting or jailing a server is that any attacker who compromises the server won’t be able to compile malicious code, due to not having the necessary libraries.

    So, if you copy all of /lib64 and /usr/lib into the jail, including /lib64/gcc for instance, haven’t you sort of given an attacker, if not the key to the jail, then some equipment that can be used to create a key?

  • 🐧 nixCraft Feb 11, 2009 @ 17:22

    @ jared,

    Noop, we just copied libs no headers or compiler itself. Also, in order to upload or download file most attacker depends upon tools like wget or others. Under jail none of the binaries or headers available.

    You can selectively copy files /lib64 such as resolvers by tracing used libs via ldd command.


  • jared Feb 12, 2009 @ 3:21

    I see! Thanks for clarifying.

    Copying /lib and /lib64 certainly seems quicker than running ldd for every executable I want to bring into the jail. So why is the ldd approach the only one I’ve seen in ‘apache security’ and the like? Any thoughts? Maybe just to keep chroot size down?

  • Laurens Feb 22, 2009 @ 19:49


    Thanks for the tutorial! It helped me a lot!
    Any tips on getting fam to work with lighttpd?

  • andy May 12, 2009 @ 17:06

    Thanks for the great tutorial, but I ran into a few pains in the arse. For some reason, the test file fails when trying to open both the passwd and hosts file. I’ve even chmodded them to 777 with no avail.

    This little issue screwed up my wordpress install, which I was able to work around (as far as I can tell, anyways) by changing the reference in the config file from “localhost” to, but I’m not sure if this will adversely affect me anywhere else down the line.

    Any ideas on fixing this?

  • Laurent May 16, 2009 @ 9:01

    @andy: I assume the reference you’re talking about is the database server. I’ve come across the fact that you can not connect to mysql server via tcp/ip using the name “localhost”, you have to use (which would be equivalent in most other contexts).
    Localhost somehow seems to force a unix socket connection, which in this context would not work, as your mysql server is not in the chroot.
    Now you could transfer your db server inside the chroot, but I don’t think it makes much sense. Probably better to put it in a different chroot, or a different server altogether, you’ll just need to change the IP address…
    I hope that makes sense :o)

  • mger Feb 9, 2010 @ 4:42

    A masterpiece! Thanks for the great guide.

  • Some Kid Mar 2, 2010 @ 15:58

    Some things I’ve picked up after having followed this tutorial… If you want to use some OpenSSL features in PHP, you must recreate /dev/random and /dev/urandom in /webroot/dev/* using the mknod command. Also to debug scripts/programs in a chroot environment use the strace utility to find out dependencies.

  • aza Aug 30, 2010 @ 12:02

    Hi Vivek,
    I’m unable to start the lighttpd services.
    did the following command /etc/init.d/lighttpd start

    below is the error logs in /var/log/messages/lighttpd/error.log

    2010-08-30 17:28:52: (log.c.166) server started
    2010-08-30 18:27:54: (server.c.1503) server stopped by UID = 0 PID = 10481

    please help.

  • juanchopx2 Dec 3, 2010 @ 20:00

    It doesn’t work for me =(

    The lightttpd service doens’t starts.

    This is what my /var/log/lighttpd/error.log:

    2010-12-03 04:45:00: (server.c.1389) [note] graceful shutdown started
    2010-12-03 04:45:00: (server.c.1503) server stopped by UID = 0 PID = 2717
    2010-12-03 04:45:01: (log.c.166) server started
    2010-12-03 04:57:46: (server.c.1503) server stopped by UID = 0 PID = 2988

    Any idea?


    • juanchopx2 Dec 3, 2010 @ 20:06

      Sorry about my English :p

  • Mike May 7, 2013 @ 21:51


    The browser gives: unable to connect to

    lighttpd is running.

    Any ideas how to begin to troubleshoot this ?


Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum