Forked from DarthHTTP/gist:eadd7da2a8ed0a3e1170f6973065bea3
Created
April 21, 2024 06:55
-
-
Save machsix/9d0f861fa1dcd995632b60fb4a125cdf to your computer and use it in GitHub Desktop.
haproxy+cloudflare
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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