Score:1

HAProxy is not working with SNI and ACLs

gb flag

I am trying to get haproxy to use acls with SNI and it ain't cooperating. It presents the correct cert so SNI must be working. However, I cannot get it to select a backend based on the hostname in SNI.

Which I check the configuration, I get the following

[WARNING]  (21486) : Proxy 'fe-dr-totalflood.com': L6 sample fetches ignored on HTTP proxies (declared at ./haproxy.cfg.tmp:176).
[WARNING]  (21486) : Proxy 'fe-dr-totalflood.com': L6 sample fetches ignored on HTTP proxies (declared at ./haproxy.cfg.tmp:177).
Warnings were found.
Configuration file is valid

I have no idea what the error messages mean and I've put a note next to the corresponding lines in the following snippet.

frontend  fe-dr-totalflood.com
  mode      http
  bind      172.22.8.229:80
  bind      172.22.8.229:443 ssl crt dr-www.totalflood.com.crt crt dr-xml.totalflood.com.crt

  ## http->https redirect
  http-request redirect scheme https unless { ssl_fc }

  ## access control lists
  acl https ssl_fc
  acl letsencrypt-acl path_beg /.well-known/acme-challenge/
  acl www-acl req_ssl_sni dr-www.totalflood.com
  acl xml-acl req_ssl_sni dr-xml.totalflood.com

  # if Let's Encrypt, skip remainder and jump to the backend
  use_backend be-letsencrypt if letsencrypt-acl

  use_backend be-dr-www.totalflood.com if www-acl <------ 176
  use_backend be-dr-xml.totalflood.com if xml-acl <------ 177

  default_backend be-no-such-site

#---------------------------------------------
backend   be-dr-www.totalflood.com
  mode      http
  balance   roundrobin
  cookie    SERVERID insert indirect nocache maxidle 30m

  ## set the host name in the header
  acl h_host_exists req.hdr(Host) -m found
  http-request del-header Host if h_host_exists
  http-request set-header Host www.totalflood.com

  default-server check maxconn 100

  server  scadmzp2wb01 scadmzp2wb01.lereta.net:80 cookie scadmzp2wb01

#---------------------------------------------
backend   be-dr-xml.totalflood.com
  mode      http
  balance   roundrobin
  cookie    SERVERID insert indirect nocache maxidle 30m

  ## set the host name in the header
  acl h_host_exists req.hdr(Host) -m found
  http-request del-header Host if h_host_exists
  http-request set-header Host xml.totalflood.com

  default-server check maxconn 100

  server  scadmzxml01 scadmzxml01.lereta.net:80 cookie scadmzxml01

#---------------------------------------------
backend be-letsencrypt
  server localhost 127.0.0.1:8888

#---------------------------------------------
backend be-no-such-site
  server localhost 127.0.0.1:8888

When I try to access either site I always hit the default backend no matter what. I've tested this by changing the default backend to go other places. If I append to either url the /.well-known/acme-challenge path, haproxy seems to send me to the correct place.

What I cannot figure out is why the acls based on SNI information don't work.

I am using version 2.4.2 of haproxy OracleLinux 8.

$ haproxy -v
HAProxy version 2.4.2-553dee3 2021/07/07 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.2.html
Running on: Linux 5.4.17-2136.304.4.1.el8uek.x86_64 #2 SMP Tue Feb 8 11:54:24 PST 2022 x86_64
Score:1
gu flag

Quoting from the docs:

Fetching samples from buffer contents is a bit different from the previous sample fetches above because the sampled data are ephemeral. These data can only be used when they're available and will be lost when they're forwarded. For this reason, samples fetched from buffer contents during a request cannot be used in a response for example. Even while the data are being fetched, they can change.

That's why you get a warning about ignoring Layer 6 ACLs.

Instead of using req_ssl_sni, you had better use ssl_fc_sni at Layer 5, which will get you the same information but more reliably.

cn flag
Indeed, good solution !
scarville avatar
gb flag
That worked. Thank you.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.