Closed ajgon closed 1 year ago
This isn’t really a channels-redis issue. Maybe redis-py either have a solution or would take it as an issue. (We just pass through the params)
I've dig it some more, and it turned out - it is a bug, here: https://github.com/django/channels_redis/blob/a993f3fc1ba9e52296fdd18199f6316af39e165b/channels_redis/core.py#L138-L142
The problem is, that host
is passed to SentinelConnectionPool
, not to the aioredis.sentinel.Sentinel
itself. So the whole **connection_kwargs
which are passed later to the redis are skipped. The fix will be either passing **host to sentinel as well, i.e.
return aioredis.sentinel.SentinelConnectionPool(
master_name,
aioredis.sentinel.Sentinel(sentinels, sentinel_kwargs=sentinel_kwargs, **host),
**host
)
or somehow differentiate and them separately, something like:
return aioredis.sentinel.SentinelConnectionPool(
master_name,
aioredis.sentinel.Sentinel(sentinels, sentinel_kwargs=sentinel_kwargs, **host['redis_connection_kwargs']),
**host
)
As I mentioned, I'm not a python dev, so I'm not sure what is the correct way, so I'll leave it up to you :)
OK, let's reopen to look. If you want to make a PR with a regression test quickly we can get it in the for release. Thanks
Looks like, something is also broken on redis-py
side. Here are the results of my tests:
Having connection built like these:
return aioredis.sentinel.SentinelConnectionPool(
master_name,
aioredis.sentinel.Sentinel(sentinels, sentinel_kwargs=sentinel_kwargs, **connection_kwargs),
**host_kwargs
)
I'm getting following results basing on given arguments (I'm skipping sentinel_kwargs
and master_name
, as sentinel iteself works correctly)
Without host kwargs, and connection kwargs configured - ssl to redis master doesn't work.
connection_kwargs = {'password': 'mypass', 'ssl': True, 'ssl_cert_reqs': 'none'}
host_kwargs = {}
# redis.exceptions.ConnectionError: Error while reading from master-node-resolved-from-sentinel:6379 : (104, 'Connection reset by peer')
# 104 - means no SSL connection at all
With ssl configured in host kwargs - password is not used (checked redis-side, no AUTH
is sent at all:
connection_kwargs = {'password': 'mypass', 'ssl': True, 'ssl_cert_reqs': 'none'}
host_kwargs = {'ssl': True, 'ssl_cert_reqs': 'none'}
# redis.exceptions.AuthenticationError: Authentication required.
When I try add password to host kwargs, it gets more bizzare, as now despite sentinels were asked for masters, redis py connects to localhost 🤔
connection_kwargs = {'password': 'mypass', 'ssl': True, 'ssl_cert_reqs': 'none'}
host_kwargs = {'ssl': True, 'ssl_cert_reqs': 'none', 'password': 'mypass'}
# OSError: Multiple exceptions: [Errno 111] Connect call failed ('::1', 6379, 0, 0), [Errno 111] Connect call failed ('127.0.0.1', 6379)
And last but not least - I can skip connection_kwargs
completely, and all three behaviors repeat:
connection_kwargs = {}
host_kwargs = {}
# redis.exceptions.ConnectionError: Error while reading from master-node-resolved-from-sentinel:6379 : (104, 'Connection reset by peer')
# 104 - means no SSL connection at all
host_kwargs = {'ssl': True, 'ssl_cert_reqs': 'none'}
# redis.exceptions.AuthenticationError: Authentication required.
host_kwargs = {'ssl': True, 'ssl_cert_reqs': 'none', 'password': 'mypass'}
# OSError: Multiple exceptions: [Errno 111] Connect call failed ('::1', 6379, 0, 0), [Errno 111] Connect call failed ('127.0.0.1', 6379)
I officially throw in the towel. It seems channels_redis
is either doing everything correctly - however, I'm not sure if it should be done this way on redis-py side... Anyway, there is no point for PR at the moment, I'll copy paste most of this comment to redis-py
and ask support there...
Edit: redis-py ticket
I've had a similar issue (with straightforward hosts, not sentinels) and I needed to pass extra connection parameters. I've opened a PR to allow for it #337
I'm not sure if it's a bug or me being stupid (as I'm not a python developer), so sorry in advance :)
I'm trying to setup channels-redis (4.0.0b2, the one from main branch) with redis sentinel via SSL (self-signed) - SSL is both on sentinels and underlying redises. I have successfully managed to set up sentinels connection, and fetch master node - however I'm unable to join underlying redis. I'm getting CERTIFICATE_VERIFY_FAILED no matter what I try. This is what I'm trying to do:
and here is the exception:
I also tried to pass
ssl_cert_reqs=none
as redis connection kwargs, but this parameter is not supported there. I have a feeling that this may be a bug, as by defaultredis.py
setsssl_certs_reqs
torequired
regardless of context 🤔