≡ Menu

lighttpd

Lighttpd handle secured download mechanisms using mod_secdownload modules. It uses the lighttpd webserver and the internal HTTP authentication using secrete password. This module use the concept called authenticated URL for a specified time. Each unique url remains valid for a specified time.

Your application has to generate a token and a timestamp which are checked by the webserver before it allows the file to be downloaded by the webserver.

URL Format

The generated URL has to have the format:

<uri-prefix>/<token>/<timestamp-in-hex>/<rel-path>

Which looks like
http://theos.in/dl/6262df3adba2bc85846e05440fcc3895/4804f986/file.zip

is an MD5 of

  • a secret string (user supplied)
  • <rel-path> (starts with /)
  • <timestamp-in-hex>

Understanding filesystem layout

  • Domain name: theos.in
  • Webroot : /home/lighttpd/theos.in/http/
  • Download location : /home/lighttpd/download-area/ (you must upload all download files here)
  • Download url : http://theos.in/dl/<token>/<timestamp-in-hex>/file.zip

Make sure /home/lighttpd/download-area/ directory exists:
# mkdir -p /home/lighttpd/download-area/
# chown lighttpd:lighttpd /home/lighttpd/download-area/

Configuration

Open lighttpd.conf file:
# vi /etc/lighttpd/lighttpd.conf
Append following configuration:

secdownload.secret          = "MySecretSecurePassword"
secdownload.document-root   = "/home/lighttpd/download-area/"
secdownload.uri-prefix      = "/dl/"
secdownload.timeout         = 3600

Where.

  • secdownload.secret : Your password; it must not be shared with anyone else
  • secdownload.document-root : Download file system location, must be outside domain webroot / documentroot
  • secdownload.uri-prefix : url prefix such as /dl/ or /download/
  • secdownload.timeout : Set timeout for each unique url in seconds

Save and close the file. Restart lighttpd:
# service lighttpd restart

Sample PHP Download Script

<?php
$secret = "MySecretSecurePassword";
$uri_prefix = "/dl/";
 
# set filename
$f = "/file.zip";
 
# set current timestamp
$t = time();
$t_hex = sprintf("%08x", $t);
$m = md5($secret.$f.$t_hex);
# finally generate link and display back on screen
printf('<a href="http://www.cyberciti.biz/">%s</a>',$uri_prefix, $m, $t_hex, $f, $f);
?>

410 Gone HTTP Error Code

After timeout; unique url will be gone and end user will get 410 http status code. It indicates that the resource requested is no longer available and will not be available again. So if anybody deeplinked or hotlinked your content it will be gone after timeout.

Further readings:

Stop Hotlinking with Lighttpd

The technology behind the World Wide Web, the Hypertext Transfer Protocol (HTTP), does not make any distinction of types of links -- all links are functionally equal. Resources may be located on any server at any location. Linking to an image stored on another site increases the bandwidth use of that site even though the site is not being viewed as intended. The complaint may be the loss of ad revenue or changing the perceived meaning through an unapproved context.

Here is easy and simple way to stop hotlinking :
Open lighttpd.conf file:
$ vi lighttpd.conf

#### stop image hijacking (anti-hotlinking)
$HTTP["referer"] =~ ".*BADDOMIN\.com.*" {
        url.access-deny = ( "" )
#      url.access-deny = ( "jpg", "png", "js", "jpeg", "gif" )
}

You can also enforce password protection:

$HTTP["referer"] =~ ".*BADDOMIN\.com.*" {
 auth.require = ( "/" =>
                   (        "method"  => "digest",
                            "realm"   => "Authorized users only",
                            "require" => "valid-user"
                   )
                 )
}

Restart lighttpd:
# service lighttpd restart

Lighttpd web server will generate a directory listing if a directory is requested and no index-file was found in that directory. mod_dirlisting is one of the modules that is loaded by default and doesn't have to be specified on server.modules to work.

Task: Enable Directory Listings Globally

Open lighttpd configuration file:
# vi /etc/lighttpd/lighttpd.conf
Append / modify
server.dir-listing = "enable"
OR
dir-listing.activate = "enable"
Save and close the file. Restart lighttpd:
# /etc/init.d/lighttpd restart
To disable directory listing, use:
dir-listing.activate = "disable"

Enable directory listing only for a directory

You can also enable or disable listing on selected url / directory combination. For example, display directory listing only for /files/:
$HTTP["url"] =~ "^/files($|/)" { server.dir-listing = "enable" }
OR
$HTTP["url"] =~ "^/files($|/)" { dir-listing.activate = "enable" }

Further readings:

Mono project offers .NET compatible set of tools, including among others a C# compiler and a Common Language Runtime. It runs on Linux, *BSD, Windows and other operating systems. From the article:

The FastCGI Mono Server was developed as part of the 2007 Google Summer of Code (http://code.google.com/soc/2007/) with the goal of increasing the availablity of ASP.NET and simplifying configuration. Requiring as little as zero command line options and supporting a large number of servers, the FastCGI Mono Server makes it simple to include ASP.NET on your server.

This documentation contains configuration instructions for serveral web servers on Linux, with plans to expand support to Windows and Macintosh in the future. Please take the time to read all the information below before configuring your server.

ASP.NET Mono - How Does It Work?
(Fig. 01: How does FastCGI mono server works?)

=> The FastCGI Mono Server Configuration

It is possible to serve .php or .cgi / .pl file using different file type / extension name. This will improve security. For example, server .html as .php file, add following to your httpd.conf or .htaccess file:
# serve .html files as php files
AddType application/x-httpd-php .html
# serve .nix files as cgi files
AddType application/x-httpd-cgi .nix

If you are using Lighttpd web server add following to serve php as .html file:
fastcgi.map-extensions = ( ".html" => ".php" )

Recently, I noticed something strange about Apache 2.2.3 version running on CentOS Linux 5 64 bit version. We have centralized NFS server and all 3 web server load balanced using hardware front end (another box running LVS).

All Apache server picks up file via NFS i.e DocumentRoot is set over NFS. The small file such as 2 MB or 5 MB get downloaded correctly but large size files failed to download. Another problem was some clients reported that the file get download but cannot open due to file corruption issue.

After investigation and a little bit googling I came across the solution. You need to disable following two options:

  • EnableMMAP - This directive controls whether the httpd may use memory-mapping if it needs to read the contents of a file during delivery. By default, when the handling of a request requires access to the data within a file -- for example, when delivering a server-parsed file using mod_include -- Apache memory-maps the file if the OS supports it.
  • EnableSendfile - This directive controls whether httpd may use the sendfile support from the kernel to transmit file contents to the client. By default, when the handling of a request requires no access to the data within a file -- for example, when delivering a static file -- Apache uses sendfile to deliver the file contents without ever reading the file if the OS supports it.

However, these two directives are known to have problem with a network-mounted DocumentRoot (e.g., NFS or SMB), the kernel may be unable to serve the network file through its own cache. So just open httpd.conf on all boxes and changes the following:
EnableMMAP off
EnableSendfile off

Just restart the web server and voila!
# service httpd restart

Lighttpd / Apache : Run Xcache in Chrooted Jail

Recently I wrote about installing and running Xcache under Red hat enterprise Linux and CentOS Linux. By default Xcache use /dev/zero for caching. All you have to do is create /dev/zero in chrooted jail. Type the following command (assuming that your jail is located at /lighttpd.jail directory):
# mkdir -p /lighttpd.jail/dev
# mknod -m 666 /lighttpd.jail/dev/zero c 1 5

Just restart your web server and xcache should work under chrooted lighttpd web server.