OpenBSD Blog #14: Password-protecting httpd(8) with htpasswd(1)
A quick entry today. I just got HTTP "Basic Auth" working with OpenBSD’s web server, httpd(8). My guide to getting started was the book Httpd & Relayd Mastery by Michael W. Lucas.
Create basic your password file
The htpasswd program comes with OpenBSD and uses bcyrpt(3) hashing to create
a password (or password file).
The easiest way to create a password file is to let htpasswd create it for
you by supplying the filename and a user entry to create (if the entry already
exists, it will be updated, so you can use this same command to change passwords).
$ doas /var/www/htpasswords dave Password: Retype Password:
Tell httpd to use authentication
Use the httpd.conf(5) directive authenticate.
You can either secure the whole virtual server:
server "foo" {
...
authenticate with "/htpasswords"
}
Or just a location:
server "foo" {
...
location "/private-files/" {
authenticate with "/htpasswords"
}
}
The htpasswords file name and location are up to you, but remember that the file
path must be relative to the httpd instance’s chroot path (also defined in
httpd.conf).
Note: I found that htpasswd created the password file with 0600 permissions.
I needed to use chmod to give the httpd daemon permission to read it. There were
no messages in error.log or access.log and no indication that the daemon was
unable to read the file - the login simply failed as if I had mistyped it.
Reload the configuration with, e.g. doas rcctl reload httpd.
You do not need to reload httpd again after making changes to the password file.
It will be read afresh with each login attempt.
Try it out
Now accessing the server (or location) as specified in httpd.conf pops up the standard
browser login box asking for a username and password.
After success, you can confirm it’s working by viewing network traffic in your browser dev tools. Look for the "basic auth" type in the HTTP request header like so:
Authorization: Basic <password hash goes here>==
The user name will also appear in the web server access.log:
foo 10.0.0.2 - dave [16/Mar/2026:11:27:52 -0400] "GET / HTTP/1.1" 200 0
Note that basic auth (developer.mozilla.org) is transmitted as base64 encoding (essentially plain text), so if you’re using this over the public Internet, make sure you’re only doing it with TLS encryption so you don’t accidentally send your password in the clear!