Lighttpd For Both SSL And Non-SSL
From ArchWiki
What is Lighttpd?
The lighttpd website gives a good definition.
"lighttpd a secure, fast, compliant and very flexible web-server which has been optimized for high-performance environments. It has a very low memory footprint compared to other webservers and takes care of cpu-load. Its advanced feature-set (FastCGI, CGI, Auth, Output-Compression, URL-Rewriting and many more) make lighttpd the perfect webserver-software for every server that is suffering load problems." -- http://www.lighttpd.net/
Goals
The goal of this how to is to setup lighttpd for servicing both ssl and non-ssl connections. php will be setup via a fastcgi prespawn, that will service both ssl and non-ssl connections. The php-fcgi instances will be run as a different user than the lighttpd daemon. eaccelerator will also be setup to increase the efficiency of our php scripts.
Required packages:
- lighttpd (compiled for mysql support)
- php-cgi (compiled for cgi/fcgi support)
- fast-cgi
- eaccelerator
- ssl
If you have trouble finding a package specific to this How-To, try the resources link at the bottom.
Lighttpd Installation
Step 1: Install the lighttpd package
I have lighttpd in my repository, and there is also a version in the AUR, courtesy of klapmuetz. The one in my repository currently contains a few extra things that we will be utilizing for this how to, but they can be obtained individually from my subversion repository if needed. The compiled binaries are the same in the two packages. Just a few different scripts and helper files.
# pacman -Sy lighttpd
Step 2: Add a user
We are going to be running lighttpd as a non-root user. So, we first need to create a user for this purpose, and a home directory. We will create a group too.
# groupadd lighttpd # useradd -g lighttpd -d /home/lighttpd -s /bin/false lighttpd
Step 3: Ensure permissions are properly set.
# chown -R lighttpd.lighttpd /home/lighttpd
Step 4: Edit the lighttpd.conf file located at /etc/lighttpd/lighttpd.conf
- Uncomment mod_fastcgi and mod_compress.
- Uncomment and change server.username to "lighttpd"
- Uncomment and change server.groupname to "lighttpd"
- Uncomment compress.cache-dir and compress.filetype
Save your changes
Step 5: Change logfile permissions
Since we are running the daemon as lighttpd user, we need to change the logfile permissions.
# chown lighttpd /var/log/lighttpd/*.log
Edit: You also need to edit the /etc/logrotate.d/lighttpd file, line 2. Change the user's 'nobody nobody' to lighttpd. This has to be done or the next time the log is rotated the permissions will be reset and the dameon will not start.
From:
/var/log/lighttpd/*log { create 644 nobody nobody compress postrotate /bin/kill -HUP `cat /var/run/lighttpd.pid 2>/dev/null` 2> /dev/null || true endscript }
To:
/var/log/lighttpd/*log { create 644 lighttpd lighttpd compress postrotate /bin/kill -HUP `cat /var/run/lighttpd.pid 2>/dev/null` 2> /dev/null || true endscript }
Step 6: Start the daemon.
# /etc/rc.d/lighttpd start
Check /var/log/lighttpd/error.log for any errors. Try bringing up a web page on the server. The default index page should come up. Hooray! You got lighttpd running as a user.
It is currently only servicing port 80 (non-ssl), so next we add ssl to the mix.
Lighttpd SSL
Step 1: First things first
Lighttpd can only service either ssl or non-ssl at one time. No problem. We can easily run two daemons. We need to do a little maintenance work in the lighttpd user directory first.
Update: This is no longer true. The version of lighttpd currently in the repositories can handle both ssl and nonssl in the same daemon. Most of what follows is not neccessary, although you may want to have separate directories for SSL and nonSSL data so that you do not serve up secure content unsecured by accident. See "SSL: Alternative Method" below. End Update
# /etc/rc.d/lighttpd stop # mkdir -p /home/lighttpd/ssl/html /home/lighttpd/ssl/cache # mkdir /home/lighttpd/nonssl # mv /home/lighttpd/html /home/lighttpd/nonssl # mv /home/lighttpd/cache /home/lighttpd/nonssl # cp /home/lighttpd/nonssl/html/index.html /home/lighttpd/ssl/html # chown -R lighttpd.lighttpd /home/lighttpd
Step 2: Copy things
Now we need to setup a separate config script, and init script for the ssl version.
# cp /usr/sbin/lighttpd /usr/sbin/lighttpd-ssl # cp /etc/rc.d/lighttpd /etc/rc.d/lighttpd-ssl # cp /etc/conf.d/lighttpd /etc/conf.d/lighttpd-ssl # cp /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd-ssl.conf
Step 3: Edit /etc/conf.d/lighttpd-ssl
Change to the following:
DAEMON_NAME="lighttpd-ssl" DAEMON_CONF="/etc/lighttpd/lighttpd-ssl.conf" DAEMON_PATH="/usr/sbin/lighttpd-ssl"
Step 4: Edit /etc/rc.d/lighttpd-ssl
Change to the following:
[ -f /etc/conf.d/lighttpd-ssl ] && . /etc/conf.d/lighttpd-ssl
Step 5: Edit /etc/lighttpd/lighttpd-ssl.conf
Change to the following:
server.document-root = "/home/lighttpd/ssl/html" server.errorlog = "/var/log/lighttpd/error-ssl.log" accesslog.filename = "/var/log/lighttpd/access-ssl.log" server.pid-file = "/var/run/lighttpd-ssl.pid" compress.cache-dir = "/home/lighttpd/ssl/cache" ssl.engine = "enable" ssl.pemfile = "/home/lighttpd/ssl/server.pem"
Step 6: Edit /etc/lighttpd/lighttpd.conf
Now that the ssl version is correct, we have to slightly modify the non-ssl version to deal with our new directory structure.
server.document-root = "/home/lighttpd/nonssl/html" compress.cache-dir = "/home/lighttpd/nonssl/cache"
Step 7: Create the self signed certificate
# cd /home/lighttpd/ssl # openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes # chown lighttpd.lighttpd server.pem # chmod 600 server.pem
Step 8: Start the daemons
# /etc/rc.d/lighttpd start # /etc/rc.d/lighttpd-ssl start
Check /var/log/lighttpd/error.log and /var/log/lighttpd/error-ssl.log for errors.
Step 9: Test
Try navigating with a web browser to both the http and https address of your server. Hoory! You just setup for ssl and nonssl serving using lighttpd.
SSL: Alternative Method
Create folders for SSL/html and SSL/cache as above. Create ssl key (.pem file as above) Edit /etc/lighttpd/lighttpd.conf Find the line ssl.engine, and change that area to $SERVER["socket"] == ":443" { server.document-root = "/srv/ssl/html" # use your ssl directory here ssl.engine = "enable" ssl.pemfile = "/etc/ssl/private/lighttpd.pem" # use the path where you created your pem file }
Then restart lighttpd with /etc/rc.d/lighttpd restart
SSL: Last step, redirection
The last step is to set up redirection. The following steps will redirect only certain pages or directories to ssl. For the example, we'll use a squirrelmail directory.
Edit /etc/lighttpd/lighttpd.conf Uncomment mod_redirect Then add the following lines: $SERVER["socket"] == ":80" { $HTTP["url"] =~ "^/squirrelmail/*" { $HTTP["host"] =~ "(.*)" { url.redirect = ( "^/(.*)" => "https://%1/$1" ) } } }
This will redirect any normal http requests for squirrelmail to https://host/squirrelmail
FastCGI and PHP with eAcceleration
Step 1: Install fastcgi and php compiled for cgi/fcgi
You may first need to uncomment these lines in /etc/pacman.conf.
[community] Include = /etc/pacman.d/community
Note: php-cgi is now obsolete, use php
# pacman -Sy fcgi php eaccelerator # /etc/rc.d/lighttpd-ssl start
N.B eaccelerator currently doesnt work with php 5.1.x
Step 2: Create a php user
# mkdir -p /home/phpuser/eaccelerator/cache # groupadd phpuser # useradd -g phpuser -d /home/phpuser -s /bin/false phpuser # chown -R phpuser.phpuser /home/phpuser
Step 3: Add eaccelerator to php.ini and make additional changes
Note. Make sure you use >> in the following command. If you use a single >, you will overwrite, instead of append. not good.
# cat /etc/php/conf.d/eaccelerator.ini >> /etc/php/php.ini
Step 4: Edit /etc/php.ini
zlib.output_compression = On cgi.fix_pathinfo=1 eaccelerator.cache_dir="/home/phpuser/eaccelerator/cache"
I additionally set safe_mod
to On
in my setup, but this is not required.
Step 5: Setup fcgi-php prespawns
Now we are going to setup a mechanism for spawning php instances to handle requests.
# chmod 755 /etc/rc.d/spawn-php
Step 6: Modify /etc/conf.d/spawn-php
You need to edit a few parts of the spawn-php init script
Change the following to reflect the php user you created earlier:
USERID=phpuser GROUPID=phpuser FCGISOCKET="/tmp/php-fastcgi.socket"
Step 7: Spawn the php instances
# /etc/rc.d/spawn-php start
You should get some sort of message saying that is has started child processes.
To check to see if it indeed has (the spawn script is a bit buggy yet, I haven't worked out the kinks in the wrapper portion).
$ ps afx || grep php 3192 ? Ss 0:00 /usr/bin/php 3193 ? S 0:00 \_ /usr/bin/php 3194 ? S 0:00 \_ /usr/bin/php 3195 ? S 0:00 \_ /usr/bin/php 3196 ? S 0:00 \_ /usr/bin/php 3197 ? S 0:00 \_ /usr/bin/php 3198 ? S 0:00 \_ /usr/bin/php 3199 ? S 0:00 \_ /usr/bin/php 3200 ? S 0:00 \_ /usr/bin/php 3201 ? S 0:00 \_ /usr/bin/php 3202 ? S 0:00 \_ /usr/bin/php 3203 ? S 0:00 \_ /usr/bin/php 3204 ? S 0:00 \_ /usr/bin/php
Step 8: Setup lighttpd and lighttpd-ssl to use the instances
Uncomment both /etc/lighttpd/lighttpd.conf and /etc/lighttpd/lighttpd-ssl.conf to the following:
fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/tmp/php-fastcgi.socket", "bin-path" => "/usr/bin/php-cgi" ) ) )
Step 9: Restart both daemons
# /etc/rc.d/lighttpd restart # /etc/rc.d/lighttpd-ssl restart
Check /var/log/lighttpd/error.log and /var/log/lighttpd/error-ssl.log for errors.
Step 10: Try a php page.
Create the following php page, name it index.php, and place a copy in both /home/lighttpd/ssl/html and /home/lighttpd/nonssl/html
<?php phpinfo(); ?>
Try navigating with a web browser to both the http and https address of your server. If you see the phpinfo page, then you are almost done! Hooray!
N.B eaccelerator currently doesnt work with php 5.1.x
Step 11: Check on eaccelerator caching..
# ls -l /home/phpuser/eaccelerator/cache
If the above command outputs the following:
-rw------- 1 phpuser phpuser 456 2005-05-05 14:53 eaccelerator-277.58081 -rw------- 1 phpuser phpuser 452 2005-05-05 14:53 eaccelerator-277.88081
Then you are done! Eaccelerator is happily caching your php scripts to help speed things up. Good luck with your setup. :D
Resources:
fastcgi and lighttpd - klapmuetz's how to on using lighttpd for ruby on rails. It also has good information on lighttpd setup.
Cacuts Repo Information - Information about my Archlinuxrepository. Packages used in this howto can be found there.