Basic OpenHTTPd Configuration
(redirected from Openbsd.Openhttpd)
OpenHTTPd is a light-weight web server developed by the OpenBSD dev team.
Overview
Pros:
- Lean: Small, no plugins
- Clean code
- Secure: Strict validity checking, privilege separation, strong cryptography
- Fast
- Easy to configure with good manpage documentation
Docs and references
You'll want to consult the httpd and httpd.conf man pages.
Configuring
NOTE: You must replace example.com with your own domain
Copy the example file in /etc/examples/httpd.conf
:
$ doas cp /etc/examples/httpd.conf /etc/httpd.conf
Edit /etc/httpd.conf
:
Server block #1
server "example.com" { listen on * port 80 location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } location * { block return 302 "https://$HTTP_HOST$REQUEST_URI" } }
server: this block specifies the hostname ( example.com
)". Change example.com
to your personal hostname, such as username.fruit.ircnow.org
. On other web servers, this might be known as the virtual host.
listen on: tells the web server to listen on all IPs on port 80.
location: (lines 3-6) is used for requesting certificates using ACME. It says that for any request that begins with http://example.com/.well-known/acme-challenge/, look for the documents in the new root /acme. By default, openhttpd chroots to /var/www, so the document root is actually /var/www/acme/
. The directive request strip 2
is needed so that openhttpd searches in /var/www/acme/
and not /var/www/acme/.well-known/acme-challenge/
.
location: (Lines 7-9) indicate that for all other requests, use the HTTP 302 response to forward the web browser to a new URL address. Any user that connects to your web server using port 80, except for ACME verification, will be forwarded to use TLS on port 443 instead.
Note: You must have a server block listening on port 80. Do not delete this block or else acme-client will not work.
Server block #2
server "example.com" { listen on * tls port 443 tls { certificate "/etc/ssl/example.com.fullchain.pem" key "/etc/ssl/private/example.com.key" } location "/pub/*" { directory auto index } location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } }
This block is similar to before. Replace example.com
.
There are only two differences.
Lines 2-6 tells the web server to listen on all IPs on port 443. As a result, we need a tls block to specify which SSL certs to use. Later, after you run acme-client, you will need to change the certificate and key to match your real files.
Lines 7-9 say that for any request that begins with https://example.com/pub/ should automatically show a directory listing. Normally this is not a good idea for security reasons, but for a public folder it should be fine.
Make sure to replace every instance of example.com
with your real hostname, then enable and start the web server:
Starting the server
$ doas rcctl enable httpd $ doas rcctl start httpd
Testing, testing
Let's test to see if the web server is working on port 80. This test should be run on some other computer besides your web server (your home PC or phone is fine). Let's use telnet:
$ telnet example.com 80 GET /index.html HTTP/1.1 Host: example.com
You should a response similar to the one below:
HTTP/1.0 302 Found Date: Tue, 23 Feb 2021 14:01:28 GMT OpenBSD httpd Connection: close Content-Type: text/html Content-Length: 486 Location: https://example.com/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>302 Found</title> <style type="text/css"><!-- body { background-color: white; color: black; font-family: 'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; } hr { border: 0; border-bottom: 1px dashed; } @media (prefers-color-scheme: dark) { body { background-color: #1E1F21; color: #EEEFF1; } a { color: #BAD7FF; } } --></style> </head> <body> <h1>302 Found</h1> <hr> <address>OpenBSD httpd</address> </body> </html> Connection closed by foreign host.
Troubleshooting
If you were unable to establish the connection above, it may be because your firewall is blocking port 80.
You can ensure pf allows incoming http connections by putting this line into /etc/pf.conf:
pass in quick proto tcp to port {http https}
Then, reload the pf rulesets:
$ doas pfctl -f /etc/pf.conf
Adding TLS
Next, you'll want to request an SSL cert using acme-client.
Go do that now, I'll wait...
Once you have a valid SSL cert, you'll want to open up /etc/httpd.conf and look for the tls block:
tls { certificate "/etc/ssl/example.com.fullchain.pem" key "/etc/ssl/private/example.com.key" }
change /etc/ssl/example.com.fullchain.pem
and /etc/ssl/private/example.com.key
so that the certificate and key match the real location of your SSL cert.
Then, restart the web server:
$ doas rcctl restart httpd
To test if your web server has a working SSL cert, use openssl:
$ openssl s_client -connect example.com:443
You should see the correct SSL subject and issuer:
$ openssl s_client -connect example.org:443 CONNECTED(00000003) depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R3 verify return:1 depth=0 CN = example.com verify return:1 depth=0 CN = example.com verify return:1 write W BLOCK --- Certificate chain 0 s:/CN=example.com i:/C=US/O=Let's Encrypt/CN=R3 1 s:/C=US/O=Let's Encrypt/CN=R3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- subject=/CN=example.com issuer=/C=US/O=Let's Encrypt/CN=R3 --- No client certificate CA names sent Server Temp Key: ECDH, X25519, 253 bits --- SSL handshake has read 3730 bytes and written 367 bytes --- New, TLSv1/SSLv3, Cipher is AEAD-AES256-GCM-SHA384 Server public key is 4096 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.3 Cipher : AEAD-AES256-GCM-SHA384 Session-ID: Session-ID-ctx: Master-Key: Start Time: 1614233943 Timeout : 7200 (sec) Verify return code: 0 (ok) ---
You can also visit the website using your web browser. Load your domain (e.g. https://example.com
). While you are likely to see an error such as 403 Forbidden if you havent set up a website, look for the SSL padlock in the address bar (which indicates your site is secure), then view more information about the certificate:
Attach:ssl-cert.png