# ACL filters when using mode tcp?

**URL:** <https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863>\
**Category:** Help!\
**Created:** [August 27, 2021, 4:00pm UTC](https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863 "2021-08-27T16:00:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amplificator](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/amplificator/32/1538_2.png) [@Amplificator](https://discourse.haproxy.org/u/Amplificator)\
**Post date:** [August 27, 2021, 4:00pm UTC](https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863/1 "2021-08-27T16:00:30Z")

</div>

Hi, I have a setup I’ve been struggling with for a while.

I want to use tcp mode to pass-through SSL.  
I want it so when I enter [abc.com](http://abc.com) I get passed through to the [abc.com](http://abc.com) backend, but if any other domain than [abc.com](http://abc.com) is used to access haproxy with it will be sent to the fallback backend.

Is that possible?

Here is what I’ve tried so far:

```auto
global
        log /dev/log local0
        log /dev/log local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        maxconn 10240
        nbproc 4
        nbthread 1
        cpu-map auto:1/1-4 0-3

defaults
        log global
        mode tcp
        option tcplog
        option dontlognull
        maxconn 2048
        retries 3
        timeout connect 10s
        timeout client 30s
        timeout server 30s
        timeout http-request 10s
        timeout http-keep-alive 2s
        timeout queue 5s
        timeout tunnel 2m
        timeout client-fin 2s
        timeout server-fin 2s

frontend abc.com
         bind XXX.YYY.ZZZ.WWW:80
         bind XXX.YYY.ZZZ.WWW:443
         use_backend abc.com if { hdr(host) -i www.abc.com }
         use_backend abc.com if { hdr_dom(host) -i abc.com }
         default_backend fallback

backend abc.com
         balance static-rr
         server default AAA.BBB.CCC.DDD:443 check verify none fall 3 rise 2

backend fallback
         balance static-rr
         server fallback reverse-proxy.fallback.com:443

```

Any suggestions?

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 27, 2021, 7:02pm UTC](https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863/2 "2021-08-27T19:02:09Z")

</div>

Those ACL would access HTTP headers. This is possible when a) the content is not encrypted or it is decrypted by haproxy and b) when the frontend is in http mode (this implies decryption).

In this case though the entire HTTP transaction is encrypted and you cannot access it.

What you can do is parse the SNI value in the SSL client\_hello.

```
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend abc.com if { req.ssl_sni -i abc.com }

```

Two important notes:

- you need to wait for the complete SSL client\_hello to be in the buffers (first to lines)
- this will not work for overlapping certificates (one certificate that covers both acl’ed as well as fallback domains, because the SNI decision will be made once per SSL session (during handshake based on the client\_hello packet) and the browser will reuse an existing SSL session for different domains, when the certificate allows that

---

<div class="post-metadata">

**Author:** ![Amplificator](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/amplificator/32/1538_2.png) [@Amplificator](https://discourse.haproxy.org/u/Amplificator)\
**Post date:** [August 27, 2021, 7:21pm UTC](https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863/3 "2021-08-27T19:21:14Z")

</div>

Those 3 lines work wonders for the actual [abc.com](http://abc.com) backend, thanks!

But is there any way to have it fallback to another backend if none of those rules fire? Like, if I change it to:

```auto
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend abc.com if { req.ssl_sni -i abc2.com }
use_backend abc.com if { req.ssl_sni -i www.abc2.com }

```

I have then added “default\_backend fallback” after those 4 lines but it doesn’t seem to register?  
I have a web server running on the same machine as haproxy which listens on 127.0.0.1:8080 and it works fine using “curl 127.0.0.1:8080” so it is running - but the backend is never used?

My fallback backend simply looks like this:

```auto
backend fallback
         balance static-rr
         server fallback 127.0.0.1:8080

```

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 27, 2021, 9:00pm UTC](https://discourse.haproxy.org/t/acl-filters-when-using-mode-tcp/6863/4 "2021-08-27T21:00:13Z")

</div>

8080 is probably not an HTTPS/SSL port. You can’t connect incoming HTTPS on port 443 to a plain HTTP server.

> works fine using “curl 127.0.0.1:8080”

Exactly, using HTTP. Not HTTPS.  
(You also need to remove binding to port 80 on your frontend, this will do the wrong thing)

When this is fixed, post the output of

```
curl -v https://XXX.YYY.ZZZ.WWW:443/

```

from the haproxy box, to see what happens.
