HAProxy community

Multiple ssl/sni frontend configs without sharing config settings between sni names

I am currently having two different frontends, both I want to offer on ssl 443. However each front end has different acls, http-response set-headers. I think the default[1] to redirect to backends is somethink like this.

frontend env_ssl_frontend
bind *:443
mode tcp
option tcplog
tcp-request inspect-delay 10s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bk_app1 if { req.ssl_sni -m end app1.domain.com }
use_backend bk_app2 if { req.ssl_sni -m end app2.domain.com }
use_backend bk_app3 if { req.ssl_sni -m end app3.domain.com }

frontend http
bind *:443 ssl crt /etc/ssl/certs/mycert.pem
mode tcp
acl backend1 ssl_fc_sni backed1.domain.com
acl backend2 ssl_fc_sni backed2.domain.com
tcp-request inspect-delay 5s
use_backend backend1 if backend1
use_backend backend2 if backend2

But I think this would mean I cannot separate acl’s for different backends, or am I mistaken here? Or is there another way to configure this? I was thinking of doing maybe an port redirection, but that does not really look nice on the client side.

So basically I would like to have a frontend configuration that is similar to eg. webservers. Where you have a seperate config for a ‘domain’ identified by sni name and certificate.

Maybe this way not?

Or are there other options since then?

Different ACLs, response headers etc can all be combined with any other ACL, you do not need a different frontend for that.

There are some cases where you need to divide the two, but that is very rarely an issue.

Do you need to TLS passthrough some traffic while terminating TLS on some other traffic? That’s a typical use-case for this.

Yes, but whether you really need this is the real question. A lot of things can be configured without this, for example the example in question does not consider that with crt-list we can already configure ssl client certification per certificate, so this is not needed in this case anymore.

Yes, there are many options. To answer the specific question we need to know the actual use-case, otherwise.

For now I would like to keep configs separate, so it is clear when editing and when editing, I am not accidentally messing up a different frontend

frontend webchat
#bind *:80
bind 0.0.0.0:443 ssl crt aaa.aaa.aaa.pem
mode http
default_backend webchat

frontend exchange
mode http
#bind *:80
bind *:443 ssl crt bbb.bbb.bbb.pem
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-Content-Type-Options nosniff
acl autodiscover url_beg /Autodiscover
acl autodiscover url_beg /autodiscover
acl mapi url_beg /mapi
acl rpc url_beg /rpc
acl owa url_beg /owa
acl owa url_beg /OWA
acl eas url_beg /Microsoft-Server-ActiveSync
acl ecp url_beg /ecp
acl ews url_beg /EWS
acl ews url_beg /ews
acl oab url_beg /OAB
use_backend exchange_owa if owa
default_backend exchange

If its just about HTTP options like http level ACLs and headers only, then you can probably use mode http in the first frontend layer, and content-switch to your second frontend layer via host header. This way it works for both HTTP and HTTPS the same way.

If this is also about having a specific certificate reffered to in the same frontend, then you need to go the SNI route, with a frontend layer in mode tcp and SNI content-switching to a secondary frontend layer. Hopefully for HTTP you can just need to redirect to HTTPS, otherwise you need to replicate it there as well.

Yes I want such basic http://domain.com to https://domain.com on port 80.

I have came up with this from your previous example

frontend port443
  bind :443
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }
  use_backend recir_webchat if { req_ssl_sni -i aaa.aaa.aaa }
  use_backend recir_exchange if { req_ssl_sni -i bbb.bbb.bbb }
  default_backend recir_exchange

backend recir_webchat
  server loopback-for-tls abns@webchat send-proxy-v2
backend recir_exchange
  server loopback-for-tls abns@exchange send-proxy-v2

with a bind like

bind abns@webchat accept-proxy ssl crt aaa.aaa.aaa

So this would be the simplest and least inflicting config for using the same ip/port with different backends?

In the original post this line ended with ‘crt’, was that a typo, because without seems to work also. Or should I add this?

‘abns@webchat’ I think this just a free to use string? Why was this abns@?

With different frontends you mean, yes.

No, a certificate does not belong there, it’s wrong (because you are not terminating TLS there).

Yes, it’s a free string, abns is for abstract namespace under linux, which as opposed to unix domain sockets are just free strings without permissions or paths so it’s easier to handle.

However you could replace those sockets with a port on localhost. Like you could just replace abns@webchat with 127.0.0.1:500 and abns@exchange with 127.0.0.1:501, it would be the same thing (other than IP sockets are easier to handle on reloads, so when you are reloading a lot you should probably stick to those).