FrontEnd HTTPS And TCP over TLS


#1

Hello everybody,
i would like to do a frontend HTTPS and frontend TCP over TLS:
i don’t know where i do a mistake, could you help me?
I explain i have one frontend “fe_vip_443_tcp” for analyse TLS request HTTPS or TCP over TLS if HTTPS then i send to backend redirect_for_https (@abns) to redirect to frontend “fe_vip_https”(@abns) that allow to send to http backend.
Like that i will have frontend HTTPS and frontend TCP over TLS
(HA-Proxy version 1.8.3)
My errors in this order:
fe_vip_https/1: SSL handshake failure
fe_vip_443_tcp~ redirect_for_https/loopback-for-tls 191/0/191 0 SD 4/4/0/0/0 0/0

My config file without global and default section
##################################

frontend fe_vip_443_tcp
description Front-End 443
bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem alpn h2,http/1.1#crt-ignore-err all ca-ignore-err all
mode tcp
option tcplog
maxconn 1000
############SNI############
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }

tcp-request content accept if HTTP
###########################to HTTP###############################################
use_backend redirect_for_https if HTTP
###################################################
####################To TCP#########################

default_backend	bk_null

frontend fe_vip_https
mode http
bind abns@haproxy-tls-term accept-proxy ssl crt /etc/haproxy/certs/haproxy.pem alpn h2,http/1.1 option forwardfor
##########log HTTP ###########
log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tw/%Tc/%Tt\ %B\ %ts\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {%sslv/%sslc/%[ssl_fc_sni]/%[ssl_fc_session_id]}\ “Request\ %[capture.req.method]\ %[capture.req.hdr(0)]%[capture.req.uri]\ HTTP/1.1”\ #“Server\ %[capture.res.hdr(1)]”
#########################
#acl acl_mail ssl_fc_sni mail.labaog.mydom.com
acl acl_mail req.hdr(host) -i mail.labaog.mydom.com
use_backend bk_mail if acl_mail
default_backend bk_null

backend redirect_for_https
mode tcp
option http-server-close
server loopback-for-tls abns@haproxy-tls-term send-proxy-v2

backend bk_mail
description MailOwa
balance leastconn
mode http
log global
option httpchk GET /owa/healthcheck.htm
http-check expect status 200
server mail1 192.168.166.230:443 weight 1 maxconn 100 check ssl verify none sni ssl_fc_sni

backend letsencrypt-backend
server letsencrypt 127.0.0.1:54321

backend bk_null
description NULLSRV
timeout connect 1ms
server null 200.200.200.200


#2

Please share the entire configuration as preformatted text (mark the configuration and use the </> button), otherwise it’s unreadble.

You seem to do SNI routing in frontend fe_vip_https, however it belongs in frontend fe_vip_443_tcp. Also, you must not terminate SSL in frontend fe_vip_443_tcp, so remove everything after 443 in the bind line.


#3

thanks for your contribution,
here is the complete cfg:

    global
	description HAPROXY Statistics Page
	log 127.0.0.1:514 local0 info #emerg alert crit err warning notice info debug
	master-worker
	chroot /var/lib/haproxy
	pidfile /run/haproxy.pid
	stats socket /run/admin.sock mode 660 level admin
	stats timeout 30s
	user haproxy
	group haproxy
	daemon
	ssl-default-bind-options no-sslv3 no-tls-tickets
	tune.ssl.default-dh-param 2048
	tune.bufsize 16384
	tune.maxrewrite 1024
	spread-checks 4
	

#mailers mymailers
#	mailer mymailserver 127.0.0.1:25

defaults
	log global
	mode http
	option httplog
	option dontlognull
	option http-keep-alive
	timeout connect 10000ms
	timeout client 20s
	timeout http-request 20s
	timeout server 50000ms
	timeout check 50000ms
	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
	description HAPROXY
	bind *:8008
	stats enable
	stats hide-version
	stats realm Haproxy\ Statistics
	stats uri /stats
	stats refresh 2mn
	#stats auth admin:pass
	stats admin if TRUE
	stats show-desc
	stats show-legends
	
