Differences between revisions 1 and 2
Revision 1 as of 2021-11-04 15:29:50
Size: 3456
Comment:
Revision 2 as of 2021-11-04 15:31:36
Size: 3502
Comment:
Deletions are marked like this. Additions are marked like this.
Line 65: Line 65:
==== Using with Certbot ==== ==== Using with Let's Encrypt Certificates ====
Line 67: Line 67:
Let's Encrypt doesn't automatically generate a PEM-formatted certificate. The following script could be deployed as either a `cron(8)` job or a `certbot(1)` [[Encryption/Certbot#Hooks|post-installation hook]]. [[Encryption/LetsEncrypt|Let's Encrypt]] doesn't automatically generate a PEM-formatted certificate. The following script could be deployed as either a `cron(8)` job or a `certbot(1)` [[Encryption/Certbot#Hooks|post-installation hook]].

HAProxy

haproxy(1) is a TCP load balancer and reverse proxy.


Installation

Most Linux and BSD distributions offer a haproxy package.


Configuration

BSD distributions will look for configuration files in /usr/local/etc.

Basic Configuration

A minimal configuration file looks like:

global
  user haproxy
  group haproxy
  daemon

backend www_backend
  server www1 127.0.0.1:80

frontend http_in
  bind *:80
  mode http
  default_backend www_backend

A backend instructs haproxy(1) where traffic for a particular service should be routed to. Multiple servers can be defined in a backend and an algorithm for load balancing (i.e. roundrobin, leastconn, etc.) can be specified.

A frontend instructs haproxy(1) to listen on an address and/or port. In the above, http_in binds to any name on port 80 and handles HTTP traffic. A frontend also provides logic for routing traffic to the correct backend.

SSL Termination

haproxy(1) uses PEM-formatted certificates, which are fundamentally just the certificate and private key concatenated.

To terminate the encryption, the bind instruction requires some additional parameters. It is also important to set a minimum version of TLS as a configuration option.

global
  ssl-default-bind-options ssl-min-ver TLSv1.2

frontend https_frontend
  bind *:443 ssl crt /path/to/the/pem/certificate alpn h2, http1.1

Using with Let's Encrypt Certificates

Let's Encrypt doesn't automatically generate a PEM-formatted certificate. The following script could be deployed as either a cron(8) job or a certbot(1) post-installation hook.

domain="example.com"
dir="/etc/letsencrypt/live/${domain}"

cat "${dir}/fullchain.pem" "${dir}/privkey.pem" > "${dir}/${domain}.pem"

SSL Passthrough

If SSL/TSL certificates will not be handled by haproxy(1), then configuration is much the same as with unencrypted traffic. The exception is that mode must be set to tcp, as HTTP headers will not be available for inspection.

Thorough Configuration

HTTP headers can be inspected to logically route traffic. Consider the below frontend:

frontend http_frontend
  bind *:80
  bind *:443 ssl crt /path/to/the/pem/certificate alpn h2, http1.1
  mode http

  default_backend www_backend

  #route ACME challenge from Let's Encrypt to the certbot temporary server
  acl acme path_beg /.well-known/acme-challenge
  use_backend letsencrypt_backend if acme

  #upgrade traffic to HTTPS
  http-request redirect scheme https unless { ssl_fc }

  #route API requests
  acl api hdr(host) -i api.example.com

  #for webgit, split CGI requests from file requests
  acl webgit hdr(host) -i git.example.com
  acl cdn path_beg /js
  acl cdn path_beg /css
  use_backend www_backend if webgit ! cdn
  use_backend cdn_backend if cdn

This demonstrates:

  • ACLs are defined and calculated based on HTTP headers, including host names and URI paths
  • Re-using an ACL name is equivalent to a logical OR
  • ACL names can be chained, acting as a logical AND
  • ACLs can be negated by prefixing with an exclamation mark (!)

  • Order matters! Don't upgrade traffic to HTTPS before handling ACME challenge traffic


CategoryRicottone

HAProxy (last edited 2023-10-24 19:42:44 by DominicRicottone)