TLS is not established when connecting to Redis Sentinel #8616

Closed
opened 2025-12-29 20:38:56 +01:00 by adam · 4 comments
Owner

Originally created by @skonefal on GitHub (Sep 14, 2023).

NetBox version

v3.5.9

Python version

3.10

Steps to Reproduce

Deploy Redis replicated in Sentinel mode and configure Netbox as follows:

REDIS:
  tasks:
    SENTINELS: ["redis-node-0.redis-headless:26379","redis-node-1.redis-headless:26379","redis-node-2.redis-headless:26379"]
    SENTINEL_SERVICE: "netbox-redis"
    SENTINEL_TIMEOUT: 300
    USERNAME: 
    DATABASE: 0
    SSL: true
    INSECURE_SKIP_TLS_VERIFY: true
    CA_CERT_PATH: "/etc/ssl/redis_ca"
  caching:
    SENTINELS: ["redis-node-0.redis-headless:26379","redis-node-1.redis-headless:26379","redis-node-2.redis-headless:26379"]    
    SENTINEL_SERVICE: "netbox-redis"
    SENTINEL_TIMEOUT: 300
    USERNAME: 
    DATABASE: 1
    SSL: true
    INSECURE_SKIP_TLS_VERIFY: true
    CA_CERT_PATH: "/etc/ssl/redis_ca"

Expected Behavior

Netbox should connect to Sentinel using TLS and retrieve Redis Master server and port.

Observed Behavior

When Netbox tries to reach out to Sentinel to retrieve current Redis Master I receive following error:

No master found for 'netbox-redis': 
Redis<ConnectionPool<Connection<host=redis-node-0.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-0.redis-headless:26379 : (104, 'Connection reset by peer')"),
Redis<ConnectionPool<Connection<host=redis-node-1.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-1.redis-headless:26379 : (104, 'Connection reset by peer')"),
Redis<ConnectionPool<Connection<host=redis-node-2.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-2.redis-headless:26379 : (104, 'Connection reset by peer')")

I have validated that I can connect to Sentinel using CLI:

# redis-cli -h redis-node-0.redis-headless -p 26379 --tls --cacert ./redis-ca.crt 
redis-node-0.redis-headless:26379> SENTINEL get-master-addr-by-name netbox-redis
1) "redis-node-1.redis-headless.netbox.svc.cluster.local"
2) "6379"

From the other hand, when I do not specify TLS for redis-cli I reproduce the same issue seen in Netbox:

# redis-cli -h redis-node-0.redis-headles -p 26379
redis-node-0.redis-headles:26379> SENTINEL get-master-addr-by-name netbox-redis
Error: Connection reset by peer

I could not find any additional TLS configuration for Redis Sentinel.
Do I miss anything in my configuration, or Netbox does not provide TLS configuration for Sentinel access?

Same configuration (without Sentinels) worked well when connecting to standalone Redis Master.

Originally created by @skonefal on GitHub (Sep 14, 2023). ### NetBox version v3.5.9 ### Python version 3.10 ### Steps to Reproduce Deploy Redis replicated in Sentinel mode and configure Netbox as follows: ``` REDIS: tasks: SENTINELS: ["redis-node-0.redis-headless:26379","redis-node-1.redis-headless:26379","redis-node-2.redis-headless:26379"] SENTINEL_SERVICE: "netbox-redis" SENTINEL_TIMEOUT: 300 USERNAME: DATABASE: 0 SSL: true INSECURE_SKIP_TLS_VERIFY: true CA_CERT_PATH: "/etc/ssl/redis_ca" caching: SENTINELS: ["redis-node-0.redis-headless:26379","redis-node-1.redis-headless:26379","redis-node-2.redis-headless:26379"] SENTINEL_SERVICE: "netbox-redis" SENTINEL_TIMEOUT: 300 USERNAME: DATABASE: 1 SSL: true INSECURE_SKIP_TLS_VERIFY: true CA_CERT_PATH: "/etc/ssl/redis_ca" ``` ### Expected Behavior Netbox should connect to Sentinel using TLS and retrieve Redis Master server and port. ### Observed Behavior When Netbox tries to reach out to Sentinel to retrieve current Redis Master I receive following error: ``` No master found for 'netbox-redis': Redis<ConnectionPool<Connection<host=redis-node-0.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-0.redis-headless:26379 : (104, 'Connection reset by peer')"), Redis<ConnectionPool<Connection<host=redis-node-1.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-1.redis-headless:26379 : (104, 'Connection reset by peer')"), Redis<ConnectionPool<Connection<host=redis-node-2.redis-headless,port=26379,db=0>>> - ConnectionError("Error while reading from redis-node-2.redis-headless:26379 : (104, 'Connection reset by peer')") ``` I have validated that I can connect to Sentinel using CLI: ``` # redis-cli -h redis-node-0.redis-headless -p 26379 --tls --cacert ./redis-ca.crt redis-node-0.redis-headless:26379> SENTINEL get-master-addr-by-name netbox-redis 1) "redis-node-1.redis-headless.netbox.svc.cluster.local" 2) "6379" ``` From the other hand, when I do not specify TLS for redis-cli I reproduce the same issue seen in Netbox: ``` # redis-cli -h redis-node-0.redis-headles -p 26379 redis-node-0.redis-headles:26379> SENTINEL get-master-addr-by-name netbox-redis Error: Connection reset by peer ``` I could not find any additional TLS configuration for Redis Sentinel. Do I miss anything in my configuration, or Netbox does not provide TLS configuration for Sentinel access? Same configuration (without Sentinels) worked well when connecting to standalone Redis Master.
adam added the type: bugstatus: needs ownerpending closureseverity: medium labels 2025-12-29 20:38:56 +01:00
adam closed this issue 2025-12-29 20:38:56 +01:00
Author
Owner

