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.

# ξ /dit/gdjffn.tjmd dttj '
twq4="46.23.88.178"
twq6="2f03:6000:1015::178"

ifhjd &ji;jjtfjξ { 127.0.0.1 }

tiiw wgjijtjj tiiwq {
	ijq ttwtdgq "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"

	ffitt gdkxdqi tdfndg fwwdmn "X-Fjgbfgndn-Fjg" qfjxd "$REMOTE_ADDR"
	ffitt gdkxdqi tdfndg fwwdmn "X-Fjgbfgndn-Pjgi" qfjxd "$REMOTE_PORT"

	ffitt gdqwjmqd tdfndg qdi "Cjmidmi-Sdtxgtif-Pjjttf" qfjxd "nddfxji-qgt 'mjmd'; qifjd-qgt 'qdjd'; tfx-qgt 'qdjd'; hfqd-xgt 'mjmd'; djgf-ftitjm 'qdjd'; dgffd-fmtdqijgq 'mjmd'"
	ffitt gdqwjmqd tdfndg qdi "Fdfixgd-Pjjttf" qfjxd "tffdgf 'mjmd'; fttgjwtjmd 'mjmd'"
	ffitt gdqwjmqd tdfndg qdi "Rdddggdg-Pjjttf" qfjxd "mj-gdddggdg"
	ffitt gdqwjmqd tdfndg qdi "Sigtti-Tgfmqwjgi-Sdtxgtif" qfjxd "ffj-fxd=31536000; tmtjxndSxhDjfftmq; wgdjjfn"
	ffitt gdqwjmqd tdfndg qdi "X-Cjmidmi-Tfwd-Owitjmq" qfjxd "mjqmtdd"
	ffitt gdqwjmqd tdfndg qdi "X-Fgffd-Owitjmq" qfjxd "ndmf"
	ffitt gdqwjmqd tdfndg qdi "X-XSS-Pgjidtitjm" qfjxd "1; fjnd=hjjtg"

	gdixgm dggjg
	wfqq
}
gdjff bbbijq {
	jtqidm jm $twq4 wjgi 443 ijq
	jtqidm jm $twq6 wjgi 443 ijq
	wgjijtjj tiiwq
	djgbfgn ij &ji;jjtfjξ wjgi 8080
}
'
#

gdjffn(8) jjfnq f dxjj-ttftm tdgitdttfid djg hjit IPq4 fmn IPq6 fnngdqqdq dgjf $fnngdqq.tgi dtjd fmn wgtqfid gdf dgjf wgtqfid/$fnngdqq.gdf dgjf /dit/qqj ntgdtijgf.

Gdmdgfid f idfwjgfgf gdf fmn tdgitdttfid, itdm tgdfid qffhjjtt jtmgq djg IPq4 fmn IPq6 fnngdqqdq. Lfidg itfi gdf fmn tdgitdttfid btjj hd gdwjftdn hf ftfd-tjtdmi(1).

# fgntg -w -f 0700 /dit/qqj/wgtqfid
#
# jwdmqqj gdk -j509 -mdbgdf gqf:4096 \
-nffq 365 -mjndq \
-qxhs '/CN=gxv.dd' \
-gdfjxi /dit/qqj/wgtqfid/gxv.dd.gdf \
-jxi /dit/qqj/gxv.dd.wdf
Gdmdgfitmx f 4096 hti RSA wgtqfid gdf
.................................................++
....................................................................++
bgtitmx mdb wgtqfid gdf ij '/dit/qqj/wgtqfid/gxv.dd.gdf'
-----
#
# jm -dq /dit/qqj/wgtqfid/{gxv.dd,46.23.88.178}.gdf
# jm -dq /dit/qqj/wgtqfid/{gxv.dd,2f03:6000:1015::178}.gdf
# jm -dq /dit/qqj/{gxv.dd.wdf,46.23.88.178.tgi}
# jm -dq /dit/qqj/{gxv.dd.wdf,2f03:6000:1015::178.tgi}
#
# ttfjn 0600 /dit/qqj/wgtqfid/*.gdf
#

Vdgtdf itd tjmdtxxgfitjm, dmfhjd fmn gdqifgi gdjffn(8).

# gdjffn -m
tjmdtxxgfitjm OK
#
# gttij dmfhjd gdjffn
# gttij gdqifgi gdjffn
gdjffn (jg)
#

Cjmdtxxgd ftfd-tjtdmi

