How to secure your website with <em>haproxy</em>, certbot and nginx — fd0

fd0

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 OpenBSD

How to secure your website with haproxy, certbot and nginx

HAproxy

HAproxy 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:

Prev Next


OpenBSD in Amsterdam is a project by High5! and Powered by ssg (identity)
© 2008–2019 fd0  User Agreement  Privacy Policy