Fast and safe with the Hiawatha secure web server

Keys to the Realm

For confidential data, you should always use a secure SSL connection. Before Hiawatha can speak https, you need an X509 SSL certificate, which you can either buy from a trusted third party (i.e., a Certificate Authority) or create yourself with the use of OpenSSL [2]. The commands to accomplish this are shown in Listing 2.

Listing 2

Creating an X509 SSL Certificate

01 openssl genrsa -out serverkey.pem 2048
02 openssl req -new -x509 -days 3650 -key serverkey.pem -out server.crt
03 echo "" >> serverkey.pem
04 cat server.crt >> serverkey.pem
05 echo "" >> serverkey.pem
06 rm -f server.crt

The result of this is a serverkey.pem file, which you need to store along with httpd.conf (typically in /usr/local/etc/hiawatha).

Https connections are typically directed at port 443; the web server thus needs to listen on this port and grab the certificate when it receives a request:

Binding {
   Port = 443
   Interface =
   UseSSL = yes
   ServerKey = /usr/local/etc/hiawatha/serverkey.pem

The preceding entry means that browsers can only use the https protocol to set up a connection to Hiawatha by way of port 443; in this example, the result would be Additionally, the certificate is only valid for the specified port and interface combination. To use it for all secure connections, put the last line behind the closing bracket.

Mutual Liability

CGI programs are popular targets for attackers, possibly because they are buggy, or because the developer has been lazy with respect to security. To prevent CGI programs from running amok and even taking the web server down, Hiawatha can use a CGI wrapper to confine them. The wrapper will give CGI programs a different user ID if needed.

To set up the jail, you first need to select a directory as your CGI root; the CGI root directory contains all CGI programs and scripts. To match Listing 1, the directory could be /usr/local/var/www/hiawatha/cgi. The wrapper will only run CGI programs and scripts from this directory.

Next you need another configuration file called cgi-wrapper.conf. This file resides in the same directory as httpd.conf – that is, /usr/local/etc/hiawatha. The Hiawatha archive includes a sample of cgi-wrapper.conf with all the lines commented out.

The cgi-wrapper.conf first tells the wrapper what programs it is allowed to run outside the CGI root directory. The list of permissible programs might include interpreters for the script languages you use:

CGIhandler = /usr/bin/php5-cgi
CGIhandler = /usr/bin/perl

Note that CGIhandler is not a good choice of name because this setting has very little in common with the identically named setting in httpd.conf. Once you have configured the wrapper, you can lock away your CGI programs:

Wrap = wrap_id; /usr/local/var/www/hiawatha/cgi; tim

The name of the jail is at the start of the line. Because you will need to add this name to your httpd.conf file, you need to keep it in mind. Following the first semicolon, you have the name of the CGI root directory and then finally the username (or ID) under which CGI programs will be running. If the directory name contains a pipe symbol, as in the following line,

Wrap = wrap_id; /usr/local/var/www/hiawatha|cgi; tim

the CGI wrapper will use the part before the pipe as a chroot directory and put everything else into this environment. In this case, you will need to make sure the CGI handlers are available in the chroot directory.

The CGI wrapper is now ready to rumble, and you just need to tell Hiawatha to use it by adding the following to the httpd.conf file:

WrapCGI = wrap_id

You can define multiple wrappers in cgi-wrapper.conf and then use them for different virtual hosts (see the "Virtual Hosts" box).

Virtual Hosts

Like many other web servers, Hiawatha can serve up multiple, independent Internet sites. To allow this to happen, multiple (domain) names are first assigned to a physical server; this means that all browser requests are automatically directed to the same web server. The server analyzes the URL to determine the Internet site. The client sees multiple, additional virtual machine hosts. ISPs, in particular like this technique because it lets them serve multiple, smaller web presences with a single expensive IP address.

To add virtual hosts to Hiawatha, you need to set up a separate section for each host in httpd.conf, as follows :

VirtualHost {
    WebsiteRoot = /var/www/anothersite/wwwroot
   Hostname =

Inside the brackets, you can use more or less any settings you used for the page itself (the default website in Hiawatha-speak). There are even a couple of functions that you can use only with virtual hosts, including four interesting Prevent security mechanisms. For example:

PreventCMDI = yes

stops command injection attacks by telling Hiawatha to convert backslashes, pipe symbols, and semicolons in the URL and POST data with underscores. Because this fairly rigorous approach also mangles uploaded binaries, it is disabled by default.

The following line prevents cross-site request forgery (CSRF):

PreventCSRF = yes

The virtual host will then ignore any cookies sent to it by the browser if it reaches Hiawatha via an external link. The line

PreventSQLi = yes

combats SQL injection attacks by inserting a slash in front of each tick (') in the URL, the POST data, and cookies. This feature works like Magic Quotes in PHP; also, you should not enable PreventSQLi if you use PHP scripts. Just like its sibling PreventCSRF, this function could mangle uploaded binaries.

The last security function,

PreventXSS = yes

is designed to prevent cross-site scripting (XSS) attacks by replacing all the less than, greater than, quotes, and ticks in the URL with underscores.


A final treat is UrlToolkit, which works similarly to the Apache server's mod_rewrite. Each URL the web server reads is compared with predefined patterns. In the case of a match, Hiawatha will perform a predefined action. Any regular expression can serve as a test pattern [2]. Listing 3 gives a small example.

Listing 3

Two Rule Sets with UrlToolkit

01 UrlToolkit {
02     ToolkitID = varioustests
03     Match ^/php/ Return
04     Match /index.php4(.*) Rewrite /index.php$1
05 }
07 UrlToolkit {
08     ToolkitID = secret
09     Call varioustests
10     Match /secret(.*) DenyAccess
11 }

Listing 3 looks far more cryptic than it actually is. The listing defines two rule sets. The ToolkitID for the upper rule set is varioustests, whereas I called the second one secret. The varioustests rule set first checks to see whether the URL starts with /php/. If this is the case, Hiawatha stops all further tests with this rule set (Return). If not, it checks to see whether the URL starts with index.php4. In this case, Hiawatha replaces the string with /index.php; that is, it drops the 4 in the file name.

The second rule set, secret, starts by calling its colleague varioustests (Call) and then refuses access to the /secret subdirectory. Table 1 gives an overview of possible actions.

After specifying rules in httpd.conf, you only need to tell the web server which rule set to use:

UseToolkit = secret

Listing 4 shows the complete Hiawatha configuration.

Listing 4

Complete Configuration (httpd.conf)

01 #Basic configuration
02 Binding {
03         Port = 80
04         Interface =
05 }
07 Binding {
08         Port = 443
09         Interface =
10         UseSSL = yes
11         ServerKey = /usr/local/etc/hiawatha/serverkey.pem
12 }
14 WebsiteRoot = /usr/local/var/www/hiawatha
15 Hostname = localhost
17 #Logfiles
18 SystemLogfile = /usr/local/var/log/hiawatha/system.log
19 AccessLogfile = /usr/local/var/log/hiawatha/access.log
20 ErrorLogfile = /usr/local/var/log/hiawatha/error.log
21 GarbageLogfile = /usr/local/var/log/hiawatha/system.log
23 #Cache
24 CacheSize = 15
25 CacheMaxFilesize = 128
26 CacheMinFilesize = 256
28 #CGI
29 ExecuteCGI = yes
30 CGIextension = cgi
31 CGIhandler = /usr/bin/php5-cgi:php,php5
32 TimeForCGI = 5
33 #Nutze Wrapper:
34 WrapCGI = wrap_id
36 #Security functions
37 ServerId = www-data
38 ConnectionsTotal = 150
39 ConnectionsPerIP = 10
40 BanOnGarbage = 300
41 BanOnMaxReqSize = 60
42 BanOnFlooding = 10/1:35
43 BanOnCMDi = 60
44 BanOnSQLi = 70
45 BanlistMask = allow, deny
46 RebanDuringBan = yes
48 #UrlToolkit
49 UrlToolkit {
50         ToolkitID = varioustests
51         Match ^/php/ Return
52         Match /index.php4(.*) Rewrite /index.php$1
53 }
55 UrlToolkit {
56         ToolkitID = secret
57         Call varioustests
58         Match /secret(.*) DenyAccess
59 }
61 UseToolkit = secret


Besides the security functions described in this article, Hiawatha has a number of other clever capabilities. For example, the web server has a more intelligent approach to Gzip compression than its colleagues, and it gives you the option of an internal error handler. If the client requests an XML file and the matching XSLT file exists, Hiawatha will automatically perform XSL transformation if needed. If the execution speed of CGI scripts is too slow, you can enable the FastCGI mechanism. Hiawatha also has a good understanding of access privileges for directories. You can even throttle the upload speed for specified file types.

If you would like to know more about Hiawatha, check the slightly terse HowTo [2]. The HowTo even discusses the option of combining the web server with AppArmor and Grsecurity [3].

The Author

Tim Schürmann is a computer scientist and is currently working as a freelance author. Tim starting working with Linux back in the 1990s and has published several books and articles in various languages on the free operating system. Apart from that, he is absolutely convinced that VI must have been invented by the devil himself. For more information, visit Tim's homepage at

Read full article as PDF:

Related content

comments powered by Disqus

Direct Download

Read full article as PDF: