So Long Relayd, and Thanks for All the Fish
🏠Home
👋About
✍️Posts
🏗️Projects
🌐Colophon
💸Contribute
🤖Infra
💻Uses
🧠Wiki
So Long Relayd, and Thanks for All the Fish
2026-08-17
Running relayd alongside httpd on your OpenBSD web servers is no longer necessary for injecting HTTP security headers. Thanks to the incredible work by rsadowski@ we now have the ability to set our security headers directly inside httpd. Pretty awesome, right?
Note: I still love relayd and I'm aware that it offers more than simply applying HTTP security headers. If you still prefer using it, that's okay! Please don't yell at me!
Requirements
Before & After
Full Guide
Requirements
As of this time of writing (August 2026) you’ll need to be running your system on OpenBSD -current in order to use these new header sets in httpd. If you’re okay with being on the “cutting-edge”, you can update by running the following:
doas sysupgrade -s
This will trigger a pull of the latest snapshot instead of the next release. Your machine will reboot into the installer automatically, upgrade, and then reboot again.
Before & After
Previously your web server would need to have both of the following in order to include HTTP security headers:
/etc/httpd.conf:
server "yourcooldomain.com" {<br>alias "www.yourcooldomain.com"<br>listen on * tls port 443<br>root "/htdocs/yourcooldomain.com"<br>hsts
location "/.well-known/acme-challenge/*" {<br>root "/acme"<br>request strip 2
tls {<br>certificate "/etc/ssl/yourcooldomain.com.crt"<br>key "/etc/ssl/private/yourcooldomain.com.key"<br>server "yourcooldomain.com" {<br>alias "www.yourcooldomain.com"<br>listen on * port 80
location "/.well-known/acme-challenge/*" {<br>root "/acme"<br>request strip 2
block return 301 "https://$SERVER_NAME$REQUEST_URI"
/etc/relayd.conf:
ip4="YOUR IPv4"<br>ip6="YOUR IPv6"<br>table { 127.0.0.1 }<br>log connection
http protocol https {<br>match request header append "X-Forwarded-For" value "$REMOTE_ADDR"<br>match request header append "X-Forwarded-By" \<br>value "$SERVER_ADDR:$SERVER_PORT"<br>match request header set "Connection" value "close"
# Add security headers<br>match response header append "Strict-Transport-Security" value "max-age=31536000; includeSubDomains; preload"<br>match response header append "Cache-Control" value "public, max-age=86400"<br>match response header append "Content-Security-Policy" value "default-src 'self'; script-src 'self'; object-src 'none';"<br>match response header append "X-Content-Type-Options" value "nosniff"<br>match response header append "X-Frame-Options" value "SAMEORIGIN"<br>match response header append "Referrer-Policy" value "no-referrer"<br>match response header append "Permissions-Policy" value "interest-cohort=()"
match request header set "Accept-Encoding" value "gzip, deflate"
relay wwwtls {<br>listen on $ip4 port 443 tls<br>protocol https<br>forward to port 8080 check icmp<br>relay www6tls {<br>listen on $ip6 port 443 tls<br>protocol https<br>forward to port 8080 check icmp
But now we can place everything directly inside our httpd.conf, like so:
server "yourcooldomain.com" {<br>listen on * tls port 443<br>root "/htdocs/yourcooldomain.com"<br>hsts
# Security headers<br>header set "Strict-Transport-Security" "max-age=31536000; includeSubDomains; preload"<br>header set "Content-Security-Policy" "default-src 'self'; script-src 'self'; object-src 'none';"<br>header set "X-Content-Type-Options" "nosniff" always<br>header set "X-Frame-Options" "SAMEORIGIN" always<br>header set "Referrer-Policy" "no-referrer" always<br>header set "X-Permitted-Cross-Domain-Policies" "none" always<br>header set "X-XSS-Protection" "0" always<br>header set "Permissions-Policy" "interest-cohort=()"
# Avoid info leak: strip the revealing header (optional)<br>header remove "X-Powered-By"
location "/.well-known/acme-challenge/*" {<br>root "/acme"<br>request strip 2
tls {<br>certificate "/etc/ssl/yourcooldomain.com.crt"<br>key "/etc/ssl/private/yourcooldomain.com.key"
The above security header settings are just my personal preferences, this can be changed as you see fit. But that’s it!
Full Guide
If you’d like a more detailed guide that takes you through the entire process of setting up your own httpd web server running on OpenBSD, check it out here: httpd.rocks
Found this blog useful?<br>Consider donating or buy some custom stickers!
↑ Top of page
Website generated with wruby
Hosted on NearlyFreeSpeech.NET
View this website's source code
Check out NextDNS, TierHive & Fathom
No ads, trackers or cookies. Ever.
RSS Feed | Terms of Use