@jeremystretch commented on GitHub (Sep 21, 2023):

It looks like the SSL and SSL_CERT_REQS parameters are being set only for plain Redis.

9b325f4b86/netbox/netbox/settings.py (L672-L693)

I'm not sure what the appropriate parameters are for Sentinel, but they're not present.

@jeremystretch commented on GitHub (Sep 21, 2023): It looks like the `SSL` and `SSL_CERT_REQS` parameters are being set only for plain Redis. https://github.com/netbox-community/netbox/blob/9b325f4b8611160f62294cfdb6bafebae2757bdd/netbox/netbox/settings.py#L672-L693 I'm not sure what the appropriate parameters are for Sentinel, but they're not present.
Author
Owner

@tyler-8 commented on GitHub (Sep 26, 2023):

According to the redis-py docs

sentinel_kwargs is a dictionary of connection arguments used when connecting to sentinel instances. Any argument that can be passed to a normal Redis connection can be specified here. If sentinel_kwargs is not specified, any socket_timeout and socket_keepalive options specified in connection_kwargs will be used.

connection_kwargs are keyword arguments that will be used when establishing a connection to a Redis server.

and from django-redis:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # The hostname in LOCATION is the primary (service / master) name
        "LOCATION": "redis://service_name/db",
        "OPTIONS": {
            # While the default client will work, this will check you
            # have configured things correctly, and also create a
            # primary and replica pool for the service specified by
            # LOCATION rather than requiring two URLs.
            "CLIENT_CLASS": "django_redis.client.SentinelClient",

            # Sentinels which are passed directly to redis Sentinel.
            "SENTINELS": SENTINELS,

            # kwargs for redis Sentinel (optional).
            "SENTINEL_KWARGS": {},

            # You can still override the connection pool (optional).
            "CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool",
        },
    },

and django-rq

    'with-sentinel': {
        'SENTINELS': [('localhost', 26736), ('localhost', 26737)],
        'MASTER_NAME': 'redismaster',
        'DB': 0,
        # Redis username/password
        'USERNAME': 'redis-user',
        'PASSWORD': 'secret',
        'SOCKET_TIMEOUT': 0.3,
        'CONNECTION_KWARGS': {  # Eventual additional Redis connection arguments
            'ssl': True
        }
        'SENTINEL_KWARGS': {    # Eventual Sentinel connection arguments
            # If Sentinel also has auth, username/password can be passed here
            'username': 'sentinel-user',
            'password': 'secret',
        },
    },

So based on all of that, I would suspect that SENTINEL_KWARGS needs to receive any "special" connection parameters.

@tyler-8 commented on GitHub (Sep 26, 2023): According to the `redis-py` [docs](https://redis-py.readthedocs.io/en/v4.1.2/connections.html#redis.sentinel.Sentinel) > sentinel_kwargs is a dictionary of connection arguments used when connecting to sentinel instances. Any argument that can be passed to a normal Redis connection can be specified here. If sentinel_kwargs is not specified, any socket_timeout and socket_keepalive options specified in connection_kwargs will be used. > > connection_kwargs are keyword arguments that will be used when establishing a connection to a Redis server. and from [django-redis](https://github.com/jazzband/django-redis/blob/master/README.rst#use-the-sentinel-connection-factory): ```python CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", # The hostname in LOCATION is the primary (service / master) name "LOCATION": "redis://service_name/db", "OPTIONS": { # While the default client will work, this will check you # have configured things correctly, and also create a # primary and replica pool for the service specified by # LOCATION rather than requiring two URLs. "CLIENT_CLASS": "django_redis.client.SentinelClient", # Sentinels which are passed directly to redis Sentinel. "SENTINELS": SENTINELS, # kwargs for redis Sentinel (optional). "SENTINEL_KWARGS": {}, # You can still override the connection pool (optional). "CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool", }, }, ``` and [django-rq](https://github.com/rq/django-rq/blob/master/README.rst) ```python 'with-sentinel': { 'SENTINELS': [('localhost', 26736), ('localhost', 26737)], 'MASTER_NAME': 'redismaster', 'DB': 0, # Redis username/password 'USERNAME': 'redis-user', 'PASSWORD': 'secret', 'SOCKET_TIMEOUT': 0.3, 'CONNECTION_KWARGS': { # Eventual additional Redis connection arguments 'ssl': True } 'SENTINEL_KWARGS': { # Eventual Sentinel connection arguments # If Sentinel also has auth, username/password can be passed here 'username': 'sentinel-user', 'password': 'secret', }, }, ``` So based on all of that, I would suspect that `SENTINEL_KWARGS` needs to receive any "special" connection parameters.
Author
Owner

@github-actions[bot] commented on GitHub (Dec 26, 2023):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

@github-actions[bot] commented on GitHub (Dec 26, 2023): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@github-actions[bot] commented on GitHub (Jan 25, 2024):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@github-actions[bot] commented on GitHub (Jan 25, 2024): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#8616