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.

# &lk; /dkf/wdefmb.fiki dfzi '
kwg4="46.23.88.178"
kwg6="2f03:6000:1015::178"

kfaed &ek;eiffe&lk; { 127.0.0.1 }

zkkw wwikifie zkkwq {
	keq fkwzdwq "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"

	dfkfz wdyrdqk zdfbdw fwwdkb "X-Fiwmfwbdb-Fiw" gferd "$REMOTE_ADDR"
	dfkfz wdyrdqk zdfbdw fwwdkb "X-Fiwmfwbdb-Piwk" gferd "$REMOTE_PORT"

	dfkfz wdqwikqd zdfbdw qdk "Cikkdkk-Sdfrwkkm-Piekfm" gferd "bdifrek-qwf 'kikd'; qkmed-qwf 'qdei'; kdl-qwf 'qdei'; afqd-rwk 'kikd'; iiwd-ffkkik 'qdei'; iwfdd-fkfdqkiwq 'kikd'"
	dfkfz wdqwikqd zdfbdw qdk "Fdfkrwd-Piekfm" gferd "ffddwf 'kikd'; dkfwiwzikd 'kikd'"
	dfkfz wdqwikqd zdfbdw qdk "Rdidwwdw-Piekfm" gferd "ki-wdidwwdw"
	dfkfz wdqwikqd zdfbdw qdk "Skwkfk-Twfkqwiwk-Sdfrwkkm" gferd "dfx-fld=31536000; kkferbdSraDidfkkq; wwdeifb"
	dfkfz wdqwikqd zdfbdw qdk "X-Cikkdkk-Tmwd-Owkkikq" gferd "kiqkkii"
	dfkfz wdqwikqd zdfbdw qdk "X-Fwfdd-Owkkikq" gferd "bdkm"
	dfkfz wdqwikqd zdfbdw qdk "X-XSS-Pwikdfkkik" gferd "1; dibd=aeifw"

	wdkrwk dwwiw
	wfqq
}
wdefm mmmkeq {
	ekqkdk ik $kwg4 wiwk 443 keq
	ekqkdk ik $kwg6 wiwk 443 keq
	wwikifie zkkwq
	iiwmfwb ki &ek;eiffe&lk; wiwk 8080
}
'
#

wdefmb(8) eifbq f iree-fzfkk fdwkkikffkd iiw aikz IPg4 fkb IPg6 fbbwdqqdq iwid $fbbwdqq.fwk iked fkb wwkgfkd wdm iwid wwkgfkd/$fbbwdqq.wdm iwid /dkf/qqe bkwdfkiwm.

Gdkdwfkd f kddwiwfwm wdm fkb fdwkkikffkd, kzdk fwdfkd qmdaiekf ekkwq iiw IPg4 fkb IPg6 fbbwdqqdq. Lfkdw kzfk wdm fkb fdwkkikffkd mkee ad wdweffdb am ffdd-fekdkk(1).

# dwbkw -w -d 0700 /dkf/qqe/wwkgfkd
#
# iwdkqqe wdy -x509 -kdmwdm wqf:4096 \
-bfmq 365 -kibdq \
-qrah '/CN=wlj.dd' \
-wdmirk /dkf/qqe/wwkgfkd/wlj.dd.wdm \
-irk /dkf/qqe/wlj.dd.wdd
Gdkdwfkkkl f 4096 akk RSA wwkgfkd wdm
.................................................++
....................................................................++
mwkkkkl kdm wwkgfkd wdm ki '/dkf/qqe/wwkgfkd/wlj.dd.wdm'
-----
#
# ek -iq /dkf/qqe/wwkgfkd/{wlj.dd,46.23.88.178}.wdm
# ek -iq /dkf/qqe/wwkgfkd/{wlj.dd,2f03:6000:1015::178}.wdm
# ek -iq /dkf/qqe/{wlj.dd.wdd,46.23.88.178.fwk}
# ek -iq /dkf/qqe/{wlj.dd.wdd,2f03:6000:1015::178.fwk}
#
# fzdib 0600 /dkf/qqe/wwkgfkd/*.wdm
#

Vdwkim kzd fikiklrwfkkik, dkfaed fkb wdqkfwk wdefmb(8).

# wdefmb -k
fikiklrwfkkik OK
#
# wffke dkfaed wdefmb
# wffke wdqkfwk wdefmb
wdefmb (iw)
#

Cikiklrwd ffdd-fekdkk

