Hosting OpenHTTPd
Goal
This guide will providing web hosting for multiple users on a shared, multi-user server. This setup supports multiple, custom domain names. Afterwards, we will use relayd to provide TLS encryption.
This guide assumes you have read the basic openhttpd configuration guide. This is a slightly more advanced setup.
Configuration
For each user we want to support, we must add two blocks to /etc/httpd.conf. Here's the first block:
server "user.example.com" { alias "www.example.org" listen on * port 80 root "/htdocs/user/" location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } }
Line 1 says that this block is for the hostname "user.example.com". On other
web servers, this might be known as the virtual host. Replace this with
the user's actual subdomain. If the user has an additional domain name he
wishes to use, change the alias "www.example.org" to match his actual domain
name. For each extra domain name, add a new alias line. If he does not have
an alternative name, you can delete the alias "www.example.com"
line.
Line 3 tells the web server to listen on all IPs on port 80.
Line 4 tells us that the root directory for all web documents are in /htdocs/user/
. Remember, however, that openhttpd runs inside a chroot. All root directories should therefore be prepended with the path /var/www
. So, web documents are actually fetched from /var/www/htdocs/user/
. If a web browser requests https://user.example.com/index.html
, openhttpd would respond with the file /var/www/htdocs/user/index.html
.
Lines 5-8 (the location block) is used for requesting certificates using ACME. For any request that begins with http://user.example.com/.well-known/acme-challenge/
, openhttpd will look for documents in the new root /acme
. Again, openhttpd chroots to /var/www
by default, so the document root is actually /var/www/acme/
. The directive request strip 2
tells openhttpd to strip off the last two path components from the URL, so that it searches in /var/www/acme/
rather than /var/www/acme/.well-known/acme-challenge/
.
Note: You must have a server block listening on port 80. Do not delete this block or else acme-client will not work.
Note: Unlike in /etc/examples/httpd.conf
, this guide does not automatically redirect to port 443. Some older web browsers do not support TLS, and we do not want to break backwards compatibility.
Notice that we do not add any blocks with TLS. TLS will be provided by relayd.
Creating Web Files
Next, we create a directory for each web folder, and a symbolic link in each user's home folder that points to that web folder:
$ doas mkdir -p /var/www/htdocs/user/ $ doas ln -s /var/www/htdocs/user/ /home/user/htdocs $ doas chown -R username:daemon /var/www/htdocs/user/
Again, user
with the user's actual username, and user.example.com
with the actual subdomain.
Users will now be able to create new web files by putting them in ~/htdocs/
.
Start the Server and Test
For the test below, you will want to create an index file in
/home/username/htdocs/index.html
.
Enable and restart the web server:
$ doas rcctl enable httpd $ doas rcctl restart httpd
Testing Port 80
To see if the web server is working on port 80, run a test on another computer besides the web server. Here, we use telnet:
$ telnet user.example.com 80 GET /index.html HTTP/1.1 Host: user.example.com
You should a response similar to the one below:
HTTP/1.1 200 OK Connection: keep-alive Content-Length: 34 Content-Type: text/html Date: Sun, 28 Feb 2021 02:07:55 GMT Last-Modified: Sat, 27 Feb 2021 10:22:27 GMT Server: OpenBSD httpd
Troubleshooting
First, stop any active openhttpd processes:
$ doas rcctl stop httpd $ doas pkill httpd
To check for any configuration errors, run:
$ doas httpd -n
At any time, you can run openhttpd in debug mode:
$ doas httpd -dvv
Firewall
If there were no errors when running openhttpd in debug mode, you may need to check your firewall? to see if it's blocking packets to port 80.
Adding TLS
Next, you'll want to request an SSL cert using acme-client for each domain the user requested.
TLS Acceleration
Finally, you'll want to configure relayd for TLS acceleration.