Serving static site like this with lets-encrypt certificates. OpenBSD provides the set of tools to do that out of the box.

  • acme-client for certificates
  • httpd for the file serving part
  • relayd for ssl and http header mangling

NOTE: most of the configuration samples here use hugo’s nginx syntax highlighter. At the time of writing this provided most readable results

Pre-requisites

Ensure that your packet filter is not blocking requests from outside. We need to expose ports 80 and 443.

acme-client

Create /etc/acme-client.conf

Add your domain at the bottom:

domain onnenmyyra.duckdns.org {
	# alternative names { secure.example.com }
	domain key "/etc/ssl/private/onnenmyyra.duckdns.org.key"
	domain certificate "/etc/ssl/onnenmyyra.duckdns.org.crt"
	domain full chain certificate "/etc/ssl/onnenmyyra.duckdns.org.fullchain.pem"
	sign with letsencrypt
}

Test that your config is valid.

acme-client -vn

httpd

Create /etc/httpd.conf

server "onnenmyyra.duckdns.org" {
	listen on 127.0.0.1 port 8080
	log style forwarded
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
	location "/*" {
		block return 301 "https://$HTTP_HOST$REQUEST_URI"
	}
}

server "onnenmyyra.duckdns.org" {
	listen on 127.0.0.1 port 8443
	log style forwarded
	root "/htdocs/onnenmyyra"
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
}

Test your configuration:

httpd -n

Enable and start httpd

rcctl enable httpd
rcctl start httpd

relayd

Create /etc/relayd.conf

httpd_port="8080"
https_port="8443"

table <local> { 127.0.0.1 }

log connection errors

http protocol "http" {
	match request header set "Connection" value "close"
	match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
	match request header append "X-Forwarded-Port" value "$REMOTE_PORT"
	match response header remove "Server"
}

relay "http_relay" {
	listen on onnenmyyra.duckdns.org port http
	protocol "http"
	forward to <local> port $httpd_port
}

http protocol https {
	tls keypair "onnenmyyra.duckdns.org.fullchain"

	match request header append "X-Forwarded-For" value "$REMOTE_ADDR"
	match request header append "X-Forwarded-Port" value "$REMOTE_PORT"
	match response header remove "Server"
}

relay "https_relay" {
	listen on onnenmyyra.duckdns.org port 443 tls
	protocol https
	forward to <local> port $https_port
}

Test your configuration

relayd -n

Start and enable relayd

rcctl enable relayd
rcctl start relayd

Getting certificates

Get set of certificates with acme-client

acme-client -v

Next create symlink for the full certificate chain’s key for the relayd

ln -s \
	/etc/ssl/private/onnenmyyra.duckdns.org.key \
	/etc/ssl/private/onnenmyyra.duckdns.org.fullchain.key

Finally reload the relayd

rcctl reload relayd

Setting automatic renewal

create /etc/daily.local

next_part "Refreshing Let's Encrypt certificates"
acme-client onnenmyyra.duckdns.org && rcctl reload relayd

Next steps

  • Mangle the httpd server headers with relayd so that the security headers are properly set
  • Create some content on your shiny new https enabled web server

References