Hosting a website on OpenBSD

openbsd-banner1.gif

These notes detail how to setup an HTTPS enabled web server hosted by OpenBSD. The configuration supports the following,

The webserver is provided by the standard httpd(8) daemon, which is a refreshingly simple piece of software, configured like so in /etc/httpd.conf,

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

server "druid.fish" {
	listen on * tls port 443
	tls {
		certificate "/etc/ssl/druid.fish.crt"
		key "/etc/ssl/private/druid.fish.key"
	}

	location "/public/*" {
		root "/public"
		request strip 1
		directory auto index
	}

	location "/files/*" {
		root "/files"
		request strip 1
		authenticate "Home page" with "/files/htpasswd"
		directory auto index
	}

	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}

	root "/druid.fish"
}

server "files.druid.fish" {
	listen on * tls port 443
	tls {
		certificate "/etc/ssl/druid.fish.crt"
		key "/etc/ssl/private/druid.fish.key"
	}

	root "/files"
	authenticate "Home Page" with "/files/htpasswd"
	directory auto index

	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}

}

types {
    include "/usr/share/misc/mime.types"
}

Always run httpd -n after making changes to check the syntax, then rcctl reload httpd to have the daemon reread its configuration.

Getting HTTPS support is little tricky, but with letsencrypt its quite doable without spending hundreds of dollars! The point of HTTPS is that we can prove to our visitors that we own the domain by using a trusted third-party. The visitor and myself both trust LetsEncrypt (a Certificate Authority), by adding the following to the webserver,

location "/.well-known/acme-challenge/*" {
	root "/acme"
	request strip 2
}

as above, an ACME-client can automatically handle all the mintae regarding PKI. OpenBSD again ships a wonderful utility called acme-client that we can use to this for us. First configure the ACME-client in /etc/acme-client.conf,

authority letsencrypt {
  api url "https://acme-v02.api.letsencrypt.org/directory"
  # This will be generated the first time acme-client is run
  account key "/etc/ssl/private/letsencrypt.key"
}

domain druid.fish {
  domain name druid.fish
  # For subdomains
  alternative names { "files.druid.fish" }
  domain key "/etc/ssl/private/druid.fish.key"
  domain full chain certificate "/etc/ssl/druid.fish.crt"
  sign with letsencrypt
}

Then, running acme-client druid.fish && rcctl reload httpd gets us HTTPS without anymore intervention required.

See LetsEncrypt's documentation for more details on this process.

To handle certificates expiring, put this in the crontab,

@daily acme-client druid.fish && rcctl reload httpd

Qualys. SSL Labs SSL Server Test is a great utility to ensure you have a correctly setup HTTPS site, ensuring old ciphers and such are not mistakenly being used.

Created: 2021-11-28 Sun 17:57

Validate