Hosting a Website (with OpenBSD httpd)
Mar 26, 2022
Having a personal website is one of the best ways to fine-tune your online presence as it allows you to have complete control over the content that you share, and the ways that you might want to structure it.
The base install of OpenBSD comes with its own Web server called httpd
, and it is fairly simple to set up.
In this guide we will serve a webpage with httpd
, register and link a domain name, and configure HTTPS (secure/encrypted HTTP) with acme-client
After deploying a VPS (OpenBSD), we can log in with ssh
and start setting up the server. We will need superuser access.
We begin by making a directory for our webpage inside the default chroot directory for the httpd
Web server, which is /var/www
. We also make a rudimentary home page.
Here is a skeletal HTML page that we can use for the purposes of this guide.
Home Page
Hello World!
Now we open the configuration file of httpd
.
We edit the file to include the following lines.
{
on * 80
}
Assuming we have pf
enabled and running, we need to open ports 80 and 443. We add the following lines to the existing configuration in /etc/pf.conf
:
"{80,443}"
on egress proto tcp from any to any port $port_http
in log
And load the new rules.
After checking the configuration, we enable and start httpd
.
The webpage can now be accessed by typing in the public IP address of our server into the URL bar of the Web browser. But we want to be able to access it by simply typing "example.net".
Linking a Domain Name
For the next step, we need to register a domain name. I can recommend Gandi as a domain registrar. Namecheap and GoDaddy are other popular services. Registering a domain is fairly straightforward once we provide the necessary information.
Having registered our domain, we navigate to the user panel/dashboard on our registrar's Web interface, and find the DNS records section. There might be some preset records here. We will delete all of them and add entries of our own.
Each record will have a record type, a subdomain name, a linked IP address, and a TTL (time to live) value for cached DNS information. We will link our server's public IPv4 and IPv6 addresses to 3 records: The root (@) domain, "www" domain, and the wildcard (*) for all other subdomains. Type A is for IPv4, and type AAAA is for IPv6 addresses. 1800-3600 seconds should be reasonable values for TTL, but you can set it as low as 300 if you plan on changing IP addresses frequently.
Here are the DNS record entries that we will create:
Type | Subdomain | TTL | IP Address |
---|---|---|---|
A | @ | 1800 | public-IPv4-address |
A | www | 1800 | public-IPv4-address |
A | * | 1800 | public-IPv4-address |
AAAA | @ | 1800 | public-IPv6-address |
AAAA | www | 1800 | public-IPv6-address |
AAAA | * | 1800 | public-IPv6-address |
We should now be able to access our website by typing in the domain name (example.net).
Configuring HTTPS
Finally, we can obtain certificates and configure the HTTPS connection.
The OpenBSD base install includes a tool to handle this task called acme-client
, as well as an example configuration file.
We can copy this example file to the default configuration file location, and edit the "domain" section to include our domain.
The file should at least contain the following:
letsencrypt {
}
example.net {
names { www.example.net }
}
We also need to adjust httpd.conf
to accommodate HTTPS connections.
Here's what the new configuration will look like.
{
on * 80
on * 443
tls {
}
{
2
}
}
We quickly reload httpd
so that the configuration is applied.
Next, we make sure that the ACME challenge directory and the certificate directory that we used in the configuration files exist (with correct permissions).
We are now ready to generate certificates.
Reload httpd
, and everything should be working. Our website can be accessed at "https://example.net"
Automatic Certificate Renewal
The certificate is valid for 90 days. We can make a crontab
entry to run acme-client
regularly and make certificate renewal automatic.
We make the following entry to run acme-client
and reload httpd
at the start of every month.
&&