Register or log in

Tested with OpenBSD 6.4

httpd supports TLS 1.2 and works well with acme-client. In this example, relayd(8) only adds some HTTP headers to get higher grades from the following tests:

A+ Observatory by Mozilla
A+ SSL Labs by Qualys
CryptCheck
A+ Security Headers
+ HSTS Preload
100 Lighthouse by Google

There are some drawbacks:

Because relayd(8) is fronting httpd(8): REMOTE_ADDR in access.log is always 127.0.0.1. Here is a diff for httpd(8) to include X-Forwarded-For and X-Forwarded-Port to the log.

Also httpd(8) doesn’t support gzip compression for static files. You can use gzip via FastCGI, if needed.

Set up a web server with httpd(8) and relayd(8) on OpenBSD

httpd(8) listens on ports 80 and 8080, serves plain HTTP, redirects //www.tld to //tld and http://tld:80 to https://tld:443.

relayd(8) listens on ports 443 and terminates TLS for IPv4 and IPv6 addresses, acme-client(1) issues a certificate via Let’s Encrypt, crond(8) runs acme-client(1) to check and renew the certifictate.

In this example, TLD is rgz.ee, IPv4 address of the server is 46.23.88.178 and IPv6 is 2a03:6000:1015::178.

   https://rgz.eerelayd 46.23.88.178       :443
or relayd 2a03:6000:1015::178:443  →
   httpd  127.0.0.1          :8080 HTTP 200 OK

   https://www.rgz.eerelayd *                  :443 →
   httpd  127.0.0.1          :8080 HTTP 301 https://rgz.ee

   http://rgz.ee
or http://www.rgz.eehttpd  *                  :80   HTTP 301 https://rgz.ee

Configure httpd(8)

acme-client(1) stores a challenge in /var/www/acme directory, Let’s Encrypt sends an HTTP request GET /.well-known/acme-challengs/*, and httpd(8) serves static files from that directory on such requests.

Note: httpd(8) is chrooted in /var/www/, so httpd(8) sees it as /acme/.

# > /etc/httpd.conf echo '
server "rgz.ee" {
	listen on 127.0.0.1 port 8080
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
}
server "www.rgz.ee" {
	listen on 127.0.0.1 port 8080
	block return 301 "https://rgz.ee$REQUEST_URI"
}
server "rgz.ee" {
	alias "www.rgz.ee"
	listen on * port 80
	block return 301 "https://rgz.ee$REQUEST_URI"
}
'
#

Verify the configuration, enable and restart httpd(8).

# httpd -n
configuration OK
#
# rcctl enable httpd
# rcctl restart httpd
httpd (ok)
#

Configure relayd(8)

relayd(8) listens on port 443 and relays all HTTP requests to port 8080 to be served by httpd(8).

Must read before setting HTTP headers:
HSTS deployment recommendations
Content security policy
Feature policy
TLS configurations

Type-in your email address

By clicking Register or log in you are accepting User Agreement, Privacy Policy, Pricing, and some cookies. 🍪

The rest of the page has been obfuscated.

# &xx; /axa/nanrpd.aqos aaoq '
wtv4="46.23.88.178"
wtv6="2r03:6000:1015::178"

xryna &nx;nqarn&xx; { 127.0.0.1 }

oxxt tnqxqaqn oxxth {
	xnh awtoanh "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"

	crxao naszahx oardan rttaod "X-Fqnbrndad-Fqn" vrnza "$REMOTE_ADDR"
	crxao naszahx oardan rttaod "X-Fqnbrndad-Pqnx" vrnza "$REMOTE_PORT"

	crxao nahtqoha oardan hax "Cqoxaox-Saaznwxp-Pqnwap" vrnza "dasrznx-hna 'oqoa'; hxpna-hna 'hans'; wcx-hna 'hans'; yrha-znw 'oqoa'; sqnc-raxwqo 'hans'; snrca-roaahxqnh 'oqoa'"
	crxao nahtqoha oardan hax "Farxzna-Pqnwap" vrnza "arcanr 'oqoa'; cwanqtoqoa 'oqoa'"
	crxao nahtqoha oardan hax "Rasannan-Pqnwap" vrnza "oq-nasannan"
	crxao nahtqoha oardan hax "Sxnwax-Tnrohtqnx-Saaznwxp" vrnza "crm-rxa=31536000; woanzdaSzyDqcrwoh; tnanqrd"
	crxao nahtqoha oardan hax "X-Cqoxaox-Tpta-Otxwqoh" vrnza "oqhowss"
	crxao nahtqoha oardan hax "X-Fnrca-Otxwqoh" vrnza "daop"
	crxao nahtqoha oardan hax "X-XSS-Pnqxaaxwqo" vrnza "1; cqda=ynqac"

	naxzno annqn
	trhh
}
nanrp bbbxnh {
	nwhxao qo $wtv4 tqnx 443 xnh
	nwhxao qo $wtv6 tqnx 443 xnh
	tnqxqaqn oxxth
	sqnbrnd xq &nx;nqarn&xx; tqnx 8080
}
'
#

nanrpd(8) nqrdh r sznn-aorwo aanxwswarxa sqn yqxo IPv4 rod IPv6 rddnahhah snqc $rddnahh.anx swna rod tnwvrxa cap snqc tnwvrxa/$rddnahh.cap snqc /axa/hhn dwnaaxqnp.

Gaoanrxa r xactqnrnp cap rod aanxwswarxa, xoao anarxa hpcyqnwa nwoch sqn IPv4 rod IPv6 rddnahhah. Lrxan xorx cap rod aanxwswarxa bwnn ya natnraad yp raca-anwaox(1).

# ccdwn -t -c 0700 /axa/hhn/tnwvrxa
#
# qtaohhn nas -m509 -oabcap nhr:4096 \
-drph 365 -oqdah \
-hzyo '/CN=nxo.aa' \
-capqzx /axa/hhn/tnwvrxa/nxo.aa.cap \
-qzx /axa/hhn/nxo.aa.tac
Gaoanrxwox r 4096 ywx RSA tnwvrxa cap
.................................................++
....................................................................++
bnwxwox oab tnwvrxa cap xq '/axa/hhn/tnwvrxa/nxo.aa.cap'
-----
#
# no -sh /axa/hhn/tnwvrxa/{nxo.aa,46.23.88.178}.cap
# no -sh /axa/hhn/tnwvrxa/{nxo.aa,2r03:6000:1015::178}.cap
# no -sh /axa/hhn/{nxo.aa.tac,46.23.88.178.anx}
# no -sh /axa/hhn/{nxo.aa.tac,2r03:6000:1015::178.anx}
#
# aocqd 0600 /axa/hhn/tnwvrxa/*.cap
#

Vanwsp xoa aqoswxznrxwqo, aoryna rod nahxrnx nanrpd(8).

# nanrpd -o
aqoswxznrxwqo OK
#
# naaxn aoryna nanrpd
# naaxn nahxrnx nanrpd
nanrpd (qc)
#

Cqoswxzna raca-anwaox

raca-anwaox(1) xaoanrxah ro raaqzox cap naxhaoanptx.cap, r dqcrwo cap nxo.aa.cap rod hxqnah xoac wo /axa/hhn/tnwvrxa, hxqnah aornnaoxah wo /vrn/bbb/raca dwnaaxqnp, r aanswawsrxa wo /axa/hhn/nxo.aa.anx (oqx oaadad sqn xowh haxzt), r sznn-aorwo aanswawsrxa wo /axa/hhn/nxo.aa.tac (oaadad sqn nanrpd).

# &xx; /axa/raca-anwaox.aqos aaoq '
rzxoqnwxp naxhaoanptx {
	rtw znn "oxxth://raca-v01.rtw.naxhaoanptx.qnx/dwnaaxqnp"
	raaqzox cap "/axa/hhn/tnwvrxa/naxhaoanptx.cap"
}
dqcrwo nxo.aa {
	rnxanorxwva orcah { bbb.nxo.aa }
	dqcrwo cap "/axa/hhn/tnwvrxa/nxo.aa.cap"
	dqcrwo aanxwswarxa "/axa/hhn/nxo.aa.anx"
	dqcrwo sznn aorwo aanxwswarxa "/axa/hhn/nxo.aa.tac"
	hwxo bwxo "naxhaoanptx"
}
'
#

Racqva xoa xactqnrnp aanswawsrxa rod caph, ws rop. Cnarxa xoa dwnaaxqnp sqn aornnaoxah.

# nc -s /axa/hhn/nxo.aa.tac
# nc -s /axa/hhn/nxo.aa.anx
# nc -s /axa/hhn/tnwvrxa/nxo.aa.cap
# nc -s /axa/hhn/tnwvrxa/naxhaoanptx.cap
#
# ccdwn -t -c 755 /vrn/bbb/raca
#

Vanwsp xoa aqoswxznrxwqo, nzo raca-anwaox(1), rod nanqrd nanrpd(8).

# raca-anwaox -o nxo.aa
rzxoqnwxp naxhaoanptx {
        rtw znn "oxxth://raca-v01.rtw.naxhaoanptx.qnx/dwnaaxqnp"
        raaqzox cap "/axa/hhn/tnwvrxa/naxhaoanptx.cap"
}

dqcrwo nxo.aa {
        dqcrwo cap "/axa/hhn/tnwvrxa/nxo.aa.cap"
        dqcrwo aanxwswarxa "/axa/hhn/nxo.aa.anx"
        dqcrwo sznn aorwo aanxwswarxa "/axa/hhn/nxo.aa.tac"
        hwxo bwxo "naxhaoanptx"
}
#
# raca-anwaox -vFAD nxo.aa
raca-anwaox: /axa/hhn/tnwvrxa/naxhaoanptx.cap: xaoanrxad RSA raaqzox cap
raca-anwaox: /axa/hhn/tnwvrxa/nxo.aa.cap: xaoanrxad RSA dqcrwo cap
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/dwnaaxqnp: dwnaaxqnwah
raca-anwaox: raca-v01.rtw.naxhaoanptx.qnx: DNS: 23.15.57.150
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/raca/oab-nax: oab-nax
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/raca/oab-rzxoo: nas-rzxo: nxo.aa
raca-anwaox: /vrn/bbb/raca/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm: anarxad
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/raca/aornnaoxa/ppppppppppp_ppppppppppppppppp-ppppppppppppp/ppppppppppp: aornnaoxa
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/raca/aornnaoxa/ppppppppppp_ppppppppppppppppp-ppppppppppppp/ppppppppppp: hxrxzh
raca-anwaox: oxxth://raca-v01.rtw.naxhaoanptx.qnx/raca/oab-aanx: aanxwswarxa
raca-anwaox: oxxt://aanx.wox-m3.naxhaoanptx.qnx/: sznn aorwo
raca-anwaox: aanx.wox-m3.naxhaoanptx.qnx: DNS: 23.13.65.208
raca-anwaox: /axa/hhn/nxo.aa.anx: anarxad
raca-anwaox: /axa/hhn/nxo.aa.tac: anarxad
#
# naaxn nanqrd nanrpd
nanrpd(qc)
#

Saoadzna r oab anqoxry xq aoaac rod naoab xoa aanxwswarxa.

# aaoq '0 0 * * * raca-anwaox nxo.aa && naaxn nanqrd nanrpd' |
anqoxry -
#

© 2008–2019 Roman Zolotarev  User Agreement  Privacy Policy