This post is about Getting Started with OpenBSD httpd
Introduction
In this article, I’m going to go through the basics of configuring the httpd
web server which comes by default in the recent versions of OpenBSD (7.1, in this case). OpenBSD is well-known in the industry for being a great operating system when it comes to simplicity, code quality, and security. They’re also well-known for creating tons of good software, all free and open-source; among which some even come pre-installed on other operating systems. With the release of OpenBSD 5.6, they’ve started to include their own web server simply named httpd
.
httpd
is a web-server built to provide the most common web functions. OpenBSD is a great choice for hosting static web sites while also fulfilling basic website needs like handling PHP scripts, load balancing, etc. Furthermore, all of the software in its web stack will be built with the better, more secure LibreSSL library. Please have a look at the talk by Bob Beck on LibreSSL (Invidious / YouTube ) to learn why that project exists and why you should care about it. This much should give me enough reason to use httpd
on its native operating system – OpenBSD.
How httpd
Works
httpd
puts a lot of effort into minimizing its attack surface. It uses the concept of privilege separation where possible. When started, it spawns multiple processes, each handling a certain task. The part of the server that attaches to privileged ports and can open log files will be run as root
. Other processes will be unprivileged and will only have as much access as they require. Furthermore, httpd
will always run in a chroot
directory under /var/www
thus a code injection vulnerability in the web server won’t affect the rest of the system. That is, unless the hackers find a way to escape the sandbox, of course.
We will find several directories inside /var/www/
.
There are directories related to CGI (bin/
, cgi-bin/
). The default website will be at htdocs/
. The run/
directory is for UNIX sockets to be used byslowcgi
– OpenBSD’s implementation of the FastCGI protocol.
The httpd.conf(5)
The primary configuration of httpd
is done inside /etc/httpd.conf
. However, that file won’t exist by default. We can, however, have a look at the example file located at /etc/examples/httpd.conf
. So, a basic configuration would look like the following:
server "openbsd.local" {
listen on 192.168.1.10 port 80
root "/htdocs"
}
This configuration will make our openbsd.local
server serve files under /var/www/htdocs/
(remember the daemon will be chrooted inside /var/www/
) using plain HTTP. The configuration should be verified with doas httpd -n
.
Referring to the httpd.conf(5)
man page now, we find that the configuration contains the following sections:
- Macros
- Global Settings
- Servers
- Types
I’ll now go briefly over some of those sections so that we understand what we’re doing better before getting our hands dirty.
Macros
These are basically just variables. They allow us to avoid repeating information throughout our configuration by replacing them (the information) with a single identifier. Like macros in programming languages like C
, we have to define them at the top and then they can be accessed using the $
character, like so:
server_ip="192.168.1.10"
server "openbsd.local" {
listen on $server_ip port 80
root "/htdocs"
}
Servers
Like most web servers, OpenBSD httpd
also allows us to host multiple web sites within a single machine. In the above examples, we’ve used the server
keyword to define the configuration for a single virtual server named openbsd.local
.
Server names need not be unique throughout the configuration, provided they’re listening on different address or ports. This can also be done with the alias
keyword inside the server block. So, if we wanted the same site to be delivered as www.openbsd.local
as well, then we’d use the following configuration:
server "openbsd.local" {
# listen on all IP addresses
listen on * port 80
alias "www.openbsd.local"
root "/htdocs"
}
Assuming the required DNS entries exist, of course.
Global Settings
Note that the server
keyword follows with a set of curly braces. The configurations inside those braces apply only to the server, while the server_ip
will be visible throughout the configuration file. In this case, server_ip
is a global setting.
Types
When a server sends a file to a client, it needs to know what type of file it is so that the client can render it properly. These types are known as MIME types. We define the type according to its extension. So to define a type for our HTML files, we’d use the following syntax:
types {
text/html html htm
}
Having to define a MIME type for every extension possible is a great way to make your life (more) miserable. Thankfully, httpd
comes with a number of types already defined at /usr/share/misc/mime.types
. We simply have to include that file into our configuration. This is done with the include
keyword.
types {
include "/usr/share/misc/mime.types"
}
Basic Configuration
Let’s combine what we’ve learned and try out a simple configuration. I’ve put the following file under /var/www/htdocs/index.html
:
The configuration shall be as follows:
types {
include "/usr/share/misc/mime.types"
}
server "openbsd.local" {
# listen on all IP addresses
listen on * port 80
alias "www.openbsd.local"
root "/htdocs"
}
Check the configuration syntax with doas httpd -n
and start the service with doas rcctl start httpd
.
Now let’s load the website in our browser.
And it loads. That’s it for today. Hope you learned something from this article. Thank you for reading.
References
I have primarily used the Relayd and HTTPD Mastery by Michael W. Lucas in the making of this article. He has also written a lot of other books regarding similar IT topics. I wrote this section because I admire him and his work (and also his sense of humour) although I have not been able to fully support him.