HTTPS SNI on non-standard port not sending to correct backend

I’m new to HAProxy, and have a basic setup running on port 80 and port 443. The frontend on port 443 is looking at the host and sending the traffic to the correct backend based on that. This part is working as expected (and it’s awesome!)

Today I’m trying to setup a similar configuration on port 8172. I copied my frontend config block for 443, changed the port to 8172, and restarted HAProxy. It runs as normal.

However, when I send a request to a site in the new frontend block, HAProxy always sends the request on to the default_backend. It seems like I’ve missed something in configuring this to send it to the proper backend. I’ve tried setting the mode of the 8172 frontend to http, but the result is the same.

Here’s what my frontend definitions look like:

frontend https-www
bind *:443 ssl crt /etc/haproxy/certs/

    option forwardfor
    option http-server-close
    reqadd X-Forwarded-Proto:\ https
    rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
    rspadd X-Frame-Options:\ DENY
    acl host_log.domain.com       hdr(host)       -i log.domain.com
    use_backend backend_log.domain.com if host_log.domain.com
    acl host_demo.domain.com    hdr(host) -i demo.domain.com
    use_backend backend_demo.domain.com if host_demo.domain.com
    default_backend backend_demo.domain.com

frontend webdeploy
mode http
bind *:8172 ssl crt /etc/haproxy/certs/

    option forwardfor
    option http-server-close
    reqadd X-Forwarded-Proto:\ https
    rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
    rspadd X-Frame-Options:\ DENY
    acl host_log.domain.com       hdr(host)       -i log.domain.com
    use_backend backend_log.domain.com if host_log.domain.com
    acl host_demo.domain.com    hdr(host) -i demo.domain.com
    use_backend backend_demo.domain.com if host_demo.domain.com
    default_backend backend_demo.domain.com

Any ideas? I’ve tried removing the ‘mode http’ line from the 8172 frontend, but I experience the same result: all requests sent to 8172 get send on to the default backend.

According to your configuraiton, SNI is not involved in the backend selection, the HTTP Host header is.

And the Host header will have :8172 appended to it, since this is a non-standard port (see [1]).

So update your ACLs to include the port, like this:
acl host_log.domain.com hdr(host) -i log.domain.com:8172

and I think backend selection will start working again.

[1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23

1 Like

Perfect! That did the trick! Thanks!

That makes perfect sense, thank you for explaining and providing the link. After reading this, I tried sending a request to 8172 from my browser and looked at the headers in dev tools. Sure enough, the host is set to log.domain.com:8172.

I updated my config and everything is working as expected.

Thanks again!