Hi, I have a setup I’ve been struggling with for a while.
I want to use tcp mode to pass-through SSL.
I want it so when I enter abc.com I get passed through to the abc.com backend, but if any other domain than abc.com is used to access haproxy with it will be sent to the fallback backend.
Is that possible?
Here is what I’ve tried so far:
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
maxconn 10240
nbproc 4
nbthread 1
cpu-map auto:1/1-4 0-3
defaults
log global
mode tcp
option tcplog
option dontlognull
maxconn 2048
retries 3
timeout connect 10s
timeout client 30s
timeout server 30s
timeout http-request 10s
timeout http-keep-alive 2s
timeout queue 5s
timeout tunnel 2m
timeout client-fin 2s
timeout server-fin 2s
frontend abc.com
bind XXX.YYY.ZZZ.WWW:80
bind XXX.YYY.ZZZ.WWW:443
use_backend abc.com if { hdr(host) -i www.abc.com }
use_backend abc.com if { hdr_dom(host) -i abc.com }
default_backend fallback
backend abc.com
balance static-rr
server default AAA.BBB.CCC.DDD:443 check verify none fall 3 rise 2
backend fallback
balance static-rr
server fallback reverse-proxy.fallback.com:443
Any suggestions?
Those ACL would access HTTP headers. This is possible when a) the content is not encrypted or it is decrypted by haproxy and b) when the frontend is in http mode (this implies decryption).
In this case though the entire HTTP transaction is encrypted and you cannot access it.
What you can do is parse the SNI value in the SSL client_hello.
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend abc.com if { req.ssl_sni -i abc.com }
Two important notes:
- you need to wait for the complete SSL client_hello to be in the buffers (first to lines)
- this will not work for overlapping certificates (one certificate that covers both acl’ed as well as fallback domains, because the SNI decision will be made once per SSL session (during handshake based on the client_hello packet) and the browser will reuse an existing SSL session for different domains, when the certificate allows that
2 Likes
Those 3 lines work wonders for the actual abc.com backend, thanks!
But is there any way to have it fallback to another backend if none of those rules fire? Like, if I change it to:
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend abc.com if { req.ssl_sni -i abc2.com }
use_backend abc.com if { req.ssl_sni -i www.abc2.com }
I have then added “default_backend fallback” after those 4 lines but it doesn’t seem to register?
I have a web server running on the same machine as haproxy which listens on 127.0.0.1:8080 and it works fine using “curl 127.0.0.1:8080” so it is running - but the backend is never used?
My fallback backend simply looks like this:
backend fallback
balance static-rr
server fallback 127.0.0.1:8080
8080 is probably not an HTTPS/SSL port. You can’t connect incoming HTTPS on port 443 to a plain HTTP server.
works fine using “curl 127.0.0.1:8080”
Exactly, using HTTP. Not HTTPS.
(You also need to remove binding to port 80 on your frontend, this will do the wrong thing)
When this is fixed, post the output of
curl -v https://XXX.YYY.ZZZ.WWW:443/
from the haproxy box, to see what happens.
1 Like