Uses YouTube Apache or Lighttpd


lighttpd is a very lightweight, easy-to-administer, high-performance HTTP server that is used primarily wherever speed is crucial and where high access numbers are to be expected. For example, YouTube, Wikipedia and SourceForge give lighttpd priority over Apache and similarly extensive HTTP servers.

Lighttpd is also suitable simply as a slim alternative to Apache. This article describes how to set up a full-fledged server environment consisting of lighttpd, PHP, MySQL (or MariaDB) and Python.


lighttpd is available as lighttpd in, and can be installed from there using Pacman.

# lighttpd itself
pacman -S lighttpd

# Useful for web servers
pacman -S php php-cgi mariadb mariadb-clients

PHP and the CGI module for PHP, as well as MariaDB and clients are also available in and should be installed at the same time.


Before lighttpd can be started, it has to be configured. The configuration is done in the file. Most of the options in the standard configuration have already been assigned meaningful values.


The section "server.modules" defines which additional modules should be loaded by lighttpd. For a meaningful operation, the modules "fastcgi" and "cgi" are required in addition to the already activated modules. This results in the following configuration of the modules:

server.modules = ("mod_access", "mod_fastcgi", "mod_cgi", "mod_accesslog")

Modules that have been commented out have been omitted from the view. “Userdir” can also be of interest, which enables (these directories can be called via http: // host / ~ user).

Directory and file names

By default, lighttpd uses the directory as the root directory of the HTML files. If you want to leave it that way, you can of course, but you have to make sure that this directory either has its own partition or that the partition on which this directory is located is large enough.

It is better to put the root directory of the server on its own partition. Here you can also restrict the rights accordingly (as a mount option, for example) to make the server a bit more secure.

server.document-root = "/ media / webserver"

Index files are always displayed when a directory is accessed via HTTP. If there is no index file, either the directory content is displayed or an error message is output stating that the directory content cannot be displayed.

For example, if you want to use it as an index file, you enter this in the index file list. When http: // host / blubb / is called, the index file list is searched and as soon as a file with a file name from the list is available, it is displayed without having to specify the file name. In the example, calling http: // host / blubb / displays the file http: //host/blub/start.htm.

index-file.names = ("index.php", "index.html", "start.htm")

The section “mimetype.assign” assigns certain file extensions to defined file content types. If you use your own file extensions that have a certain content, you can add them here. However, all common types have already been defined, so that normally nothing more needs to be changed here.

Server options

If you do not want someone who calls the page to receive information that the HTTP server is lighttpd, you can change this using the "server.tag" option.

server.tag = "blubb"

This sends the server name "blubb" to the calling client via the HTTP header. In addition to the server tag, however, there are other options that can be used to infer the actual server.

If you do not want to deliver certain file types via HTTP, you can do this using the "url.access-deny" list. By default, backup files () and include files () are excluded. If you want to exclude other file types from delivery, simply add the extensions of these to the list.

By default, lighttpd listens on port 80 like any other HTTP server. This can be changed via "server.port" and let lighttpd listen on port 5678 for example.

server.port = 5678

A client that accesses the server can still find out by simple port scanning, e.g. using nmap, which port is listening on what, and thus of course that an HTTP server is listening on port 5678.

If you only want to operate lighttpd as a local test system and do not want any clients to be able to access the server, you can bind lighttpd to a specific IP. In the case of the local test system, this is, for example.

server.bind = ""

If you want to use virtual hosts, you have to activate the server module "mod_simple_vhost" and set the options according to the comments in the configuration file.

simple-vhost.server-root = "/ media / webserver / vhosts /" simple-vhost.default-host = "myhost.invalid" simple-vhost.document-root = "/ htdocs /"

The root directory is then made up of the three entries in this order by default.

Otherwise the middle part (in the example "myhost.invalid") is automatically replaced by the host name via which the server is called. For example, if you access the server using "server.lan", the HTML root directory is


The directory lists mentioned above, if the index file is missing, can be influenced using the “dir-listing.activate” option. "Enable" activates the directory listing, "disable" deactivates it.

dir-listing.activate = "enable" dir-listing.encoding = "utf-8"

If the directory listing is deactivated and the index file is missing, a message is sent to the client that the file could not be found (). The listing is deactivated by default.


By default, the server does not run with root rights, but with the rights of the user and the “http” group. This user is not allowed to log in (he has a shell instead, which returns an error message every time he tries to log in), which means a certain degree of security.

If you want to operate the server as a productive system, you should leave it that way and assign the document root directory of the server to the appropriate user and group. If you assign other users to this group, these users can also work in this root directory (and below).

If you want to use lighttpd as a local test system, you can also run it with the rights of another user (e.g. yourself). The advantage is that there are fewer rights problems, since all files belong to the user who is also running the web server.

server.username = "username" = "users"

The disadvantage here is that the HTTP server with the the same Rights that the corresponding user also has. A successful attacker or a faulty script can thus access all data that the corresponding user has access to. This setup should exclusively be implemented in environments that are not accessible from the outside.

  • It is advisable not to let a web server configured in this way run permanently, but only to start it when it is actually to be used for development / testing.

MariaDB and PHP

By using MariaDB and PHP one achieves a full-fledged server system that is compatible with all common web applications. Apache-specific functions in the web applications are usually not directly supported, but - apart from htaccess (see there) - these are also relatively rare.


In order to be able to use PHP, the fastcgi server still has to be configured; there is already a commented entry in the lighttpd configuration file that can be used. The binary path to PHP and the socket file of PHP must be specified. In addition, it must be defined which extension PHP files have.

fastcgi.server = (".php" => (("bin-path" => "/ usr / bin / php-cgi", "socket" => "/tmp/php.socket")))

In addition, the option "cgi.fix_pathinfo" must be set to 1 (commented) in the PHP configuration file. In order to be able to use MariaDB, the PHP extension must also be activated; this is done in the same file by commenting on the corresponding option.

; ...; ... extension =; ...; ...

The PHP save mode, which is often mentioned as a security function, can also be activated (), but since PHP version 5.3.0 it has been available as deprecated checked and will be removed in PHP 6.


First of all, a root password for MariaDB should be assigned. This has nothing to do with the system root account, it only relates to the MariaDB server. The password is set using the MariaDB administration tool.

mysqladmin -uroot password 'the desired password'

This means that you can only access the database with a password as root. Other MariaDB users can also be set up: To do this, you have to log in as root on the MariaDB server and transfer a certain SQL string.

mysql -uroot -p […]> USE mysql; > INSERT INTO user (host, user, password) VALUES ('localhost', 'username', password ('the desired password'));

Then the MariaDB server must be restarted using. With regard to the further authorization structure within the MariaDB server, please consult the setup instructions linked in the web links. Alternatively, there is the GRANT system.

mysql -uroot -p […]> CREATE DATABASE testdb; > GRANT USAGE ON *. * TO 'testuser' @ 'localhost' IDENTIFIED BY 'daspasswort';

This creates the MariaDB user. The database is created beforehand. When the user is created, any privileges for all databases are withdrawn (USAGE is a synonym for “no privileges” in SQL syntax). Now you can grant this user authorizations for a specific database

> GRANT select, insert, update, delete, create, drop ON testdb. * TO 'testuser' @ 'localhost'

This grants the user just created read and write access to the database just created. The user can create and delete tables, but he cannot change the database itself. The user can only access the database from the server ("localhost") and not from other systems.


In order for lighttpd to be able to execute Python scripts, a corresponding assignment must be made in the configuration file. It is assumed that Python is addressed via.

cgi.assign = (".py" => "/ usr / bin / python")

In addition, Python must be added to the file extensions.

static-file.exclude-extensions = (.., .., ".py")

It must be activated for this to work.


lighttpd is a service, which means that it should be activated for automatic start.

systemctl enable lighttpd

Lighttpd can be started manually using. If you have changed the user and the group, an authorization error regarding the log files can occur when starting. The (possibly necessary) manual creation of the log file directory and the assignment of the user and rights solves the problem.

mkdir / var / log / lighttpd chown username: log / var / log / lighttpd chmod 760 / var / log / lighttpd

Alternatively, you can also use the option "accesslog.filename" (and others) in the lighttpd configuration file to create the log file in a location where the corresponding user has write access.


As a test, you can now create a file in the document root directory and write it into it. This is a PHP information function. When you call up the page via http: //localhost/info.php, an overview of what the server can do and how it was configured appears.

The document provides information about the PHP installation, MariaDB, the web server, and the system on which the server is running.

This file should not be left accessible on a publicly accessible production system, as the PHP function used makes a great deal of information about the system accessible to an attacker. You should therefore delete the file or at least not save it under an easily accessible file name.

Special feature: htaccess

lighttpd cannot handle htaccess files. This means that all web applications that use htaccess cannot run directly. This applies to forwarding as well as access mechanisms. lighttpd manages these things in the vHost configuration.

There are several sections in the file for this purpose. Within these sections, all information relating to this host regarding login queries, URL rewriting, etc. is made.

In order for URL rewriting and login queries to work, the modules and must be activated in the section.

URL rewriting

The configuration of URL rewrites is carried out using the function, TYP being one of the different types that can be used by lighttpd. corresponds to the behavior known from htaccess.

url.rewrite-once = ("/ angegeber_pfad" => "forwarding_to.php")

Other types are (corresponds to the specification for htaccess redirects) and (corresponds to the htaccess specification).


If you use the Wordpress blog system, you probably want to use its function of displaying URLs in a "beautiful" way. Wordpress uses htaccess for this, since this is not used by lighttpd, you have to rewrite the information from the Wordpress htaccess file to information. Since the regular expressions of htaccess and lighttpd's rewriting system are identical, this is relatively easy to do.

$ HTTP ["host"] = ~ "" {url.rewrite-once = ("^ / (. *) \. (. +) $" => "$ 0", "^ / (wp-. +) $ "=>" $ 0 "," ^ / xmlrpc.php "=>" $ 0 "," ^ / sitemap.xml "=>" $ 0 "," ^ / (. +) /? $ "=>" /index.php/$1 ")}

If the blog is on, Wordpress can now be accessed using the familiar Wordpress URLs if Wordpress URL rewriting is activated. lighttpd automatically rewrites the URLs accordingly, just as Apache would do with the htaccess file.


The HTTP authentication dialog, shown here by Firefox

The lighttpd login system works a little differently than that of apache (htaccess). First of all it is defined what kind of authentication system is to be used and which file (in the case of file-based authentication methods) is to be used. Authentication is then activated using the section for individual subdirectories.

auth.backend = "SYSTEM" auth.backend.SYSTEM.userfile = "/ var / www / password" auth.require = ("/ subdirectory" => ("method" => "Authentication method", "realm" => " Text that is displayed in the login window "," require "=>" What is recognized as a valid login "))

The following values ​​can be used for SYSTEM:

  • - Expects usernames and passwords in plain text in the specified file.
  • - Expects usernames and passwords in the form known from htaccess password protection in the specified file.
  • - Expects username, realm and hashed (MD5) password in the specified file, separated by colons for each line in this order.

In addition, there is also the option of realizing authentication via LDAP.


For example, if you want to protect the subdirectory on your server from access using basic-auth, you use the following:

$ HTTP ["host"] = ~ "" {auth.backend = "htpasswd" auth.backend.htpasswd.userfile = "/ var / www / password" auth.require = ("/ secure" => ( "method" => "basic", "realm" => "Login", "require" => "valid-user"))}

The file now contains, for example, the lines

user1: mjsHyevlsdf4HeAQ user2: mjdvGdwe3345HIsd

This means that user1 and user2 can log in with their respective passwords (the hashes in the example are random values ​​and do not correspond to any password known to the author). Everyone who wants to access will see “Login” as information text.

This configuration corresponds to the htaccess-based password protection.

The information about the authentication system and the corresponding file can also be defined globally (outside of a block).


The functioning of the digest method does not yet fully comply with the standard and is currently classified as rather insecure, as it does not withstand the replay attack, for example.

The LDAP authentication currently only supports usernames without special characters. The username "ein.user" is currently being discarded by lighttpd's LDAP authentication system with an error message.

Faulty login attempts are currently not recorded properly ("There seems to be no reasonable logging of failed login attempts yet")

The group-based authentication does not currently work. is intended for this, but is currently simply ignored.

See also

Web links