OpenBSD httpd 7.3: Web server
Tags: openbsd, httpd, web, server
Published: 2023-05-06 05:17:08

## Summary

OpenBSD develops and maintains their own web server called "[httpd](https://man.openbsd.org/httpd.8)" under [ISC license](https://cvsweb.openbsd.org/src/share/misc/license.template?rev=HEAD).
It is installed by default in OS installation.

The great web server is something that is simple, robust and secure.
On performance, it is not the fastest among the competitors. However, it is enough fast, and, in addition, the development is in progress. For example, support to [gzip compression](https://man.openbsd.org/httpd.conf.5#gzip-static) has begun since [7.1](https://www.openbsd.org/71.html).

In addition, the integration of httpd and [relayd](https://man.openbsd.org/relayd.8), their native relay daemon, makes your servers more functional.

This post will bring you to the journey to get how to configure httpd and run it. Bon voyage 🐡

### Environment

- OS: OpenBSD [7.3](https://www.openbsd.org/73.html)
- Web: OpenBSD httpd

## Tutorial

### Prepare the configuration file

[`httpd.conf`](https://man.openbsd.org/httpd.conf.5) is required in order to activate httpd service.
The default path is `/etc/httpd.conf`. You can also [work with the `include` keyword](https://man.openbsd.org/httpd.conf#DESCRIPTION):

> Additional configuration files can be included with the include keyword, for example:
> 
> include "/etc/httpd.conf.local"

#### Create `httpd.conf`

Copy the template from `/etc/examples`:

```console
$ doas cp -p /etc/examples/httpd.conf /etc/
```

Alternatively, of course, it can be created manually:

```console
$ doas nvim /etc/httpd.conf
```

#### The template content

The template is like this:

```apache
# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $

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
	}
}
```

#### Remember `chroot` works

`root` property in "SERVERS" section above means the directories under `/var/www` . The official document mentions in [GLOBAL CONFIGURATION](https://man.openbsd.org/httpd.conf.5#GLOBAL_CONFIGURATION) section:

> chroot directory
> 
> Set the chroot(2) directory. If not specified, it defaults to /var/www, the home directory of the www user.

### Edit `httpd.conf` (Optional)

Now you can modify the conf file to build server as you want:

```console
$ doas nvim /etc/httpd.conf
```

#### Case [PHP](https://www.php.net/) [FastCGI](https://www.php.net/manual/en/install.fpm.php) servers

Additional server definitions may be like these:

```apache
server "www.https-example.domain" { 
    alias "https-example.domain" 
    listen on * port 80 
    listen on * tls port 443
    tls {
        key         "/etc/ssl/private/www.https-example.domain.key"
        certificate "/etc/ssl/www.https-example.domain.crt"
    }
    root "/htdocs/www.https-example.domain" 
}

server "www.fastcgi-tcp-example.domain" {
    alias "fastcgi-example.domain"
    listen on * port 80
    fastcgi socket tcp 127.0.0.1 8080
}

server "www.fastcgi-unix-socket-example.domain" {
    alias "fastcgi-example.domain"
    listen on * port 80
    fastcgi socket "/run/example/unix_socket.sock"
}
```

#### Case TLS connection

You can get certificate by [Let's Encrypt](https://letsencrypt.org/) with [`acme-client`](https://man.openbsd.org/acme-client.1).

First, copy the configuration file template in `/etc/examples`:

```console
$ doas cp -p /etc/examples/acme-client.conf /etc/
```

Then edit it to add your servers:

```console
$ doas nvim /etc/acme-client.conf
```

Also edit `httpd` servers if necessary:

```console
$ doas nvim /etc/httpd.conf
```

Finally run the command:

```console
$ acme-client -vd xxx
```

The detail is in [this post](https://obsd.solutions/en/blog/2022/03/04/openbsd-acme-client-70-for-letsencrypt-certificates/index.html).

### Activate the `httpd` daemon

Enable httpd:

```shell-session
# rcctl enable httpd
```

Besides, `/etc/rc.conf.local` will be created like this if it is the first time:

```console
# cat /etc/rc.conf.local
httpd_flags=
```

Then start it:

```shell-session
# rcctl start httpd
httpd(ok)
```

#### Alternatively, `-f` option helps for temporary confirmation

You can also run `rcctl -f start httpd` to start httpd forcely under the default setting, `httpd_flags=NO`.

### Test if the server listens

Your `httpd` server are now ready to reply to HTTP requests. Let's try it.

Make `index.html`:

```console
# mkdir -p /var/www/htdocs/www.https-example.domain
# # as needed:
# #chown www:www /var/www/htdocs/www.https-example.domain

$ echo "Hello, world. from OpenBSD httpd" > \
      /var/www/www.https-example.domain/index.html
```

Then send HTTP request in your client:

```console
$ curl localhost:80
```

Your client must *GET*:

```
Hello, world. from OpenBSD httpd
```

## Conclusion

You can add more servers with `/etc/httpd.conf`.
Moreover, when you have many servers, you can define parts of them in external files with `include` keyword as written above. For example:

```diff
  # httpd.conf
  (...)
+ include "/etc/httpd.d/another.conf"
```

Remember to restart the daemon by running `doas rcctl restart httpd` after changing `httpd.conf`.

---

### Historical backgrounds (as reference)

OpenBSD httpd first appeared in [5.6](https://www.openbsd.org/56.html). In the same version, they decided to remove [Apache](http://httpd.apache.org/) httpd from their base. In the next, [5.7](https://www.openbsd.org/57.html), [Nginx](https://www.nginx.com/resources/wiki/start/topics/tutorials/openbsd/) was removed, too.

Do you remember "[Heartbleed](https://en.wikipedia.org/wiki/Heartbleed)" and "[Shellshock](https://en.wikipedia.org/wiki/Shellshock_(software_bug))", the vulnerabilities and the scare ? Issues on them and others happened in 2014. It made bad effects on SSL connection and CGI servers and so on in severe level.

The OpenBSD projects made their best effort to improve the situation. For instance, they developed [LibreSSL](https://www.libressl.org/) and made it their native library instead of [OpenSSL](https://www.openssl.org/). They also tried to improve memory allocation methods. It was in the process that they developed their native web server called "httpd".

### Use of other web servers

It is also possible to get Nginx, Apache (called "apache-httpd"), [Lighttpd](https://www.lighttpd.net/) and [darkhttpd](https://github.com/emikulic/darkhttpd) as (thankfullly) maintained packages based on the [Ports](https://www.openbsd.org/faq/ports/ports.html) system.
You can install each of them by executing [`pkg_add`](https://man.openbsd.org/pkg_add).
It's also possible to get even [Caddy](https://caddyserver.com/) by manually installing.

---

Happy serving 🕊