SSL passthrough issue

Hi all,

I’m having an issue in moving a company’s application from SSL termination to SSL passthrough on HAproxy. The application is composed by 2 servers; the frontend which as a webpage that display a gadget coming from the backend, and the backend that has the final gadget webpage. When I have HAproxy in SSL termination I am able to access both backend and frontend servers without issues, and these are how the access are logged:

Backend directly:

May 14 12:40:19 CLB11-LAB2-1 haproxy[16068]: 192.168.151.32:51643 [14/May/2020:12:40:19.473] global_https_front~ https_back_ece/ECE1-LAB2-1 0/0/2/9/11 200 1956 - - --NN 1/1/0/0/0 0/0 “GET /system/templates/finesse/gadget/agent/ece.xml HTTP/1.1”

Frontend via gadget:

May 14 12:42:24 CLB11-LAB2-1 haproxy[16068]: 192.168.151.32:51799 [14/May/2020:12:42:24.807] global_https_front~ https_back_ece/ECE1-LAB2-1 0/0/1/5/6 200 50942 - - --VN 1/1/0/0/0 0/0 “GET /system/web/apps/shared/fonts/egainicons.woff HTTP/1.1”

*note: in the frontend log I can see that the connection is coming from my computer (192.168.151.32)

When I switch the configuration to SSL passthrough, the backend direct access works fine but then the access via front-end stops working, showing the following logs:

Backend directly:

May 14 12:47:10 CLB11-LAB2-1 haproxy[16093]: 192.168.151.32:51955 [14/May/2020:12:45:11.346] https_in https_back_ece/ECE1-LAB2-1 1/0/118823 19700 – 1/1/0/0/0 0/0
May 14 12:47:16 CLB11-LAB2-1 haproxy[16093]: 192.168.151.32:52046 [14/May/2020:12:47:16.496] https_in https_back_ece/ECE1-LAB2-1 3/1/107 2037 SD 1/1/0/0/0 0/0

Frontend via gadget:

May 14 12:46:37 CLB11-LAB2-1 haproxy[16093]: 172.20.104.30:52894 [14/May/2020:12:46:37.832] https_in https_in/ -1/-1/0 0 SC 2/2/0/0/0 0/0

*note: in the frontend log the connection is coming from the frontend server and not my computer

Here my HAproxy config:

global
log /dev/log local0 debug
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 2000

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

defaults
log global
mode http
option httplog
option dontlognull
#option forwardfor
option redispatch
option http-server-close
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 3600s
timeout http-keep-alive 1s
timeout http-request 15s
timeout queue 30s
timeout tarpit 60s
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 http_in
mode http
option httplog
bind *:80
option forwardfor
redirect scheme https if !{ ssl_fc }

frontend https_in
mode tcp
option tcplog
bind *:443
acl tls req.ssl_hello_type 1
tcp-request inspect-delay 5s
tcp-request content accept if tls
stats uri /haproxy?stats

   acl host_ece req.ssl_sni -i ece.lab2.domain.com
   use_backend https_back_ece if host_ece

backend https_back_ece
mode tcp
option tcplog
option ssl-hello-chk
option httpchk HEAD /default
http-check expect ! rstatus ^5
cookie JSESSIONID prefix nocache
default-server inter 3000 fall 2
server ECE1-LAB2-1 172.20.206.45:443 check check-ssl verify none cookie s1
server ECE2-LAB2-1 172.21.206.45:443 check check-ssl backup verify none cookie s2

It is due to the fact that the connection is passing through HAproxy and cannot process the HTTP GET request? Any idea of what could cause this issue?

Thank you!

Just replace this with default_backend https_back_ece, otherwise you REQUIRE SNI support with a correct value which may not be the case for your frontend gadget.

I have took out from the config the other ACL rules and backend serving other URLs for simplicity, so I cannot run a default backend rule for that reason. In regards for SSL SNI it may be useful to switch to hdr(host)?

Thank you

No, you cannot access HTTP headers when you are passing through encrypted content, that is the point of encryption in the first place.

SSL passthrough means that you are connecting a TCP socket with another TCP socket. It has A LOT of limitations. If you are trying to make routing decisions based on SNI, you need to actually have SSL handshake request with SNI, otherwise it will not work.

So first of all, check and confirm that you actually can rely on SNI. Capture traffic and check the SSL hello packet.

I have done a test directly from my web browser and from the frontend server and unfortunately I cannot see the “Extension: server_name” field in the query from the frontend server. So I guess at this point there is nothing that I can do beside try to see if there is a way to upgrade the frontend server to support SNI?

Thank you!
T

Correct, if there is no server_name in the SSL hello, then haproxy cannot make routing decisions based on that.