Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SentinelManagedConnection needs a SSLSentinelManagedConnection to complement SSLConnection #1306

Closed
nickwilliams-eventbrite opened this issue Mar 12, 2020 · 3 comments
Labels

Comments

@nickwilliams-eventbrite

Version: 3.4.1

Platform: 2.7.17, 3.5.9, and 3.7.6

Description: With Redis 6, Redis provides TLS support directly. This means that replicas and Sentinels can communicate with Redis over TLS. When Sentinel communicates with Redis over TLS, it gives its clients the TLS address for the Redis master and replicas when the master and replica address are requested. However, the Sentinel client in this library contains only SentinelManagedConnection, and SentinelManagedConnection does not understand TLS. It extends Connection directly.

So, if I configure my Sentinel like this:

self._sentinel = redis.sentinel.Sentinel(
    hosts,
    sentinel_kwargs={'socket_connect_timeout': 5.0, 'socket_timeout': 5.0},
    **{
        'ssl_ca_certs': '/srv/run/tls/ca.crt',
        'ssl_certfile': '/srv/run/tls/redis.crt',
        'ssl_keyfile': '/srv/run/tls/redis.key',
    },
)

I get a TypeError that SentinelManagedConnection does not have keyword arguments ssl_ca_certs, etc. But if I configure it like this, without SSL info:

self._sentinel = redis.sentinel.Sentinel(
    hosts,
    sentinel_kwargs={'socket_connect_timeout': 5.0, 'socket_timeout': 5.0},
    **{},
)

I get SSL handshake errors on the Redis server and unexpected-disconnect errors on the client (because the server is expecting a TLS handshake and the client is not).

I was able to solve this problem very simply. I created this class:

class SSLSentinelManagedConnection(redis.sentinel.SentinelManagedConnection, redis.SSLConnection):
    def __init__(self, **kwargs):
        self.connection_pool = kwargs.pop('connection_pool')  # replicate the init code from SentinelManagedConnection
        redis.SSLConnection.__init__(self, **kwargs)  # we cannot use super() here because it is not first in the MRO

And then I configured my Sentinel like this:

self._sentinel = redis.sentinel.Sentinel(
    hosts,
    sentinel_kwargs={'socket_connect_timeout': 5.0, 'socket_timeout': 5.0},
    **{
        'connection_class': SSLSentinelManagedConnection,
        'ssl_ca_certs': '/srv/run/tls/ca.crt',
        'ssl_certfile': '/srv/run/tls/redis.crt',
        'ssl_keyfile': '/srv/run/tls/redis.key',
    },
)

Now it works perfectly.

The Sentinel class should work similarly to the Redis class—it should do connection_kwargs.pop('ssl', False) and, if that value is true, it should change the connection class from SentinelManagedConnection to SSLSentinelManagedConnection.

I could happily and quickly put together a pull request implementing this, but I didn't know how you felt about multiple inheritance and thought you might want to take a different approach, so I'll wait a few days for word from you about how you feel about my approach before I put that together.

nickwilliams-eventbrite added a commit to eventbrite/pysoa that referenced this issue Mar 13, 2020
- Update functional tests to use Redis 5 and 6 instead of Redis 4 and 5.
- Update Redis 6 Sentinel tests to use ACLs (authentication) and TLSv1.2 (TLSv1.3 cannot be supported on Ubuntu 16.04).
- Add a few more functional tests.
- This proves that:
  - PySOA can use Redis 6 without ACL and TLS
  - PySOA can use Redis 6 with ACL
  - PySOA can use Redis 6 with TLS with unprotected Sentinel
  - PySOA can use Redis 6 with TLS with Sentinel with TLS
- Created redis/redis-py#1306.
- Created redis/redis#6986.
- Created antirez/redis#6985.
@nishantgeorge
Copy link

I can confirm this issue exists. I believe @nickwilliams-eventbrite's solution is the correct approach.

@andymccurdy
Copy link
Contributor

@nickwilliams-eventbrite Hey Nick, sorry it's taken so long for me to get to this. If you're still open to making a PR I'm fine with multiple inheritance.

@github-actions
Copy link
Contributor

This issue is marked stale. It will be closed in 30 days if it is not updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants