[Docker Swarm] redis tls passthrough issue

Hi,

Could you help to find out why passthrough does not work with redis service.

I have the following configuration:
traefik static config:

entryPoints:
  redisacl:
    address: ":16100"

docker-compose (exposed port 16379 and labeled traefik entrypoint 16100 at the same time for the debugging purpose):

  testredis:
    image: redis:7.0.4
    ports:
      - 16379:6379
    hostname: testredis
    deploy:
      labels:
         # Add labels for Traefik loadbalancer
         - traefik.enable=true
         - traefik.tcp.routers.testredis.rule=HostSNI(`redisssl.test.lan`)
         - traefik.tcp.routers.testredis.service=testredis
         - traefik.tcp.routers.testredis.entrypoints=redisacl
         - traefik.tcp.services.testredis.loadbalancer.server.port=6379
         - traefik.tcp.routers.testredis.tls=true
         - traefik.tcp.routers.testredis.tls.passthrough=true

I've tried

traefik.tcp.routers.testredis.rule=HostSNI(`*`) 

as well.

I can see the TCP Service and Routers in the Traefik dashboard.
Ports are open:

nc -zv redisssl.test.lan 16379
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Connected to xxx.xxx.xxx.35:16100.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

nc -zv redisssl.test.lan 16100
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Connected to xxx.xxx.xxx.35:16379.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

But connection to the redis via port 16100 has failed.

redis-cli --sni redisssl.test.lan -h redisssl.test.lan -p 16379 --tls --cacert /usr/local/etc/redis/tls/ca.crt --cert /usr/local/etc/redis/tls/redis.crt --key /usr/local/etc/redis/tls/redis.key
OK

redis-cli --sni redisssl.test.lan -h redisssl.test.lan -p 16100 --tls --cacert /usr/local/etc/redis/tls/ca.crt --cert /usr/local/etc/redis/tls/redis.crt --key /usr/local/etc/redis/tls/redis.key
Could not connect to Redis at redisssl.test.lan:16100: SSL_connect failed: Success

From the remote windows client the following error has appeared: Error: Protocol error, got "H" as reply type byte

traefik version

Version: 2.8.3
Codename: vacherin
Go version: go1.19
Built: 2022-08-12T14:24:34Z
OS/Arch: linux/amd64

I don't think you should set the service for the router. Try removing this line:

- traefik.tcp.routers.testredis.service=testredis

@bluepuma77 Unfortunately it does not helped.
Curios when I set wrong value to --sni it immediately says:

Could not connect to Redis at redisssl.test.lan:16100: SSL_connect failed: certificate verify failed

Additional info.
I've checked with openssl:

exposed port 16379

openssl s_client -connect redisssl.test.lan:16379

CONNECTED(00000003)
depth=1 O = Redis Test, CN = Certificate Authority
verify error:num=19:self signed certificate in certificate chain
verify return:1
depth=1 O = Redis Test, CN = Certificate Authority
verify return:1
depth=0 O = Redis Test, CN = Generic-cert
verify return:1
---

traefik entry point 16100

openssl s_client -connect redisssl.test.lan:16100
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 324 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

Something wrong with traefik.tcp.routers.{service}.tls.passthrough ;(
BTW, traefik.http.routers.{service}.tls.passthrough works well for portainer.

Hi @gray380 ,
I had the same issue with HAProxy backend service.
And i think based on your description it was the same.
The problem is not with traefik, but with redis in your case.
The backend needs to accept accept a Proxy Protocol header
for HAProxy like this;

bind :80 accept-proxy
bind :443 ssl crt accept-proxy 
# ref: https://www.haproxy.com/documentation/hapee/latest/load-balancing/client-ip-preservation/enable-proxy-protocol/

for redis you may need to put nginx or haproxy in front of the redis service;
https://docs.redis.com/latest/ri/using-redisinsight/proxy/

Traefik can enable ProxyProtocol for TCP connections to the target service. (Doc)