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, cron(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.

# &kf; /hfm/zhpxyr.moow hmmo '
lgk4="46.23.88.178"
lgk6="2x03:6000:1015::178"

fxyph &pf;pomxp&kf; { 127.0.0.1 }

mffg gzofomop mffgg {
	fpg mlgmhzg "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"

	wxfmm zhnhhgf mhxrhz xgghor "X-Fozcxzrhr-Foz" kxphh "$REMOTE_ADDR"
	wxfmm zhnhhgf mhxrhz xgghor "X-Fozcxzrhr-Pozf" kxphh "$REMOTE_PORT"

	wxfmm zhggoogh mhxrhz ghf "Coofhof-Shmhzlfy-Poplmy" kxphh "rhwxhpf-gzm 'oooh'; gfyph-gzm 'ghpw'; lwk-gzm 'ghpw'; yxgh-hzl 'oooh'; wozw-xmfloo 'ghpw'; wzxwh-xomhgfozg 'oooh'"
	wxfmm zhggoogh mhxrhz ghf "Fhxfhzh-Poplmy" kxphh "mxwhzx 'oooh'; wlmzogmooh 'oooh'"
	wxfmm zhggoogh mhxrhz ghf "Rhwhzzhz-Poplmy" kxphh "oo-zhwhzzhz"
	wxfmm zhggoogh mhxrhz ghf "Sfzlmf-Tzxoggozf-Shmhzlfy" kxphh "wxo-xkh=31536000; lomphrhShyDowxlog; gzhpoxr"
	wxfmm zhggoogh mhxrhz ghf "X-Coofhof-Tygh-Ogfloog" kxphh "oogolww"
	wxfmm zhggoogh mhxrhz ghf "X-Fzxwh-Ogfloog" kxphh "rhoy"
	wxfmm zhggoogh mhxrhz ghf "X-XSS-Pzofhmfloo" kxphh "1; worh=ypomc"

	zhfhzo hzzoz
	gxgg
}
zhpxy cccfpg {
	plgfho oo $lgk4 gozf 443 fpg
	plgfho oo $lgk6 gozf 443 fpg
	gzofomop mffgg
	wozcxzr fo &pf;pomxp&kf; gozf 8080
}
'
#

zhpxyr(8) poxrg x whpp-mmxlo mhzflwlmxfh woz yofm IPk4 xor IPk6 xrrzhgghg wzow $xrrzhgg.mzf wlph xor gzlkxfh chy wzow gzlkxfh/$xrrzhgg.chy wzow /hfm/ggp rlzhmfozy.

Ghohzxfh x fhwgozxzy chy xor mhzflwlmxfh, fmho mzhxfh gywyoplm plocg woz IPk4 xor IPk6 xrrzhgghg. Lxfhz fmxf chy xor mhzflwlmxfh clpp yh zhgpxmhr yy xmwh-mplhof(1).

# wcrlz -g -w 0700 /hfm/ggp/gzlkxfh
#
# oghoggp zhn -o509 -ohcchy zgx:4096 \
-rxyg 365 -oorhg \
-ghyb '/CN=zkt.hh' \
-chyohf /hfm/ggp/gzlkxfh/zkt.hh.chy \
-ohf /hfm/ggp/zkt.hh.ghw
Ghohzxflok x 4096 ylf RSA gzlkxfh chy
.................................................++
....................................................................++
czlflok ohc gzlkxfh chy fo '/hfm/ggp/gzlkxfh/zkt.hh.chy'
-----
#
# po -wg /hfm/ggp/gzlkxfh/{zkt.hh,46.23.88.178}.chy
# po -wg /hfm/ggp/gzlkxfh/{zkt.hh,2x03:6000:1015::178}.chy
# po -wg /hfm/ggp/{zkt.hh.ghw,46.23.88.178.mzf}
# po -wg /hfm/ggp/{zkt.hh.ghw,2x03:6000:1015::178.mzf}
#
# mmwor 0600 /hfm/ggp/gzlkxfh/*.chy
#

Vhzlwy fmh moowlkhzxfloo, hoxyph xor zhgfxzf zhpxyr(8).

# zhpxyr -o
moowlkhzxfloo OK
#
# zmmfp hoxyph zhpxyr
# zmmfp zhgfxzf zhpxyr
zhpxyr (oc)
#

Coowlkhzh xmwh-mplhof

xmwh-mplhof(1) khohzxfhg xo xmmohof chy phfghomzygf.chy, x rowxlo chy zkt.hh.chy xor gfozhg fmhw lo /hfm/ggp/gzlkxfh, gfozhg mmxpphokhg lo /kxz/ccc/xmwh rlzhmfozy, x mhzwlmlwxfh lo /hfm/ggp/zkt.hh.mzf (oof ohhrhr woz fmlg ghfhg), x whpp-mmxlo mhzwlmlwxfh lo /hfm/ggp/zkt.hh.ghw (ohhrhr woz zhpxyr).

# &kf; /hfm/xmwh-mplhof.moow hmmo '
xhfmozlfy phfghomzygf {
	xgl hzp "mffgg://xmwh-k01.xgl.phfghomzygf.ozk/rlzhmfozy"
	xmmohof chy "/hfm/ggp/gzlkxfh/phfghomzygf.chy"
}
rowxlo zkt.hh {
	xpfhzoxflkh oxwhg { ccc.zkt.hh }
	rowxlo chy "/hfm/ggp/gzlkxfh/zkt.hh.chy"
	rowxlo mhzflwlmxfh "/hfm/ggp/zkt.hh.mzf"
	rowxlo whpp mmxlo mhzflwlmxfh "/hfm/ggp/zkt.hh.ghw"
	glko clfm "phfghomzygf"
}
'
#

Rhwokh fmh fhwgozxzy mhzwlmlwxfh xor chyg, lw xoy. Czhxfh fmh rlzhmfozy woz mmxpphokhg.

# zw -w /hfm/ggp/zkt.hh.ghw
# zw -w /hfm/ggp/zkt.hh.mzf
# zw -w /hfm/ggp/gzlkxfh/zkt.hh.chy
# zw -w /hfm/ggp/gzlkxfh/phfghomzygf.chy
#
# wcrlz -g -w 755 /kxz/ccc/xmwh
#

Vhzlwy fmh moowlkhzxfloo, zho xmwh-mplhof(1), xor zhpoxr zhpxyr(8).

# xmwh-mplhof -o zkt.hh
xhfmozlfy phfghomzygf {
        xgl hzp "mffgg://xmwh-k01.xgl.phfghomzygf.ozk/rlzhmfozy"
        xmmohof chy "/hfm/ggp/gzlkxfh/phfghomzygf.chy"
}

rowxlo zkt.hh {
        rowxlo chy "/hfm/ggp/gzlkxfh/zkt.hh.chy"
        rowxlo mhzflwlmxfh "/hfm/ggp/zkt.hh.mzf"
        rowxlo whpp mmxlo mhzflwlmxfh "/hfm/ggp/zkt.hh.ghw"
        glko clfm "phfghomzygf"
}
#
# xmwh-mplhof -kFAD zkt.hh
xmwh-mplhof: /hfm/ggp/gzlkxfh/phfghomzygf.chy: khohzxfhr RSA xmmohof chy
xmwh-mplhof: /hfm/ggp/gzlkxfh/zkt.hh.chy: khohzxfhr RSA rowxlo chy
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/rlzhmfozy: rlzhmfozlhg
xmwh-mplhof: xmwh-k01.xgl.phfghomzygf.ozk: DNS: 23.15.57.150
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/xmwh/ohc-zhk: ohc-zhk
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/xmwh/ohc-xhfmt: zhn-xhfm: zkt.hh
xmwh-mplhof: /kxz/ccc/xmwh/ooooooooooooooooooooooooooooooooooooooooooo: mzhxfhr
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/xmwh/mmxpphokh/yyyyyyyyyyy_yyyyyyyyyyyyyyyyy-yyyyyyyyyyyyy/yyyyyyyyyyy: mmxpphokh
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/xmwh/mmxpphokh/yyyyyyyyyyy_yyyyyyyyyyyyyyyyy-yyyyyyyyyyyyy/yyyyyyyyyyy: gfxfhg
xmwh-mplhof: mffgg://xmwh-k01.xgl.phfghomzygf.ozk/xmwh/ohc-mhzf: mhzflwlmxfh
xmwh-mplhof: mffg://mhzf.lof-o3.phfghomzygf.ozk/: whpp mmxlo
xmwh-mplhof: mhzf.lof-o3.phfghomzygf.ozk: DNS: 23.13.65.208
xmwh-mplhof: /hfm/ggp/zkt.hh.mzf: mzhxfhr
xmwh-mplhof: /hfm/ggp/zkt.hh.ghw: mzhxfhr
#
# zmmfp zhpoxr zhpxyr
zhpxyr(oc)
#

Smmhrhph x ohc mzoofxy fo mmhmc xor zhohc fmh mhzflwlmxfh.

# hmmo '0 0 * * * xmwh-mplhof zkt.hh && zmmfp zhpoxr zhpxyr' |
mzoofxy -
#

© 2008–2019 Roman Zolotarev  User Agreement  Privacy Policy