redis / redis-py

Redis Python client
MIT License
12.4k stars 2.48k forks source link

Authentication errors when using RESP 3 and health check #3283

Open king-phyte opened 2 weeks ago

king-phyte commented 2 weeks ago

Version: 5.0.6

Platform: MacOS Sonoma Version 14.5

Description: When using the RESP 3 protocol with health check enabled for an auth enabled redis server, all commands return an authentication error (Both redis and hiredis, so maybe I am doing something wrong instead). It seems (from my "debugging") the issue stems from the PING command that is issued before the actual command is sent. I can confirm that if no health check time is set, the client works as expected. Also, if the protocol is set to 2, it works as expected. Sample provided below:

redis.conf

protected-mode yes
timeout 30
port 0
tls-port 6379
tls-cert-file /tls/redis.crt
tls-key-file /tls/redis.key
tls-ca-cert-file /tls/ca.crt
tls-auth-clients optional
daemonize no
loglevel debug
logfile ""
save ""
maxmemory-policy allkeys-lru
appendonly no

user king on +@all ~* >king+phyte
user default on +@all ~* >king+phyte

Redis configuration

import redis.asyncio as aioredis
import redis.exceptions

async_redis_connection = aioredis.Redis(
    username="king",
    password="king+phyte",
    host="xxx.xxx.xxx.xxx",
    port=3306,
    decode_responses=True,
    protocol=3, # If set to 2, works fine with health check
    ssl=True,
    ssl_cert_reqs="none",
    # health_check_interval=30, # If enabled on RESP 3, auth errors will be thrown
    socket_timeout=5,
)

async def get_async_redis_connection():
    async with async_redis_connection.client() as connection:
       connection.get("foo") # Point of failure
  File "/Users/king/PycharmProjects/backend/edok/database/core.py", line 71, in get_async_redis_connection
    async with async_redis_connection.client() as connection:
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/client.py", line 533, in __aenter__
    return await self.initialize()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/client.py", line 354, in initialize
    self.connection = await self.connection_pool.get_connection("_")
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 1083, in get_connection
    await self.ensure_connection(connection)
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 1116, in ensure_connection
    await connection.connect()
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 289, in connect
    await self.on_connect()
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 345, in on_connect
    await self.send_command("HELLO", self.protocol, "AUTH", *auth_args)
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 497, in send_command
    await self.send_packed_command(
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 460, in send_packed_command
    await self.check_health()
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 448, in check_health
    await self.retry.call_with_retry(self._send_ping, self._ping_failed)
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/retry.py", line 64, in call_with_retry
    raise error
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/retry.py", line 59, in call_with_retry
    return await do()
           ^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 435, in _send_ping
    if str_if_bytes(await self.read_response()) != "PONG":
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/asyncio/connection.py", line 528, in read_response
    response = await self._parser.read_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/_parsers/resp3.py", line 153, in read_response
    response = await self._read_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/king/Library/Caches/pypoetry/virtualenvs/backend-xjdhYfao-py3.12/lib/python3.12/site-packages/redis/_parsers/resp3.py", line 182, in _read_response
    raise error
redis.exceptions.AuthenticationError: Authentication required.