my general nick is fd0, but various variations exist because they had been in use, so you can also see me as fd1, fd0` etc.
Follow me on Twitter - Donate to OpenBSDHAproxy is a highspeed reverse proxy that is capable of loadbalancing various backend services, not just HTTP servers. Another great feature is offloading or terminating SSL connections in a central place.
In this example I am setting up a simple reverse proxy where SSL termination will take place and where a specific Let’s Encrypt frontend and backend will be configured.
First thing to do is to install HAproxy. This is done the standard way, from the pkg repository:
root@host# pkg_add haproxy
quirks-2.414 signed on 2018-03-28T14:24:37Z
haproxy-1.7.10: ok
The following new rcscripts were installed: /etc/rc.d/haproxy
See rcctl(8) for details.
Look in /usr/local/share/doc/haproxy for extra documentation.
root@host#
After the software has been has been installed it needs to be configured
root@host# cd /etc/haproxy
root@host# mv haproxy.cfg haproxy.cfg.distro
root@host#
Create a /etc/haproxy/haproxy.cfg with the following content:
global
log /dev/log local0 info # send logging to syslog
tune.ssl.default-dh-param 2048
# cipher settings
ssl-default-bind-ciphers 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
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers 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
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
maxconn 1024
chroot /var/haproxy
uid 604
gid 604
daemon
pidfile /var/run/haproxy.pid
defaults
log global
mode http
option httplog
option dontlognull
option redispatch
option forwardfor # add X-Forwarded-For headers to each request
option http-server-close # reduces latency between HAProxy and your users
# by closing connections but maintaining keep-alives.
retries 3
maxconn 2000
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http
bind :80
bind :::80
acl letsencrypt_acl path_beg /.well-known/acme-challenge/ # set Let's Encrypt ACL for matching URI
redirect scheme https if !{ ssl_fc } !letsencrypt_acl # redirect to HTTPS unless a
# Let's Encrypt request comes in
use_backend be-letsencrypt if letsencrypt_acl # In that case go to specific backend
frontend fe_https
# we define a list of certificate paths
bind :443 ssl crt-list /etc/letsencrypt/certs/crt-list.txt
bind :::443 ssl crt-list /etc/letsencrypt/certs/crt-list.txt
reqadd X-Forwarded-Proto:\ https # pass X-Forwarded-For: header on to webserver
# Default ACLs
acl h-fd0.openbsd.amsterdam hdr(host) -i fd0.openbsd.amsterdam
# Use Server name identification if applicable
use_backend be-fd0.openbsd.amsterdam if { ssl_fc_sni fd0.openbsd.amsterdam }
# Fallback to plain SSL if SNI unavailable
use_backend be-fd0.openbsd.amsterdam if h-fd0.openbsd.amsterdam
# Backends
backend be-fd0.openbsd.amsterdam
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
server fd0.openbsd.amsterdam 127.0.0.1:80 check
# Backend certbot
backend be-letsencrypt
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
server letsencrypt 127.0.0.1:<certbot portnumber>
As one can see, the certbot challenge/response will never reach any other webserver but its own, running on
localhost: