redis / redis-py

Redis Python client
MIT License
12.67k stars 2.53k forks source link

Support for Traefik routing with SNI #3340

Open dfroger opened 3 months ago

dfroger commented 3 months ago

Hi,

I'm trying to proxy with Traefik multiple Redis instances, that run in different Docker Swarm stacks.

Traefik provide HostSNI rule to route a TCP connection to the corresponding Docker container.

So my goal would be to establish with redis-py a Redis connection with SSL providing the Server Name Identification.

This seems to be possible with ssl.SSLContext.wrap_socket:

On client connections, the optional parameter server_hostname specifies the hostname of the service which we are connecting to. This allows a single server to host multiple SSL-based services with distinct certificates, quite similarly to HTTP virtual hosts. Specifying server_hostname will raise a ValueError if server_side is true.

Then redis-py documents examples on how to pass an SSLContext with the ssl_ocsp_context=ctx argument, so it seems feasible to achieve.

Does it sound good? May in the future a ssl_server_name argument be added to redis.Redis()to simplify the usage?

I should provide feedback of my experiment on this soon.

Thanks for reading!

dfroger commented 3 months ago

So redis-py actually use pyopenssl (not Python ssl stdlib module). Seems I need to call OpenSSL.SSL.Connection.set_tlsext_host_name(name).

Edit: it uses both.

dfroger commented 3 months ago

Just found that: https://github.com/redis/redis-py/pull/1087

dfroger commented 3 months ago

In redis/connection.py:SSLConnection._wrap_socket_with_ssl:

I would have expected the SNI passed in wrap_socket to be possibly different of the TCP host we connect to.