Basic OpenHTTPd Configuration

OpenHTTPd is a light-weight web server developed by OpenBSD.

Overview

Pros:

  1. Lean: Small, no plugins
  2. Clean code
  3. Secure: Strict validity checking, privilege separation, strong cryptography
  4. Fast
  5. Easy to configure with good documentation

Docs and references

In addition to httpd(8) and httpd.conf(5) man pages, you may find the book Httpd and Relayd Mastery helpful. The book contains many configuration examples. https://learnbchs.org/LearnBCHS is also an interesting stack that uses OpenHTTPd.

Configuration

NOTE: Replace example.com with your own domain

First, copy the example file in /etc/examples/httpd.conf to /etc/:

$ doas cp /etc/examples/httpd.conf /etc/httpd.conf

Edit /etc/httpd.conf to read as follows:

server "example.com" {
	listen on * port 80
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
#	location * {
#		block return 302 "https://$HTTP_HOST$REQUEST_URI"
#	}
}

#server "example.com" {
#        listen on * tls port 443
#        tls {
#                certificate "/etc/ssl/example.com.fullchain.pem"
#                key "/etc/ssl/private/example.com.key"
#        }
#        location "/pub/*" {
#                directory auto index
#        }
#        location "/.well-known/acme-challenge/*" {
#                root "/acme"
#                request strip 2
#        }
#}

Replace example.com with your actual hostname. On some other web servers, this name is known as the virtual host.

Notice how we commented out two sections. We will leave these sections commented out until we have requested TLS certs.

Let's explain the configuration file:

listen on tells the web server to listen on all IPs on port 80.

The first location block in lines 3-6 responds to verification requests according to the ACME protocol. It is used in conjunction with acme-client for requesting TLS certs. For any request that begins with http://example.com/.well-known/acme-challenge/, httpd(8) will look for the documents in the new root /acme. Since OpenHTTPd chroots to /var/www by default, the document root is actually /var/www/acme/. The directive request strip 2 tells openhttpd to search in /var/www/acme/ and not /var/www/acme/.well-known/acme-challenge/ (two path components are stripped out).

Normally, the second location section in lines 7-9 would tell the web server to respond with HTTP 302 for all other requests. An HTTP 302 response forwards the web browser to a new URL address. Any user that connects to your web server using port 80, except for ACME verification, would be forwarded to use TLS on port 443 instead.

This second location block is suggested by OpenBSD, but in this lesson, we will serve unencrypted web pages to make configuration simpler. So for now, comment out the second location block (lines 7-9) as shown above.

Note: You must have a server block listening on port 80. Do not delete this block or else acme-client will not work. The web server needs the listener block on port 80 for ACME protocol verification.

To check that your configuration is valid:

$ doas httpd -n
configuration OK

Starting the server

Use to enable and start httpd(8):

$ doas rcctl enable httpd
$ doas rcctl start httpd
httpd(ok)

Create a web page

By default, our configuration serves documents in /var/www/htdocs. So, use a text editor to create a webpage in /var/www/htdocs/index.html . Perhaps you can put the phrase "Hello, World!".

Testing

Test to see if the web server is actually working on port 80. This test should be run on some other computer besides your web server (eg, use your home PC or phone).

The simplest test is to put the URL of your website into a web browser. For example, you might load http://example.com.

To view this on the command line, try telnet:

$ telnet example.com 80

At this point, you must type your web request:

GET /index.html HTTP/1.1
Host: example.com

You should a response similar to the one below:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 14
Content-Type: text/html
Date: Tue, 12 Nov 2024 06:19:33 GMT
Last-Modified: Tue, 12 Nov 2024 06:15:19 GMT
Server: OpenBSD httpd

Hello, world!
Connection closed by foreign host.

Troubleshooting

Configuration Errors

If you were unable to establish the connection above, the first test is to see if httpd(8) has any critical errors.

First, stop all httpd processes:

$ doas rcctl stop httpd

Next, confirm that httpd is no longer running:

$ ps -ax | grep httpd

Finally, run httpd in debug mode:

$ doas httpd -d

Observe if there are any errors. If so, fix those errors before proceeding with troubleshooting.

Permissions Error

$ ls -l /var/www/htdocs/index.html
-rw-r--r--  1 root  daemon  14 Nov 12 00:15 /var/www/htdocs/index.html

If the file index.html is not readable by httpd, the webpage cannot load. See chmod(1) and chown for more information about permissions on BSD.

Firewall

If you changed your firewall rules?, double check to ensure your firewall is not blocking port 80. By default, packet filter? allows web traffic, so the firewall will not block web traffic unless you have edited the default firewall ruleset.

Adding TLS

If you have successfully served unencrypted web pages on port 80, you'll now want to request a TLS cert using acme-client. After you obtain that cert, proceed to add TLS to openhttpd.

See Also:

  1. https://learnbchs.org/LearnBCHS
  2. acme-client
  3. OpenHTTPd (with TLS)