Maintaining a Web Server (208.2)

Candidates should be able to configure a web server to use virtual hosts, Secure Sockets Layer (SSL) and customise file access.

Key Knowledge Areas

SSL configuration files, tools and utilities

SSL certificate handling

Apache 2.x virtual host implementation (with and without dedicated IP addresses)

Using redirect statements in Apache's configuration files to customise file access

The following is a partial list of the used files, terms and utilities:

Apache2 configuration files
httpd.conf
/etc/ssl/*
openssl

Resources: LinuxRef08; Engelschall00; Krause01; the man pages for the various commands.

Apache2 configuration files

httpd.conf

Configuration files can be checked for syntax errors with the following command:

$ apachectl configtest
   

The mime.types file is the default file that contains mime document types. This file is set by the "TypesConfig" directive.

Apache Virtual Hosting

Virtual Hosting is a technique that provides the capability to host more than one domain on one physical host. There are two methods to implement virtual hosting:

Name-based virtual hosting.  With name-based virtual hosting, the server relies on the client (e.g. the browser) to report the hostname as part of the HTTP headers. Using this technique, many different hosts can share the same IP address.

IP-based virtual hosting.  Using this method, each (web)domain has it's own unique IP address. Since one physical host can have more than one IP address, one host can serve more than one (web)domain. In other words: IP-based virtual hosts use the IP address of the connection to determine the correct virtual host to serve.

Name-based virtual hosting

Name-based virtual hosting is a fairly simple technique. You need to configure your DNS server to map each hostname to the correct IP address first, then configure the Apache HTTP Server to recognise the different hostnames.

Tip

Name-based virtual hosting eases the demand for scarce IP addresses. Therefore you should use name-based virtual hosting unless there is a specific reason to choose IP-based virtual hosting, see IP-based Virtual Hosting.

To use name-based virtual hosting, you must designate the IP address (and possibly port) on the server that will be accepting requests for the hosts. This is configured using the NameVirtualHost directive. Normally any and all IP addresses on the server should be used, so, you can use * as the argument to NameVirtualHost. Note that mentioning an IP address in a NameVirtualHost directive does not automatically make the server listen to that IP address: there are two additional directives used to restrict or specify which addresses and ports Apache listens to:

The directive BindAddress could be used in the older apache versions (up to apache 1.3). BindAddress is deprecated and is eliminated in Apache 2.0. Equivalent functionality and more control over the address and ports Apache listens to is available using the Listen directive.

  • BindAddress is used to restrict the server to listening to a single address, and can be used to permit multiple Apache servers on the same machine to listen to different IP addresses;

  • Listen can be used to make a single Apache server listen to more than one address and/or port.

The next step is to create a <VirtualHost> block for each different host you would like to serve. The argument to the <VirtualHost> directive should be the same as the argument to the NameVirtualHost directive (i.e., an IP address or * for all addresses). Inside each <VirtualHost> block you will need, at minimum, a ServerName directive to designate which host is served and a DocumentRoot directive to show where in the filesystem the content for that host lives.

Suppose that both www.domain.tld and www.otherdomain.tld point to the IP address 111.22.33.44. You then simply add the following to httpd.conf:

NameVirtualHost 111.22.33.44

<VirtualHost 111.22.33.44>
  ServerName www.domain.tld
  DocumentRoot /www/domain
</VirtualHost>

<VirtualHost 111.22.33.44>
  ServerName www.otherdomain.tld
  DocumentRoot /www/otherdomain
</VirtualHost>
       

In the simplest case, the IP address 111.22.44.33 can be replaced by * to match all IP addresses for your server. Many servers want to be accessible by more than one name. This is possible with the ServerAlias directive placed inside the <VirtualHost> section, if, for example, you add the following to the first <VirtualHost> block above

ServerAlias domain.tld *.domain.tld 
      

then requests for all hosts in the domain.tld domain will be served by the www.domain.tld virtual host. The wildcard characters * and ? can be used to match names.

Tip

Of course, you can't just make up names and place them in ServerName or ServerAlias. You must first have your DNS server properly configured to map those names to the IP address in the NameVirtualHost directive.

Finally, you can fine-tune the configuration of the virtual hosts by placing other directives inside the <VirtualHost> containers. Most directives can be placed in these containers and will then change the configuration only of the relevant virtual host. Configuration directives set in the main server context (outside any <VirtualHost> container) will be used only if they are not overridden by the virtual host settings.

Now when a request arrives, the server will first check if it is requesting an IP address that matches the NameVirtualHost. If it is, then it will look at each <VirtualHost> section with a matching IP address and try to find one where the ServerName or ServerAlias matches the requested hostname. If it finds one, it then uses the configuration for that server. If no matching virtual host is found, then the first listed virtual host that matches the IP address will be used.

As a consequence, the first listed virtual host is the default virtual host. The DocumentRoot from the main server will never be used when an IP address matches the NameVirtualHost directive. If you would like to have a special configuration for requests that do not match any particular virtual host, simply put that configuration in a <VirtualHost> container and list it first in the configuration file.

IP-based virtual hosting

Despite the advantages of name-based virtual hosting, there are some reasons why you might consider using IP-based virtual hosting instead:

  • Name-based virtual hosting cannot be used with SSL secure servers because of the nature of the SSL protocol.

  • Some ancient clients are not compatible with name-based virtual hosting. For name-based virtual hosting to work, the client must send the HTTP Host header. This is required by HTTP/1.1, and is implemented by all modern HTTP/1.0 browsers as an extension.

  • Some operating systems and network equipment implement bandwidth management techniques that cannot differentiate between hosts unless they are on separate IP addresses.

As the term IP-based indicates, the server must have a different IP address for each IP-based virtual host. This can be achieved by equipping the machine with several physical network connections or by use of virtual interfaces, which are supported by most modern operating systems (see system documentation for details on IP aliasing and the ifconfig command).

There are two ways of configuring Apache to support multiple hosts.

  • by running a separate httpd daemon for each hostname

  • by running a single daemon which supports all the virtual hosts.

Use multiple daemons when:

  • there are security issues, e.g., if you want to maintain strict separation between the web-pages for separate customers. In this case you would need one daemon per customer, each running with different User, Group, Listen and ServerRoot settings;

  • you can afford the memory and file descriptor requirements of listening to every IP alias on the machine. It's only possible to Listen to the wildcard address, or to specific addresses. So, if you need to listen to a specific address, you will need to listen to all specific addresses.

Use a single daemon when:

  • sharing of the httpd configuration between virtual hosts is acceptable;

  • the machine serves a large number of requests, and so the performance loss in running separate daemons may be significant.

Setting up multiple daemons

Create a separate httpd installation for each virtual host. For each installation, use the Listen directive in the configuration file to select which IP address (or virtual host) that daemon services:

Listen 123.45.67.89:80
        

You can use the domain name if you want to, but it is recommended you use the IP address instead.

Setting up a single daemon

For this case, a single httpd will service requests for the main server and all the virtual hosts. The VirtualHost directive in the configuration file is used to set the values of ServerAdmin, ServerName, DocumentRoot, ErrorLog and TransferLog or CustomLog configuration directives to different values for each virtual host.

<VirtualHost www.smallco.com>
    ServerAdmin webmaster@mail.smallco.com
    DocumentRoot /groups/smallco/www
    ServerName www.smallco.com
    ErrorLog /groups/smallco/logs/error_log
    TransferLog /groups/smallco/logs/access_log
</VirtualHost>

<VirtualHost www.baygroup.org>
    ServerAdmin webmaster@mail.baygroup.org
    DocumentRoot /groups/baygroup/www
    ServerName www.baygroup.org
    ErrorLog /groups/baygroup/logs/error_log
    TransferLog /groups/baygroup/logs/access_log
</VirtualHost>
        

Customizing file access

Redirect allows you to tell clients about documents which used to exist in your server's namespace, but do not anymore. This allows you to tell the clients where to look for the relocated document.

Redirect {old-URI} {new-URL}
    

Directory /etc/ssl/*

/etc/ssl$ ls -l
total 32
drwxr-xr-x 3 root root     16384 2011-03-06 15:31 certs
-rw-r--r-- 1 root root      9374 2010-09-24 22:05 openssl.cnf
drwx--x--- 2 root ssl-cert  4096 2011-03-06 13:19 private
    

The /etc/ssl/openssl.cnf file This is the general configuration file for OpenSSL program where you can configure the expiration date of your keys, the name of your organization, the address etc. The openssl program is a command line tool for using the various cryptography functions of OpenSSL's crypto library from the shell.

How to create a SSL server Certificate

Whilst installing OpenSSL, the program openssl has been installed on your system. This command can be used to create the necessary files.

More specifically these are:

  • the RSA private key file is a digital file that you can use to decrypt messages sent to you. It has a public component which you distribute (via your Certificate file) and allows people to encrypt messages to you;

  • a Certificate Signing Request (CSR) is a digital file which contains your public key and your name. You send the CSR to a Certifying Authority (CA) to be converted into a real Certificate.

  • A Certificate contains your RSA public key, your name, the name of the CA and is digitally signed by your CA. Browsers that know the CA can verify the signature on that Certificate, thereby obtaining your RSA public key. That enables them to send messages which only you can decrypt.

To create an RSA private key for your Apache server (it will be Triple-DES encrypted and PEM formatted), execute the following:

$ openssl genrsa -des3 -out server.key 1024
  

openssl will ask for a pass-phrase. Please backup this server.key file and remember the pass-phrase.

To create a Certificate Signing Request (CSR) with the server RSA private key (output will be PEM formatted), execute the following:

$ openssl req -new -key server.key -out server.csr
   

Make sure you enter the FQDN ("Fully Qualified Domain Name") of the server when OpenSSL prompts you for the CommonName, i.e. when you generate a CSR for a web-site which will later be accessed via https://www.foo.example/, enter www.foo.example here.

You now have to send this Certificate Signing Request (CSR) to a Certifying Authority (CA) for signing. The result is a real Certificate which can be used by Apache. Here you have two options: First you can have the CSR signed via a commercial CA like Verisign or Thawte. In that case, you usually have to post the CSR into a web form, pay for the signing and await a signed Certificate that you can store in a server.crt file. Secondly, you could create your own CA and sign the certificate yourself.

The server.csr file is no longer needed. Now you have two files: server.key and server.crt. In your Apache's httpd.conf file you should refer to them using lines like these:

SSLCertificateFile    /path/to/this/server.crt
SSLCertificateKeyFile /path/to/this/server.key
   

Tip

How do you run Apache-SSL as a shareable (DSO) module? First, configure the shared module support in the source tree:

./configure --enable-shared=apache_ssl
   

then enable the module in your httpd.conf:

LoadModule apache_ssl_module modules/libssl.so
   

Copyright Snow B.V. The Netherlands