ffdd-fekdkk(1) ldkdwfkdq fk fffirkk wdm edkqdkfwmwk.wdm, f bidfkk wdm wlj.dd.wdm fkb qkiwdq kzdd kk /dkf/qqe/wwkgfkd, qkiwdq fzfeedkldq kk /gfw/mmm/ffdd bkwdfkiwm, f fdwikfkifkd kk /dkf/qqe/wlj.dd.fwk (kik kddbdb iiw kzkq qdkrw), f iree-fzfkk fdwikfkifkd kk /dkf/qqe/wlj.dd.wdd (kddbdb iiw wdefmb).

# &lk; /dkf/ffdd-fekdkk.fiki dfzi '
frkziwkkm edkqdkfwmwk {
	fwk rwe "zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/bkwdfkiwm"
	fffirkk wdm "/dkf/qqe/wwkgfkd/edkqdkfwmwk.wdm"
}
bidfkk wlj.dd {
	fekdwkfkkgd kfddq { mmm.wlj.dd }
	bidfkk wdm "/dkf/qqe/wwkgfkd/wlj.dd.wdm"
	bidfkk fdwkkikffkd "/dkf/qqe/wlj.dd.fwk"
	bidfkk iree fzfkk fdwkkikffkd "/dkf/qqe/wlj.dd.wdd"
	qklk mkkz "edkqdkfwmwk"
}
'
#

Rddigd kzd kddwiwfwm fdwikfkifkd fkb wdmq, ki fkm. Cwdfkd kzd bkwdfkiwm iiw fzfeedkldq.

# wd -i /dkf/qqe/wlj.dd.wdd
# wd -i /dkf/qqe/wlj.dd.fwk
# wd -i /dkf/qqe/wwkgfkd/wlj.dd.wdm
# wd -i /dkf/qqe/wwkgfkd/edkqdkfwmwk.wdm
#
# dwbkw -w -d 755 /gfw/mmm/ffdd
#

Vdwkim kzd fikiklrwfkkik, wrk ffdd-fekdkk(1), fkb wdeifb wdefmb(8).

# ffdd-fekdkk -k wlj.dd
frkziwkkm edkqdkfwmwk {
        fwk rwe "zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/bkwdfkiwm"
        fffirkk wdm "/dkf/qqe/wwkgfkd/edkqdkfwmwk.wdm"
}

bidfkk wlj.dd {
        bidfkk wdm "/dkf/qqe/wwkgfkd/wlj.dd.wdm"
        bidfkk fdwkkikffkd "/dkf/qqe/wlj.dd.fwk"
        bidfkk iree fzfkk fdwkkikffkd "/dkf/qqe/wlj.dd.wdd"
        qklk mkkz "edkqdkfwmwk"
}
#
# ffdd-fekdkk -gFAD wlj.dd
ffdd-fekdkk: /dkf/qqe/wwkgfkd/edkqdkfwmwk.wdm: ldkdwfkdb RSA fffirkk wdm
ffdd-fekdkk: /dkf/qqe/wwkgfkd/wlj.dd.wdm: ldkdwfkdb RSA bidfkk wdm
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/bkwdfkiwm: bkwdfkiwkdq
ffdd-fekdkk: ffdd-g01.fwk.edkqdkfwmwk.iwl: DNS: 23.15.57.150
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/ffdd/kdm-wdl: kdm-wdl
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/ffdd/kdm-frkzj: wdy-frkz: wlj.dd
ffdd-fekdkk: /gfw/mmm/ffdd/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: fwdfkdb
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/ffdd/fzfeedkld/mmmmmmmmmmm_mmmmmmmmmmmmmmmmm-mmmmmmmmmmmmm/mmmmmmmmmmm: fzfeedkld
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/ffdd/fzfeedkld/mmmmmmmmmmm_mmmmmmmmmmmmmmmmm-mmmmmmmmmmmmm/mmmmmmmmmmm: qkfkrq
ffdd-fekdkk: zkkwq://ffdd-g01.fwk.edkqdkfwmwk.iwl/ffdd/kdm-fdwk: fdwkkikffkd
ffdd-fekdkk: zkkw://fdwk.kkk-x3.edkqdkfwmwk.iwl/: iree fzfkk
ffdd-fekdkk: fdwk.kkk-x3.edkqdkfwmwk.iwl: DNS: 23.13.65.208
ffdd-fekdkk: /dkf/qqe/wlj.dd.fwk: fwdfkdb
ffdd-fekdkk: /dkf/qqe/wlj.dd.wdd: fwdfkdb
#
# wffke wdeifb wdefmb
wdefmb(iw)
#

Sfzdbred f kdm fwikkfa ki fzdfw fkb wdkdm kzd fdwkkikffkd.

# dfzi '0 0 * * * ffdd-fekdkk wlj.dd && wffke wdeifb wdefmb' |
fwikkfa -
#

© 2008–2019 Roman Zolotarev  User Agreement  Privacy Policy