Skip to content

Instantly share code, notes, and snippets.

@artembokhan
Forked from git001/haproxy-sni.txt
Created May 14, 2020 21:15
Show Gist options
  • Save artembokhan/3a5b2cb603825104e2cc5a9b9abbe862 to your computer and use it in GitHub Desktop.
Save artembokhan/3a5b2cb603825104e2cc5a9b9abbe862 to your computer and use it in GitHub Desktop.
haproxy setup for sni routing
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log stdout format raw daemon debug
log-send-hostname cloud.DOMAIN.com
maxconn 5000
ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets
tune.ssl.default-dh-param 2048
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode tcp
log global
option dontlognull
option logasap
option srvtcpka
option log-separate-errors
retries 3
timeout http-request 10s
timeout queue 2m
timeout connect 10s
timeout client 5m
timeout server 5m
timeout http-keep-alive 10s
timeout check 10s
maxconn 750
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
##
## Frontend for HTTP
##
frontend http-in
bind :::80 v4v6
mode http
option httplog
# redirect http to https .
http-request redirect scheme https unless { ssl_fc }
##
## Frontend for HTTPS
##
frontend public_ssl
log global
option tcplog
bind :::443 v4v6
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_fc_has_sni '%[ssl_fc_has_sni]' sni:'%[capture.req.hdr(0)]' ssl_fc_sni '%[ssl_fc_sni]' ssl_fc_protocol '%[ssl_fc_protocol]' ssl_bc '%[ssl_bc]' ssl_bc_alpn '%[ssl_bc_alpn]' ssl_bc_protocol '%[ssl_bc_protocol]' ssl_c_i_dn '%[ssl_c_i_dn()]' ssl_c_s_dn '%[ssl_c_s_dn()]' ssl_f_i_dn '%[ssl_f_i_dn()]' ssl_f_s_dn '%[ssl_f_s_dn]' ssl_fc_cipher '%[ssl_fc_cipher]' "
tcp-request inspect-delay 5s
tcp-request content capture req.ssl_sni len 25
tcp-request content accept if { req.ssl_hello_type 1 }
# use_backend be_sni_xmpp if { req.ssl_sni -i -MyDomain.im }
# https://www.haproxy.com/blog/introduction-to-haproxy-maps/
use_backend %[req.ssl_sni,lower,map(tcp-domain2backend-map.txt)]
default_backend be_sni
##########################################################################
# TLS SNI
#
# When using SNI we can terminate encryption with dedicated certificates.
##########################################################################
backend be_sni
server fe_sni 127.0.0.1:10444 weight 10 send-proxy-v2-ssl-cn
backend be_sni_xmpp
server fe_sn_xmpp 127.0.0.1:10442 weight 10 send-proxy-v2-ssl-cn
# handle https incomming
frontend https-in
# terminate ssl
bind 127.0.0.1:10444 accept-proxy ssl strict-sni crt /usr/local/etc/haproxy/cloud-MyDomain-com.pem crt /usr/local/etc/haproxy/dashboard-MyDomain-com.pem crt /usr/local/etc/haproxy/upload-MyDomain-com.pem crt /usr/local/etc/haproxy/-MyDomain-com.pem
mode http
option forwardfor
option httplog
# log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_fc_has_sni '%[ssl_fc_has_sni]' sni:'%[capture.req.hdr(0)]' ssl_fc_sni '%[ssl_fc_sni]' ssl_fc_protocol '%[ssl_fc_protocol]' ssl_bc '%[ssl_bc]' ssl_bc_alpn '%[ssl_bc_alpn]' ssl_bc_protocol '%[ssl_bc_protocol]' ssl_c_i_dn '%[ssl_c_i_dn()]' ssl_c_s_dn '%[ssl_c_s_dn()]' ssl_f_i_dn '%[ssl_f_i_dn()]' ssl_f_s_dn '%[ssl_f_s_dn]' ssl_fc_cipher '%[ssl_fc_cipher]' "
# this creates a warning and this varibale is empty
# I think because the tcp termination is done in public_ssl
# tcp-request content capture req.ssl_sni len 25
# Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
http-request del-header Proxy
# from doc: front connection was made via an SSL/TLS transport
# When I use a tcp frontend and chain it via backend/frontend,
# like in this config, is this fe a front connection?
http-request redirect scheme https unless { ssl_fc_has_sni }
http-request set-header X-Forwarded-Proto https
# added from option forwardfor http-request set-header X-Forwarded-For %[src]
# makes this sence?
http-request set-header X-Forwarded-Host %[ssl_fc_sni]
## this does not work
#acl host_nc req.ssl_sni -i cloud.DOMAIN.com
# I would like to use this
# should this work?
# maybe a map would be better?
# use_backend nextcloud-backend if ssl_fc_sni -i cloud.DOMAIN.com
# https://www.haproxy.com/blog/introduction-to-haproxy-maps/
use_backend %[req.hdr(host),lower,map(http-domain2backend-map.txt)]
##
## Frontend for Galera Cluster
##
frontend galera-tcp-in
bind 127.0.0.1:3306
default_backend galera-backend
##
## Frontend for LDAP Cluster
##
frontend ldap-tcp-in
bind 127.0.0.1:389
default_backend ldap-backend
##
## Frontend for LDAP Cluster (encrypted)
##
frontend ldaps-tcp-in
bind 127.0.0.1:636
default_backend ldaps-backend
#---------------------------------------------------------------------
# backends
#---------------------------------------------------------------------
## backend for cloud.DOMAIN.com
backend nextcloud-backend
mode http
redirect scheme https if !{ ssl_fc }
option httpclose
option forwardfor
option httpchk GET / HTTP/1.1\r\nHost:\ cloud.-MyDomain-.com
server -MyDomain-cloud 127.0.0.1:81 check
## backend for dashboard.DOMAIN.com
backend dashboard-backend
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option httpclose
option forwardfor
server -MyDomain-cloud 127.0.0.1:82 check
## backend for upload.DOMAIN.im
backend httpupload-backend
log global
mode http
server -MyDomain-cloud 127.0.0.1:8443 check
## backend for DOMAIN.im (XMPP C2S)
listen xmppc2s-backend
bind 127.0.0.1:10442 accept-proxy ssl strict-sni crt /usr/local/etc/haproxy/upload-MyDomain-com.pem crt /usr/local/etc/haproxy/-MyDomain-com.pem
log global
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_fc_has_sni '%[ssl_fc_has_sni]' sni:'%[capture.req.hdr(0)]' ssl_fc_sni '%[ssl_fc_sni]' ssl_fc_protocol '%[ssl_fc_protocol]' ssl_bc '%[ssl_bc]' ssl_bc_alpn '%[ssl_bc_alpn]' ssl_bc_protocol '%[ssl_bc_protocol]' ssl_c_i_dn '%[ssl_c_i_dn()]' ssl_c_s_dn '%[ssl_c_s_dn()]' ssl_f_i_dn '%[ssl_f_i_dn()]' ssl_f_s_dn '%[ssl_f_s_dn]' ssl_fc_cipher '%[ssl_fc_cipher]' "
server -MyDomain-cloud 127.0.0.1:5223 check ssl check-ssl verify none check-sni str('-MyDomain-.im') sni str('-MyDomain-.im') ssl-min-ver TLSv1.2
backend galera-backend
balance leastconn
server db01 88.99.210.11:3306 check
server db02 88.99.210.46:3306 check
backend ldap-backend
balance leastconn
server db01 88.99.210.11:389 check
server db02 88.99.210.46:389 check
backend ldaps-backend
balance roundrobin
server db01 88.99.210.11:636 check
server db02 88.99.210.46:636 check
#---------------------------------------------------------------------
# stats page is hosted at different port
#---------------------------------------------------------------------
listen stats
bind *:10000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /stats
stats auth USER:PASS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment