1

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
scarville
  • 51
  • 6

1 Answers1

2

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.

Ginnungagap
  • 2,595
  • 10
  • 13