Question

I am trying to put an HTTPS web server behind HAProxy load balancer. HTTPS server runs on Node.js on port 8000, had all the correct SSL certs and keys and works if I try access it directly via URL, e.g. https://ssltest.mydomain.com:8000/. I can also check SSL connection using openssl s_client -connect ssltest.mydomain.com:8000 and it shows data that seems correct.

The front end for this HTTPS server is another subdomain, e.g. app.mydomain.com and it runs on default SSL port 443.

But when I try to access https://app.mydomain.com from my browser, I get an SSL error. The above command line check also fails: openssl s_client -connect app.mydomain.com:443 -state -debug

Below is how my HA Proxy config looks like:

global
    log /dev/log local0 info
    log /dev/log local0 notice
    maxconn 20000
    user haproxy
    group haproxy
    daemon
    spread-checks 5

defaults
    log     global
    mode    tcp
    option  dontlognull
    retries 3
    option  redispatch
    timeout connect 30s
    timeout client  30s
    timeout server  30s
    timeout check 5s
    balance roundrobin

frontend https_proxy
    bind :443
    acl is_app  hdr_dom(host) -i app.mydomain.com
    acl is_rest hdr_dom(host) -i rest.mydomain.com
    acl is_io   hdr_dom(host) -i io.mydomain.com
    use_backend core_https    if is_app
    use_backend core_rest_api if is_rest
    use_backend core_www_io   if is_io

backend core_https
    server www1 10.0.0.174:8000 maxconn 25 check inter 5s rise 18 fall 2

backend core_www_io
    server io1 10.0.0.174:8100 maxconn 25 check inter 5s rise 18 fall 2

backend core_rest_api
    server api1 10.0.0.174:8200 maxconn 25 check inter 5s rise 18 fall 2

I can't figure out why this does not work via HAProxy but works directly, and I would REALLY appreciate your suggestions.

Was it helpful?

Solution

You're confusing layer 4 and layer 7 load balancing. To separate requests using hdr_dom you need layer 7 that's only available for HTTP and as you may guess HTTPS works on layer 4.

So as haproxy can't inspect the host, none of your ifs are returning true and there is no backend selected, to fix you should add a default_backend entry.

frontend https_proxy
    bind :443
    acl is_app  hdr_dom(host) -i app.mydomain.com
    acl is_rest hdr_dom(host) -i rest.mydomain.com
    acl is_io   hdr_dom(host) -i io.mydomain.com
    use_backend core_https    if is_app
    use_backend core_rest_api if is_rest
    use_backend core_www_io   if is_io
    default_backend core_https
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top