https://oxcrag.net/2017/04/30/wordpress-behind-haproxy-with-tls-termination/
TLS termination configuration
The problem with terminating TLS traffic before the web server, is that any good web application should be able to recognize that the client is coming from an insecure connection. Luckily, we can use HAProxy to tell WordPress that the connection was good up until the load balancer and to trust it the rest of the way. Be aware that this is an extremely bad idea if there is any way to reach the web server other than via your HAProxy:
/usr/share/wordpress/wp-config.php:
[...]
/** Make sure WordPress understands it's behind an SSL terminator */
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS']='on';
[...]
/etc/haproxy/haproxy.cfg:
[...]
frontend web-https
option http-server-close
http-request set-header X-Forwarded-Proto https if { ssl_fc }
[...]
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# modern configuration
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend stats
bind *:9000
mode http
log global
maxconn 10
stats enable
stats refresh 10s
stats show-node
stats auth nguyen:Anne1021
stats uri /
frontend www-http
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl/
http-request set-header X-Forwarded-Proto https if { ssl_fc }
# letsencryp validation path for cert request
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
acl wp_site hdr(host) -i bebubi.com
acl wp_site hdr(host) -i www.bebubi.com
acl wp_site hdr(host) -i wp.bebubi.com
acl wp_site hdr(host) -i bibube.com
acl wp_site hdr(host) -i www.bibube.com
acl wp_site hdr(host) -i wp.bibube.com
acl nc_site hdr(host) -i nc.bibube.com
acl nc_site hdr(host) -i nc.bebubi.com
use_backend letsencrypt-backend if letsencrypt-acl
use_backend wp-backend if wp_site
use_backend nc-backend if nc_site
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888
backend wp-backend
server wp 192.168.0.201:80
backend nc-backend
server nc 192.168.0.200:443 check ssl verify none
Installing Let’s Encrypt Client
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install certbot
Obtaining a Certificate
Verify Port 80 is Open Then sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d bibube.com -d wp.bibube.com -d nc.bibube.com -d www.bibube.com sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d bebubi.com -d wp.bebubi.com -d nc.bebubi.com -d www.bebubi.com
Automated renewal script
root@pi-haproxy:~# cat renewCerts #!/bin/bash certbot renew --force-renewal --standalone --preferred-challenges http --http-01-address 127.0.0.1:8888 # Loop through all Let's Encrypt certificates for CERTIFICATE in `find /etc/letsencrypt/live/* -type d`; do CERTIFICATE=`basename $CERTIFICATE` # Combine certificate and private key to single file cat /etc/letsencrypt/live/$CERTIFICATE/fullchain.pem /etc/letsencrypt/live/$CERTIFICATE/privkey.pem > /etc/haproxy/ssl/$CERTIFICATE.pem done systemctl reload haproxy.service