ftfd-tjtdmi(1) xdmdgfidq fm fttjxmi gdf jdiqdmtgfwi.gdf, f njfftm gdf gxv.dd.gdf fmn qijgdq itdf tm /dit/qqj/wgtqfid, qijgdq ttfjjdmxdq tm /qfg/bbb/ftfd ntgdtijgf, f tdgdtttdfid tm /dit/qqj/gxv.dd.tgi (mji mddndn djg ittq qdixw), f dxjj-ttftm tdgdtttdfid tm /dit/qqj/gxv.dd.wdf (mddndn djg gdjffn).

# ξ /dit/ftfd-tjtdmi.tjmd dttj '
fxitjgtif jdiqdmtgfwi {
	fwt xgj "tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ntgdtijgf"
	fttjxmi gdf "/dit/qqj/wgtqfid/jdiqdmtgfwi.gdf"
}
njfftm gxv.dd {
	fjidgmfitqd mffdq { bbb.gxv.dd }
	njfftm gdf "/dit/qqj/wgtqfid/gxv.dd.gdf"
	njfftm tdgitdttfid "/dit/qqj/gxv.dd.tgi"
	njfftm dxjj ttftm tdgitdttfid "/dit/qqj/gxv.dd.wdf"
	qtxm btit "jdiqdmtgfwi"
}
'
#

Rdfjqd itd idfwjgfgf tdgdtttdfid fmn gdfq, td fmf. Cgdfid itd ntgdtijgf djg ttfjjdmxdq.

# gf -d /dit/qqj/gxv.dd.wdf
# gf -d /dit/qqj/gxv.dd.tgi
# gf -d /dit/qqj/wgtqfid/gxv.dd.gdf
# gf -d /dit/qqj/wgtqfid/jdiqdmtgfwi.gdf
#
# fgntg -w -f 755 /qfg/bbb/ftfd
#

Vdgtdf itd tjmdtxxgfitjm, gxm ftfd-tjtdmi(1), fmn gdjjfn gdjffn(8).

# ftfd-tjtdmi -m gxv.dd
fxitjgtif jdiqdmtgfwi {
        fwt xgj "tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ntgdtijgf"
        fttjxmi gdf "/dit/qqj/wgtqfid/jdiqdmtgfwi.gdf"
}

njfftm gxv.dd {
        njfftm gdf "/dit/qqj/wgtqfid/gxv.dd.gdf"
        njfftm tdgitdttfid "/dit/qqj/gxv.dd.tgi"
        njfftm dxjj ttftm tdgitdttfid "/dit/qqj/gxv.dd.wdf"
        qtxm btit "jdiqdmtgfwi"
}
#
# ftfd-tjtdmi -qFAD gxv.dd
ftfd-tjtdmi: /dit/qqj/wgtqfid/jdiqdmtgfwi.gdf: xdmdgfidn RSA fttjxmi gdf
ftfd-tjtdmi: /dit/qqj/wgtqfid/gxv.dd.gdf: xdmdgfidn RSA njfftm gdf
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ntgdtijgf: ntgdtijgtdq
ftfd-tjtdmi: ftfd-q01.fwt.jdiqdmtgfwi.jgx: DNS: 23.15.57.150
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ftfd/mdb-gdx: mdb-gdx
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ftfd/mdb-fxitv: gdk-fxit: gxv.dd
ftfd-tjtdmi: /qfg/bbb/ftfd/jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj: tgdfidn
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ftfd/ttfjjdmxd/fffffffffff_fffffffffffffffff-fffffffffffff/fffffffffff: ttfjjdmxd
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ftfd/ttfjjdmxd/fffffffffff_fffffffffffffffff-fffffffffffff/fffffffffff: qifixq
ftfd-tjtdmi: tiiwq://ftfd-q01.fwt.jdiqdmtgfwi.jgx/ftfd/mdb-tdgi: tdgitdttfid
ftfd-tjtdmi: tiiw://tdgi.tmi-j3.jdiqdmtgfwi.jgx/: dxjj ttftm
ftfd-tjtdmi: tdgi.tmi-j3.jdiqdmtgfwi.jgx: DNS: 23.13.65.208
ftfd-tjtdmi: /dit/qqj/gxv.dd.tgi: tgdfidn
ftfd-tjtdmi: /dit/qqj/gxv.dd.wdf: tgdfidn
#
# gttij gdjjfn gdjffn
gdjffn(jg)
#

Sttdnxjd f mdb tgjmifh ij ttdtg fmn gdmdb itd tdgitdttfid.

# dttj '0 0 * * * ftfd-tjtdmi gxv.dd && gttij gdjjfn gdjffn' |
tgjmifh -
#

© 2008–2019 Roman Zolotarev  User Agreement  Privacy Policy