WIP!
Most of this site is incomplete, and the current state is available as an open draft. Most of the text here is likely incomplete, misinformed, or just plain wrong. I'm looking for feedback on my website, so that I can:
- Fill in what I'm missing
- Take out what's unnecessary
- Figure out my target audience
- Find the right way to structure the site
- Filter out any errors
To anyone who wants to send me feedback, thank you, and shoot me an email!
This guide shows you how to host a secure website on OpenBSD with its Httpd and Acme Client.
Set up Httpd
The HTTP daemon is OpenBSD’s built-in HTTP server that enables you to host your website. It also supports HTTPS, which secures your website against eavesdropping and ad injection, and FastCGI, which enables an interface between web servers and interactive programs. This guide will show how to host a plain HTTP server before securing it with HTTPS and the Acme Client.
Create the file /etc/httpd.conf:
# Httpd is configured as multiple "servers", which are really just
# rules to match what to serve depending on the hostname that users are looking for.
# We're configure for both www.example.org and example.org.
# I'll assume you have both hostnames set up as DNS A records.
server "www.example.org" {
listen on egress port http
# Serve files found in /var/www/htdocs/example.org</strong>.</span>
root "/htdocs/example.org"
}
server "example.org" {
listen on egress port http
# Route example.org</strong> requests to point to the www subdomain instead.</span>
return 301 "http://www.example.org$REQUEST_URI"
}
Create your first webpage
Create the file /var/www/htdocs/example.org/index.html:
<h1>Hello, world</h1>
<p>This is an example webpage</p>
Start Httpd
Check the configuration and start Httpd:
$ doas httpd -n
configuration OK
$ doas rcctl enable httpd
$ doas rcctl start httpd
httpd(OK)
Enable Encryption on Httpd
HTTPS requires SSL certificates that certify that those who control your domain (read: you) are who you’re talking securely to. The Acme Client guide goes more in-depth how to manage SSL certificates in general. This guide will do the minimum to set it up for HTTPS.
Create and edit /etc/acme-client.conf
:
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
domain example.org {
alternative names { www.example.org }
domain key "/etc/ssl/private/example.org.key"
domain certificate "/etc/ssl/example.org.cert"
domain full chain certificate "/etc/ssl/example.org.fullchain.pem"
sign with letsencrypt
}
The Acme Client also needs some cooperation with Httpd. Edit /etc/httpd.conf:
server "www.example.org" {
listen on egress port http
root "/htdocs/example.org"
location found "/.well-known/acme-challenge/*" {
# acme-client will plop challenge files in /var/www/acme, that
# httpd needs to serve.
root "/acme"
# strip down the "/.well-known/acme-challenge" portion of the
# request before looking it up here.
request strip 2
}
}
server "example.org" {
listen on egress port http
return 301 "http://www.example.org$REQUEST_URI"
}
Check the configuration and restart Httpd:
$ doas httpd -n
configuration OK
$ doas rcctl restart httpd
httpd(OK)
httpd(OK)
Grab a Certificate
Run the Acme Client to grab a certificate:
$ doas acme-client -v example.org
Edit Httpd to serve HTTPS
Edit /etc/httpd.conf
to add HTTPS support:
server "example.org" {
# HTTPS is just HTTP on TLS, so the server should now enable TLS when
# receiving incoming requests on the HTTPS port:
listen on egress tls port https
tls {
# TLS needs the certificate and private key generated by the
# Acme Client:
certificate "/etc/ssl/example.org.fullchain.pem"
key "/etc/ssl/private/example.org.key"
}
root "/htdocs/example.org"
# Still support Acme Client for renewing SSL clients.
# Some CA's (like Let's Encrypt) allow redirects and intentionally
# doesn't verify HTTPS certs, so that servers can pick back up from
# self-signed or expired certificates. Not all do. At minimum they should
# support (insecure) HTTP requests without having to redirect -- so this
# block should appear just about everywhere to cover all bases.
location found "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
}
server "www.example.org" {
listen on egress port http
# If any browsers use HTTP on accident, redirect them to HTTPS:
block return 301 "https://www.example.com$REQUEST_URI"
location found "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
# Ignore the "block" directive from earlier.
pass
}
}
server "example.org" {
# For the non-WWW hostname, support both HTTP and HTTPS, and redirect to HTTPS.
listen on egress port http
listen on egress tls port https
tls {
certificate "/etc/ssl/example.org.fullchain.pem"
key "/etc/ssl/private/example.org.key"
}
return 301 "https://www.example.org$REQUEST_URI"
location found "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
pass
}
}
Restart Httpd
Check the configuration and restart Httpd:
$ doas httpd -n
configuration OK
$ doas rcctl restart httpd
httpd(OK)
httpd(OK)
Save bandwidth via gzip compression
Since OpenBSD 7.1 (released 2022 April 21), Httpd released a new feature gzip-static
, which serves pre-compressed files if they’re provided.
This feature has to be explicitly enabled:
server "www.example.org" {
…
gzip-static
}
The feature works by reviewing the pathname to a requested file, and if a sister file with an additional “.gz” suffix exists, Httpd serves that file instead. For example, the file /about/index.html.gz can be served in place of /about/index.html.
Compressing the file is simple with gzip:
$ cd /var/www/htdocs/example.org
# The -k flag indicates we should keep the old file,
# and -9 indicates we want the best compression.
$ gzip -k9 index.html
Going one step further, you can generate a gzipped mirror of all files within a directory tree with a smartly placed shell command:
# Tally up every file in the directory and create a gzipped copy right next to it.
find /var/www/htdocs/example.org -type f -exec gzip -vk9 {} +
Going Further
- Host CGI-Powered Web Apps on OpenBSD
- Password-protect OpenBSD Websites with htpasswd
- Monitor OpenBSD Website Activity with GoAccess
External Links
- Http and Relayd Mastery - Michael W Lucas