# TCP proxy with SNI support

**URL:** <https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502>\
**Category:** Help!\
**Created:** [July 18, 2020, 8:39pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502 "2020-07-18T20:39:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bitquest25c](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@bitquest25c](https://discourse.haproxy.org/u/bitquest25c)\
**Post date:** [July 18, 2020, 8:39pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/1 "2020-07-18T20:39:18Z")

</div>

Hello,

I have a single server with one Public IP and 10 domains. For each domain I’d like to have a separate docker container as an email server (Postfix + Dovecot). I’d like to achieve this with transparent TCP proxy with SNI support.

I’d like to route traffic from [example.com](http://example.com) on ports 587 & 143 to one container and traffic for [acme.com](http://acme.com) on ports 587 & 143 to a different container, etc.

Can I achieve this by using host:port? Does anyone know of an example?

I found some information on [http://www.haproxy.org/download/1.6/doc/configuration.txt](http://www.haproxy.org/download/1.6/doc/configuration.txt) about this, but not enough to achieve my desired setup.

Thank you.

---

<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:** [July 18, 2020, 8:47pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/2 "2020-07-18T20:47:14Z")

</div>

This will not work, in short: SNI can only be used in protocols that _implicitly_ use SSL (like HTTPS), not in protocols with explicit SSL via STARTTLS:

Please see the following thread for more details:

> [@SMTP & IMAP proxy based on domain (pass-through)](https://discourse.haproxy.org/t/smtp-imap-proxy-based-on-domain-pass-through/5480):
>
> Hello, My scenario is as follows: I have a single server with multiple domains. For each domain I’d like to have a separate docker container (won’t go into reasons why I want this, but it does make sense) as an email server (postfix + dovecot). I’ve researched this extensively for months and believe this should be possible using haproxy. I’d like to achieve this without ssl termination - basically using pass-though or in other words, read the TLS SNI header (domain) and decide based on that w…

---

<div class="post-metadata">

**Author:** ![bitquest25c](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@bitquest25c](https://discourse.haproxy.org/u/bitquest25c)\
**Post date:** [July 18, 2020, 8:51pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/3 "2020-07-18T20:51:03Z")

</div>

@lukastribus

Thank you for your reply. If so, why does wiki state this …?

The “use-server” statement works both in HTTP and TCP mode. This makes it  
suitable for use with content-based inspection. For instance, a server could  
be selected in a farm according to the TLS SNI field. And if these servers  
have their weight set to zero, they will not be used for other traffic.

Example :  
# intercept incoming TLS requests based on the SNI field  
use-server www if { req\_ssl\_sni -i [www.example.com](http://www.example.com) }  
server www 192.168.0.1:443 weight 0  
use-server mail if { req\_ssl\_sni -i [mail.example.com](http://mail.example.com) }  
server mail 192.168.0.1:587 weight 0  
use-server imap if { req\_ssl\_sni -i [imap.example.com](http://imap.example.com) }  
server imap 192.168.0.1:993 weight 0  
# all the rest is forwarded to this server  
server default 192.168.0.2:443 check

---

<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:** [July 18, 2020, 9:30pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/4 "2020-07-18T21:30:40Z")

</div>

You’re right, that’s a documentation error. 993 is implicit TLS, which will work (_if_ client send SNI), 587 is explicit TLS which will not work.

But it doesn’t make sense to show an example SNI routing traffic for mailservers, given that a full setup (with all protocols a mail-server needs) is not possible and something is always missing. So this needs to be fixed in the documentation.

---

<div class="post-metadata">

**Author:** ![bitquest25c](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@bitquest25c](https://discourse.haproxy.org/u/bitquest25c)\
**Post date:** [July 21, 2020, 8:22pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/5 "2020-07-21T20:22:52Z")

</div>

I’ve tried the following config within HAProxy and traffic still doesn’t get through to docker containers?

```auto
defaults
    timeout client 30s
    timeout server 30s
    timeout connect 5s

    option tcplog
    log global

frontend smtp_submission

    mode tcp
    bind *:465

    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

    use_backend smtp_submission

frontend imap

    mode tcp
    bind *:993

    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

    use_backend imap

backend smtp_submission

    mode tcp

    acl mail_domain1_match req_ssl_sni -i smtp.domain1.com
    acl mail_domain2_match req_ssl_sni -i smtp.domain2.com

    use-server mail_domain1_smtp_submission if mail_domain1_match
    use-server mail_domain2_smtp_submission if mail_domain2_match

    option ssl-hello-chk

    server mail_domain1_smtp_submission 172.17.0.12:465 weight 0
    server mail_domain2_smtp_submission 172.17.0.11:465 weight 0

backend imap

    mode tcp

    acl mail_domain1_match req_ssl_sni -i imap.domain1.com
    acl mail_domain2_match req_ssl_sni -i imap.domain2.com

    use-server mail_domain1_imap if mail_domain1_match
    use-server mail_domain2_imap if mail_domain2_match

    option ssl-hello-chk

    server mail_domain1_imap 172.17.0.12:993 weight 0
    server mail_domain2_imap 172.17.0.11:993 weight 0

```

---

<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:** [July 25, 2020, 4:16pm UTC](https://discourse.haproxy.org/t/tcp-proxy-with-sni-support/5502/6 "2020-07-25T16:16:50Z")

</div>

Check if your requests actually contain SNI (don’t just assume that) by capturing ssl client\_hello and opening it in wireshark. Also check haproxy logging for those requests.
