# 208.1 Implementing a Web server
## Detailed Objectives (208.1)

(LPIC-1 Version 4.5)
Weight: 4
Description: Candidates should be able to install and configure a web server. This objective includes monitoring the servers load and performance, restricting client user access, configuring support for scripting languages as modules and setting up client user authentication. Also included is configuring server options to restrict usage of resources. Candidates should be able to configure a web server to use virtual hosts and customize file access.
Key Knowledge Areas:
* Apache 2.4 configuration files, terms and utilities.
* Apache log files configuration and content.
* Access restriction methods and files.
* mod_perl and PHP configuration.
* Client user authentication files and utilities.
* Configuration of maximum requests, minimum and maximum servers and clients.
* Apache 2.4 virtual host implementation (with and without dedicated IP addresses).
* Using redirect statements in Apache’s configuration files to customize file access.
Terms and Utilities:
* access logs and error logs
* .htaccess
* httpd.conf
* mod_auth_basic, mod_authz_host, mod_access_compat
* htpasswd
* AuthUserFile, AuthGroupFile
* apachectl, apache2ctl
* httpd, apache2

## Overview

Apache is the most used web server on the Internet, and the "poster child" for successful open source development. While a web server itself don't need to be particularly fancy (many programming languages have tutorials how to write a HTTP server) Apaches "secret of success" is its flexibility and robustness. Apache can be easily extended by various modules, mod_perl and mod_auth will be featured in this section.

## Installation and Configuration

The Apache HTTP server in its most recent version (2.2 as of writing this) can be downloaded in source code from the Apache HTTP Server Website, or pre compiled as binary package from the repository of your favorite Linux distribution.
For the rest of this section we will refer to the Apache documentation for file names. This documentation is usually installed with the Apache binary inside the DocumentRoot. If we cannot reach the local documentation, there still is the official documentation from the Apache Website. We will use a virtual network with Slackware 13.0 inside VirtualBox, which is free (as in cost) and available Free (as in Freedom) with small restrictions. Distribution specific summaries for Debian Lenny and a clone of Redhat Enterprise, Centos 5.4 will follow below.
If we want to compile Apache from source, we use the usual configure, make, make install steps. For further details please refer to the documentation page.
The web server binary httpd itself is usually located in /usr/sbin/. We can use the binary directly to start and stop the web server through command line options, but a better idea is to use the control script apachectl to interface with the httpd. apachectl can control the web server process (start and stop) in a convenient way and sets up the environment and checks the configuration file in the background. Back in the days of the transition from Apache 1.3 to the Apache 2.x series the control script was called apache2ctl to tell it apart from the Apache 1.3 script (then) apachectl.
It is unfortunate that the LPI still refers to apache2ctl while the Apache source code produces apachectl.
Hmmm. This does not look right, because if apachectl encounters parameters it does not understand, it passes them directly to httpd. And no parameter is such a parameter, so apachectl invokes httpd without any parameter.
apachectl can start, stop and restart the web server, but even more useful is gracefull and gracefull-stop which restarts/stops the web server while not stopping currently open connections. configtest does the same as httpd -t in testing the apache configuration file. The options status and fullstatus need the mod_status module to display many useful status informations about our http server.
The logs for your Apache instance go to /var/log/httpd/. The two most important log files are access_log, which logs every access to the web server and error_log which only records errors. Tools like Awstats and Webalizer use the access_log to generate their reports.
A snippet of access_log shows (taken from the Debian Lenny machine lpidebian) the IP 192.162.10.21 accessing / on the website, which is the “welcome” page of the web server (more on this later), then trying to GET /favicon.ico and then /login.html which both result in a “404”, which means “File does not exist”.
This snippet from error_log shows the same errors but in greater detail:
The configuration of Apache takes place in /etc/httpd/httpd.conf. This lengthy, but well documented, configuration file is in part structured similar to a HTML page. To strip out any comments you can easily use grep.
This slightly striped down httpd.conf is taken from a Slackware 13.0 system (lpislack. There are two terms to know when talking about httpd.conf: "directives" and "containers". "Directives" are the configuration options (and their values) themselves, while "containers" are directories or collections of files. Any directive inside a container will only be valid inside this container, directives outside the container are of global effect for the whole site. On the other side, there are directives that are only valid inside a container.

### ServerRoot "/usr"

    This is a tricky on. All relative paths start from here, the absolute ones are, as implied by the name, absolute.

### Listen 80

    The TCP port the httpd listens for incoming connection requests. If our machine has more than one network address, we can bind the httpd to one (ore more) IP adresses/port combinations here as well.

### LoadModule auth_basic_module lib/httpd/modules/mod_auth_basic.so

    Loads the module auth_basic_module located in lib/httpd/modules/mod_auth_basic.so relative to the ServerRoot, so the whole path to this module is /usr/lib/httpd/modules/mod_auth_basic.so

### User apache

    The user account httpd runs as. This better be an restricted account. One (the first) httpd process has to run as root, if it wants to claim port 80.

### Group apache

    The group of the user httpd runs as.

### ServerAdmin webadmin@your.site

    the e-mail address of the administrator responsible for running the httpd. This shows up when errors occur.

### DocumentRoot "/srv/httpd/htdocs"

    This is the directory where the actual HTML documents live on your hard drive!

### <Directory /> ... </Directory>

    This is a container object. All directives inside are only valid for this directory "/" and all of its subdirectories.

### Options FollowSymLinks

    Potential security risk! Does what its name suggest.

### AllowOverride None

    You can override most directives with a .htaccess file. This is a security risk and the use of .htascess is denied by this directive.

### Order deny,allow

    Controls the access to files and directories. First look who is not allowed, then look who is allowed. The default is the last control that matches, if non matches or both match, use the default (=last)!

### Deny from all

    Denies all hosts the access to all file in this container.

### <Directory "/srv/httpd/htdocs"> ... </Directory>

    Container for the ServerRoot directory. Note the Order allow,deny and the Allow from all directives. Here we want access from all hosts.

### DirectoryIndex index.html

    The file with this name is presented to the client when a web browser accesses a directory and not a specific HTML page. If no index.html exist in this directory the contents of the directory itself is shown. Options Indexes allows this, while Options -Indexes generates an error message instead of listing the directories contents.

### ErrorLog "/var/log/httpd/error_log"

    Sets the logfile for error messages.

### LogLevel warn

    Sets the verbosity of the error messages.

### LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

    Sets the format of the entries in the custom log file (usually access_log)

### CustomLog "/var/log/httpd/access_log" common

    Sets name and location of the custom log file.

### ScriptAlias /cgi-bin/ "/srv/httpd/cgi-bin/"

    Directory for CGI scripts.

### DefaultType text/plain

    Apache uses this MIME type for the HTML pages it provides to the web browser, if the HTML page itself contains no other information.

### TypesConfig /etc/httpd/mime.types

    List of MIME types to use for different types of file names.

## Access restrictions methods and files

Access to files and directories on the web server can be restricted based on the machines IP or network (hostname, domain, IP address, or network) or based on user name and password. While the access can be restricted by this methods all content transmitted in both directions is still not encrypted! To secure the communication and ensure the identity of the web server the SSL/TLS protocol will be used in the next chapter of this book.

### Container

The behaviour of the Apache web server can be finely tuned in the Apache configuration (or the .htaccess file) on a per directory (<Directory> container), per file (<File> container), or per URL (<Location> container) basis. The directives inside a <Directory> (or <Location>) container are valid for the directory itself and all its subdirectories. Most of this directives can be overwritten by external configuration files, usually .htaccess. This is highly discouraged for security and sanity reasons. Some possible directives for AllowOverride are:

#### None

    no use of external configuration changes allowed (safest)

#### All

    all directives can be changed (most insecure)

#### Limit

    some changes are allowed (not secure at all)

#### AuthConfig

    mainly authentication related directives can be changed

#### Options

    mainly Options directives can be overwritten

### Machine Restrictions

Order sets the sequence of access restrictions, where the last matching rule wins. The last rule is also the default rule if neither rule matches or both match. The possible Allow/Deny restrictions are hostname (host.domain.example), domain (domain2.example), ip (192.168.10.3) and network (192.168.10 192.168.10.0/24).
All access from everywhere is allowed, but the domain example.com is denied.

### User Based Restrictions

User based access restrictions are insecure on different levels:
* passwords are not encrypted (danger: snooping)
* every content up- and download is clear text (danger: snooping)
* there is no guarantee about the identity of the server (danger: fraud/phishing)
One big part of Apaches flexibility is its capability to talk to different back ends for user authentication, the most simple being plain text files, which is OK for smaller numbers of users, but do not scale to more than (about) 150 people.
Usernames, passwords and groups are stored in text files usually called .htpasswd and .htgroup. These names are defined in httpd.conf or .htaccess by the directives AuthUserFile and AuthGroupFile. Both directives are part of the mod_auth module. We create/change a username and password with the htpasswd utility. The -c option creates a new password file, if such a file already exists it will be destroyed without warning! htpasswd requires two parameters: password and username.
One other important thing to keep in mind is that the only safe place for password file and group file is outside the DocumentRoot, where these files can't accidentally or maliciously be downloaded by unauthorized visitors.
Going back to reality, overwriting the httpd.conf directives with a .htaccess file and placing the .htpasswd and .htgroup inside the document directories is often done, if the web site administrator does not have full access to the Apache configuration, e. g. in shared hosting environments. To protect these files one can restrict the access to them in a <Files> container spelled out in the httpd.conf:

#### Example 1

This example shows the preferred, but sadly not always possible configuration. The restricted directory is /srv/httpd/htdocs/private1, that can be reached at http://lpislack.vbox.privat/private1/ by my web browser.
httpd.conf:
After fiddling with the configuration file we probably should restart the httpd server process.
Create password file htaccess:
This file is only accessible by authorized (root!) users. (And by the way, the password is tee2Seih.)
The password protected page /srv/httpd/htdocs/private1/index.html source code:

#### Example 2

This example shows a commonly used configuration. It is not the best, but sometimes the only possible setup. We can do much better (much safer) if we can locate the password file outside the DocumentRoot. The restricted directory here is /srv/httpd/htdocs/private2, that can be reached at http://lpislack.vbox.privat/private2/ by the web browser.
The only change to httpd.conf is to allow AllowOverride. In fact, if we can change httpd.conf, we could do the right thing in the first place (see Example 1).
Set up the external configuration file .htaccess in /srv/httpd/htdocs/private2/:
Restart httpd:
Create password file with the user seconduser with the password uu2yo1Wo:

## Modules and CGI

Flexibility and easy extendability are two important reasons for Apaches success. They are achieved in part by the CGI (=common gateway interconnect) concept and the ability to extend an already compiled Apache instance with modules. CGI programs (often called "CGI scripts") are executable programs that can be written in any language, be it bash, pearl, php, basic, assembler or ada. They run on the server, which uses up hardware resources of the server (RAM and CPU time) but do not impact the client. He receives what looks like any static HTML page, although the HTML page was dynamically created by the CGI program. The httpd takes the output of the CGI program and gives it unchanged and unchecked to the client web browser. (e.g., the HTTP headers have to be crafted by the CGI program). CGI programms can also take user input (via PUT or GET requests).

#### Example

This bash script outputs "don't try this at home" in ugly blinking letters and prints the content of /etc/passwd to show how dangerous CGI programming can be!

### Modules

Modules on the other hand can extend the abilites of the httpd with features that are not part of the main Apache source code. (Some modules can be compiled into the httpd directly.) Modules can be switched on and off (e. g. for security reasons) with a simple change in the httpd.conf. Most modules need addional configuration directives in httpd.conf, usually by importing configuration files.
For security reasons we will only enable modules actually needed by our web site.

### mod_php

One very useful example is mod_php. If PHP code is executed as a simple CGI script, every script starts the PHP parsing engine, the HTML text is generated, and then the PHP parsing engine is shut down.
mod_php starts the PHP engine as a module for the Apache process and the PHP engine will be persisted over multiple requests. This drastically reduces the overhead of using PHP for dynamic web site creation. As an added bonus we can use PHP code directly in our HTTP sourcecode. This code also runs at the server side and is then replaced by its output before the complete HTML page is sent to the client. If we use a database, this connection can also be persisted if we use mod_php.
The PHP language itself is configured by php.ini, located at /etc/httpd/, but this file usually don't need to be changed.
To enable mod_php on Slackware 13.0 we only need to uncomment the line
in /etc/httpd/httpd.conf. This will include this already set up configuration directly into our httpd.conf.
mod_php.conf:
We now change AddType application/x-httpd-php to
to use PHP code inside HTML documents. This can be convenient, but increases the workload on high traffic websites considerably, because ever requested HTML page is shoved through the PHP interpreter. Another thing we can do to make our lives a bit easier, is adding index.php to the DirectoryIndex directive.
Now we restart the httpd

#### Example

To check if it works we create testforphp.php somewhere below the DocumentRoot
Now remove this file (or at least deny read access), because this will blast our entire web server configuration to the whole internet, where every creep of the planet is just milliseconds away from us. (Try searching for intitle:phpinfo "PHP Version" in Google...)

### mod_perl

While Slackware 13.0 comes with perl as an installable package, the minimal test CGI script printenv in /srv/www/cgi-bin needs a small help. First we need to mark it as an executable by
and then change the first line "#!/usr/local/bin/perl" to "#!/usr/bin/perl". Now we can navigate our web browser to http://lpislack.vbox.privat/cgi-bin/printenv and see if it works:
We do not use mod_perl at this time but run CGI scripts written in Perl as we would run any other executable.
So mod_perl (from http://perl.apache.org) does for the Perl language the same as mod_php does for PHP : it adds native language support directly into the Apache web server and so reduces load and speeds up response time.
Sadly there is no pre built mod_perl package for Slackware 13.0, but http://slackbuilds.org has at http://slackbuilds.org/repository/13.0/network/mod_perl/ a tried and true buildscript for everyone who can read the instructions. (As as sidenote, SlackBuilds are the preferred method to build Slackware packages from source.)
    This situation demonstrates the use of modules: Functionality that is not included in Apache can be added by external modules without recompiling Apache. If there was a bugfix for Apache and we had to upgrade, mod_perl will still work fine as a modul. If mod_perl was compiled into Apache we had to get the source code, fit it to our setup, compile and install it. With every update we would need to go through the same process, just to keep using Perl.
After building and installing the package we simply need to include mod_perl.conf to httpd.conf and restart the Apache server.
mod_perl.conf:
Perl files can live everywhere in the DocumentRoot and their name has to end in ".pl". Let's go back to the printenv example. If we call it again, it will still be executed as CGI, but if we copy it to the DocumentRoot and rename it printenv.pl it will be run by mod_perl, as we can clearly see by the MOD_PERL and MOD_PERL_API_VERSION lines in the output below:

## Restrict Resource Usage

Apache is capable of serving up pretty busy web sites. One mechanism to provide quick responsetimes under heavy load is to have waiting processes ready to jump into action at any given time. So unlike most other programs Apache spawns multiple processes when it is started. The number of processes is adjusted depending on the numbers of connections by creating and destroying child processes as needed.
One control process listens for new requests, usually on TCP port 80, while every client is connected to its very own child process that serves requests for the whole lifetime of this connection. StartServers determines the number of processes to begin with when Apache is started. But this is of little meaning, because MinSpareServers sets the minimum number of idle Apache processes waiting to server new connections. If there are less spare servers left, they are created at a rate of one per second. If that is not enough, the rate of process creation is doubled every second up to 32 new processes per second. If this is not sufficient, we sure as hell have other problems. On the other hand, if there are more idle servers than MaxSpareServers the unneeded processes are shut down one by one.
MaxClients limits the absolute number of simultaneously running server processes, and with that the maximum number of simultaneous client connections. The maximum number of 256 is a hard limit set at compile time. If there are more connection requests than apache processes to serve them, the requests are first moved to a backlog, and only if this backlog is filled up too, the requests are rejected.
The lifetime of an apache (child) process can be limited by the absolute number of connections he will serve as defined by MaximumRequests. This can mitigate problems when memory leaks on less stable platforms occur or problems caused by buggy modules or badly written CGIs. If set to 0 child processes can live indefinitely, if they are not terminated because of too many spare servers.

## Redhat/CentOS

Installation
The web server binary is called httpd. The control script is called apachectl. The access and error log files are located in /var/log/httpd/ and called access_log and error_log.

## Debian

Intallation
The web server binary is called apache2. The control script is called apache2ctl, which is not the same as apachectl by another name. The access and error log files are located in /var/log/apache2/ and called access.log and error.log. (Note the dot “.” instead of the underscore “_”.)

## References

* ↑ "Netcraft report on web server usage". Retrieved 2009-12-27.