frontend fe_vip_http
	bind *:80
	mode http
	option forwardfor
	reqadd X-Forwarded-Proto:\ http
	acl acl_mail req.hdr(host) -i mail.labaog.mydom.com.ch
	redirect scheme https code 301 if acl_mail
		
	##############Lets Encrypt ##################################
	acl letsencrypt-acl path_beg /.well-known/acme-challenge/
	use_backend letsencrypt-backend if letsencrypt-acl
	##############END Lets Encrypt ##############################
		
	default_backend	bk_null
	
frontend fe_vip_443_tcp
	description Front-End 443
	#bind 192.168.0.91:443# ssl crt /etc/haproxy/cert_adfs_withprivkeyunprotected.pem crt /etc/haproxy/certs/haproxycert.pem #crt-ignore-err all ca-ignore-err all
	bind 192.168.0.91:443# ssl crt /etc/haproxy/certs/haproxy.pem alpn h2,http/1.1#crt-ignore-err all ca-ignore-err all
	mode tcp
	option tcplog
	maxconn 1000
	############SNI############
	tcp-request inspect-delay 5s
	tcp-request content accept if { req_ssl_hello_type 1 }
	tcp-request content accept if HTTP
	
	###########################to HTTP###############################################
	acl acl_mail ssl_fc_sni mail.labaog.mydom.com.ch
	#use_backend redirect_for_https if HTTP
	use_backend redirect_for_https if acl_mail
	###################################################
	####################To TCP#########################
	
		
	default_backend	bk_null

	
frontend fe_vip_https
	mode http
	bind abns@haproxy-tls-term accept-proxy ssl crt /etc/haproxy/certs/haproxy.pem alpn h2,http/1.1 crt-ignore-err all ca-ignore-err all
	option forwardfor
	##########log HTTP ###########
	log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tw/%Tc/%Tt\ %B\ %ts\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {%sslv/%sslc/%[ssl_fc_sni]/%[ssl_fc_session_id]}\ "Request\ %[capture.req.method]\ %[capture.req.hdr(0)]%[capture.req.uri]\ HTTP/1.1"\ #"Server\ %[capture.res.hdr(1)]"
	#########################
	#acl acl_mail ssl_fc_sni mail.labaog.mydom.com.ch
	acl acl_mail req.hdr(host) -i mail.labaog.mydom.com.ch
	use_backend bk_mail if acl_mail
	default_backend	bk_null
	
	
backend redirect_for_https
	mode tcp
	option http-server-close
	server loopback-for-tls abns@haproxy-tls-term send-proxy-v2 verify none sni ssl_fc_sni
	
	

backend bk_mail
	description MailOwa
	balance leastconn
	mode http
	log global
	option httpchk GET /owa/healthcheck.htm
	http-check expect status 200
	server mail1 192.168.166.230:443 weight 1 maxconn 100 check ssl verify none sni ssl_fc_sni
	

backend letsencrypt-backend
   server letsencrypt 127.0.0.1:54321

backend bk_null
	description NULLSRV
	timeout connect 1ms
	server null 200.200.200.200

#4

You have to use req_ssl_sni instead of ssl_fc_sni here. The former is for TCP payload with SSL data going transparently through haproxy (which is the case in frontend fe_vip_443_tcp), the latter is for a SSL session terminated by haproxy, which is the wrong tool for the job you are trying to do.


#5

I would like to do one frontend TCP over TLS and one FrontEnd HTTPS
like that:

I don’t know how to do otherwise.
maybe you have a solution
Thanks


#6

I understand what you are trying to do, and it is possible with SNI routing, if you have different hostnames in the SAN field of the certificates (they must not overlap with each other). But you have to configure haproxy properly, like explained above.


#7

I did it, thanks,
do you know how to differentiate trafic request between https and tcp ?


#8

You cannot do it based on the protocol, because it is encrypted. You can do it based on the SNI value of the client_hello.

You are doing it in your frontend:

acl acl_mail req_ssl_sni mail.labaog.mydom.com.ch
use_backend redirect_for_https if acl_mail
default_backend	bk_null

You are telling haproxy here:
if the SNI value is mail.labaog.mydom.com.ch, then route it to backend redirect_for_https, otherwise route to backend bk_null


#9

yes I know but if I could do something like that:
use_backend redirect_for_https if { tcp request have HTTP in the content request)
use_backend redirect_for_tcps if { tcp request have not HTTP in the content request)

thanks


#10

You cannot. This traffic is encrypted.