Skip to content

Instantly share code, notes, and snippets.

@DarthHTTP
Last active April 21, 2024 06:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DarthHTTP/eadd7da2a8ed0a3e1170f6973065bea3 to your computer and use it in GitHub Desktop.
Save DarthHTTP/eadd7da2a8ed0a3e1170f6973065bea3 to your computer and use it in GitHub Desktop.
haproxy+cloudflare
#
# Original idea:
# https://discourse.haproxy.org/t/haproxy-unable-to-redirect-to-https-when-terminating/2158
#
# Stats:
# https://blog.sleeplessbeastie.eu/2020/01/29/how-to-use-haproxy-stats-socket
#
# Global
global
log 127.0.0.1:514 local0
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
maxconn 4096
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
# Default
defaults
log global
option httplog
option redispatch
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors-custom/400.http
errorfile 403 /etc/haproxy/errors-custom/403.http
errorfile 408 /etc/haproxy/errors-custom/408.http
errorfile 500 /etc/haproxy/errors-custom/500.http
errorfile 502 /etc/haproxy/errors-custom/502.http
errorfile 503 /etc/haproxy/errors-custom/503.http
errorfile 504 /etc/haproxy/errors-custom/504.http
# Stats
frontend stats
mode http
bind :9000
stats enable
stats show-node
stats uri /stats
stats refresh 5s
# Restrict only to this node
acl local src 192.168.1.113
stats admin if local
# Upgrade to HTTPS unless it's Let's Encrypt
frontend http-in-80
mode http
bind :80
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-var(txn.txnhost) hdr(host)
acl letsencrypt_example_com var(txn.txnhost) -m reg -i ^([^\.]*)\.example\.com
use_backend example_com-http-backend if letsencrypt_example_com
redirect scheme https code 301 if !{ ssl_fc } !{ path_beg -i /.well-known/acme-challenge/ }
# if ACME generating problems - short-circuit here
# default_backend acmetool
# Handles the passthrough and loopsback for termination
frontend passthrough
mode tcp
bind :443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend example_com-backend if { req_ssl_sni -i example.com } or { req_ssl_sni -m end .example.com }
default_backend loopback
# Handles the termination domains on second pass
frontend termination
# crt-list if you have CF issued certs (origin certificate)
bind 127.0.0.1:8443 ssl crt-list /etc/haproxy/crt-list.txt alpn h2,http/1.1
option forwardfor
# Define known networks for later use
acl local src 127.0.0.0/8 192.168.1.0/24
acl cloudflare src 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/12 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
# Table for connection tracking
stick-table type ip size 100k expire 60s store conn_cur
# Allow known CloudFlare IPs to bypass the rate-limiting
tcp-request connection accept if cloudflare
# Reject connection if client has more than 200 open
tcp-request connection reject if { src_conn_cur ge 200 }
# Conntrack
tcp-request connection track-sc1 src
# Max inspection delay for SNI routing
tcp-request inspect-delay 2s
# Accept only SSL/TLS traffic
tcp-request content accept if { req_ssl_hello_type 1 }
http-request del-header X-Forwarded-Proto
http-request set-header X-Forwarded-Proto https if { ssl_fc }
# Here the switchboard for ssl-terminated domains
# use_backend example_org-backend if { ssl_fc_sni_end example.org }
# or
# default_backend example_org-backend
#Loopback for second pass
backend loopback
mode tcp
server https-front 127.0.0.1:8443
# Backend LetsEncrypt example.com
backend example_com-http-backend
mode http
retries 3
timeout server 300s
timeout connect 10s
server hp 192.168.1.100:80 check
# Backend example.com (no ssl termination)
backend example_com-backend
mode tcp
server nuc4 192.168.1.100:443
# Backend example.org (ssl termination at haproxy side)
backend example_org-backend
mode http
balance roundrobin
server node01 192.168.1.200:8080
server node02 192.168.1.201:8080
server node03 192.168.1.202:8080
http-request add-header X-Forwarded-Proto https
# Backend default - not used, if needed send requests in the woods
backend default-backend
mode http
server s1 1.1.1.1
http-request add-header X-Forwarded-Proto https
# Backend ACME
backend acmetool
mode http
balance roundrobin
server node01 192.168.1.253:80
server node02 192.168.1.254:80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment