Lighttpd and a convenient way to support clean URLs

A lot of people run drupal with lighttpd, a light and fast webserver, which uses FastCGI to support PHP. As lighttpd doesn't read .htaccess files, some extra config is required to get drupal's clean urls working right.

I'm doing so already for a while now, finally I found the best way to do clean urls with lighttpd. I started with some url-rewriting regexes, which isn't ideal as there are problems with some special paths or dots. I've improved the regexes a bit, but still there were problems.

Another common way is to use a lua-script. The big advantage of this script is that one can do the url rewriting based on the condition whether there is a file for the requested path - so no regex magic is required. Thus there also no problems with dots.
The disadvantage of that approach is it's inflexibility. When you want to install multiple drupal instances in several different sub directories or use a script to generate settings for all your drupal instances, it's odd that the lua variant needs one script per drupal prefix, because you have to set the prefix in the lua script!

Finally I found a way to work around this inflexibility. First off I looked into passing the prefix variable into the lua script, but I had no luck with that. So I decided to go for another approach: I wrote a simple wrapper script, that creates the needed lua script with the right prefix set on the fly. So when lighttpd parses your configuration it calls the wrapper script, which makes sure there is a lua script in place and returns the suiting configuration for your drupal installation.

Ok, enough talk. Let's see how it works. First off make sure you have lighty's mod magnet module installed and enabled. In Ubuntu this can be done easily by running

apt-get install lighttpd-mod-magnet
lighty-enable-mod magnet

Next download my wrapper script and the lua script and extract it into your lighttpd configuration. The scripts assume it's in /etc/lighttpd - if not you have to adapt them.

cd /etc/lighttpd
wget http://more.zites.net/morefiles/lighty-drupal-lua-conf.tar.gz
tar xvzf lighty-drupal-lua-conf.tar.gz

Make sure drupal-lua-conf.sh is now in place and it's executable. Then just use it by adding

$HTTP["host"] =~ "your.domain.example.com" {
  include_shell "./drupal-lua-conf.sh"
}

if your drupal doesn't live an a subdirectory.

Else just give the subdirectory as argument to the script, e.g. I use

include_shell "./drupal-lua-conf.sh drupal-5"
include_shell "./drupal-lua-conf.sh drupal-6"
include_shell "./drupal-lua-conf.sh drupal-7"

Note that the script uses "drupal-lua.conf" as template for your drupal configuration - so you can just change it, reload lighty's config and all your drupal instances are running the changed config.

For a drupal install, which doesn't live in a subdirectory, the default template is:

  url.access-deny += ( "~", ".inc", ".engine", ".install", ".info", ".module", ".sh", "sql", ".theme", ".tpl.php", ".xtmpl", "Entries", "Repository", "Root" )

  # "Fix" for Drupal SA-2006-006, requires lighttpd 1.4.13 or above
  # Only serve .php files of the drupal base directory
  $HTTP["url"] =~ "^/.*/.*\.php$" {
      fastcgi.server = ()
      url.access-deny = ("")
  }

  magnet.attract-physical-path-to = ("/etc/lighttpd/drupal-lua-scripts/p-.lua")

Note that this configuration only executes .php files inside your drupal base directory - so users can't upload and execute .php files ;) If your webserver executes some other files, e.g. perl - you should add a check for them too. Then if you enable private file downloads you may want to protect your files with something like that:

$HTTP["url"] =~ "^/files" {
  #Be sure to have this below the inclusion of the lua script.
   url.access-deny = ("")
}

But be sure to move this code snippet below the inclusion of the lua script, or it won't work.

That's it.. :) Thanks to the simple wrapper script it's just a question of adding one line and your drupal installation is configured properly.

AttachmentSize
lighty-drupal-lua-conf.tar.gz1.2 KB

Comments

Exception to the "rules"

I have successfully implemented this CleanURL feature, thanks for the effort! But, I was wondering how you handle exceptions. For example, I have a drupal site but want to install phpbb3 under /forums. With your cleanURL package, it will always redirect to the home page. I want to exclude /forums from the rewrite. Is this possible?

phpbb forum integration bug

Thank's for your works! I have just a small problem with phpbbforum module (phpbb integration), the fix : # Only serve .php files of the drupal base directory $HTTP["url"] =~ "^/.*/.*\.php$" { fastcgi.server = () url.access-deny = ("") } should be removed because the phpbb URL always show 403 error.

Does mod_rewrite need to be enabled?

Hi, Thanks for the article. Just so I understand, do I also need to enable mod_rewrite (by uncommenting it from lighttpd.conf). I know I need to install and enable mod_magnet, but what about mod_rewrite? thanks, Kurt

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Back to top