Claude Code Plugins

Community-maintained marketplace

Feedback

Master Redis security - authentication, ACL, TLS encryption, network hardening, and production security best practices

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name redis-security
description Master Redis security - authentication, ACL, TLS encryption, network hardening, and production security best practices
sasmp_version 1.3.0
bonded_agent 07-redis-security
bond_type PRIMARY_BOND
version 2.1.0
last_updated 2025-01
parameters [object Object]
retry_config [object Object]
observability [object Object]

Redis Security Skill

Security Maturity Levels

Level Features Use Case
Basic Password only Development
Standard ACL + Network Internal apps
High ACL + TLS + Network Production
Paranoid All + Audit + WAF Financial/Healthcare

Authentication

Legacy Password (Pre-6.0)

# redis.conf
requirepass your_strong_password_here_min_32_chars
AUTH password

ACL Authentication (Redis 6.0+)

AUTH username password

Access Control Lists (ACL)

User Management

# Create user with specific permissions
ACL SETUSER app_user on >secure_password ~app:* +@read +@write -@dangerous

# Create read-only user
ACL SETUSER readonly_user on >password ~* +@read -@write -@admin

# Create admin user
ACL SETUSER admin_user on >strong_password ~* +@all

# Disable user
ACL SETUSER app_user off

# Delete user
ACL DELUSER app_user

# List all users
ACL LIST

# Show current user
ACL WHOAMI

ACL Rule Syntax

ACL SETUSER username [on|off] [>password|#hash] [~pattern] [+command|-command] [+@category|-@category]

Key Patterns:

  • ~* - All keys
  • ~app:* - Keys starting with "app:"
  • ~user:${USER}:* - Variable pattern (Redis 7+)

Command Categories:

ACL CAT  # List all categories

# Common categories:
# @read - Read commands (GET, MGET, etc.)
# @write - Write commands (SET, DEL, etc.)
# @admin - Admin commands (CONFIG, DEBUG, etc.)
# @dangerous - Potentially harmful (KEYS, FLUSHALL, etc.)
# @slow - Commands that may block
# @fast - O(1) commands
# @pubsub - Pub/Sub commands
# @scripting - Lua scripting

ACL File

# acl-users.conf
user default off
user admin on >admin_password ~* +@all
user app on >app_password ~app:* +@read +@write -@dangerous
user readonly on >ro_password ~* +@read -@write -@admin
user replication on >repl_password +psync +replconf +ping
# redis.conf
aclfile /etc/redis/acl-users.conf

ACL Audit Log

# View ACL violations
ACL LOG [count]

# Reset log
ACL LOG RESET

TLS Configuration

Generate Certificates

#!/bin/bash
# generate-certs.sh

# CA
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha256 -days 3650 \
    -key ca.key -out ca.crt \
    -subj "/CN=Redis-CA"

# Server
openssl genrsa -out redis.key 2048
openssl req -new -key redis.key -out redis.csr \
    -subj "/CN=redis-server"
openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -out redis.crt -days 365 -sha256

# Client (optional for mTLS)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
    -subj "/CN=redis-client"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -out client.crt -days 365 -sha256

# Set permissions
chmod 600 *.key
chmod 644 *.crt

Server Configuration

# redis.conf

# TLS port (disable plain port)
tls-port 6379
port 0

# Certificates
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt

# Require client certificates (mTLS)
tls-auth-clients yes  # or 'optional' or 'no'

# TLS versions (disable old versions)
tls-protocols "TLSv1.2 TLSv1.3"

# Cipher suites
tls-ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
tls-ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"

# Replication over TLS
tls-replication yes

# Cluster over TLS
tls-cluster yes

Client Connection

# redis-cli with TLS
redis-cli --tls \
    --cert /path/to/client.crt \
    --key /path/to/client.key \
    --cacert /path/to/ca.crt \
    -h redis.example.com
# Python with TLS
import redis
r = redis.Redis(
    host='redis.example.com',
    port=6379,
    ssl=True,
    ssl_certfile='/path/to/client.crt',
    ssl_keyfile='/path/to/client.key',
    ssl_ca_certs='/path/to/ca.crt'
)

Network Security

Bind Configuration

# redis.conf

# Bind to specific interfaces
bind 127.0.0.1 -::1        # Localhost only
bind 10.0.0.1 127.0.0.1    # Internal + localhost

# Protected mode (blocks external when no password)
protected-mode yes

Firewall Rules

# UFW
ufw allow from 10.0.0.0/8 to any port 6379

# iptables
iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

# Kubernetes NetworkPolicy
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: redis-policy
spec:
  podSelector:
    matchLabels:
      app: redis
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: redis
    ports:
    - port: 6379

Command Restrictions

Rename Dangerous Commands

# redis.conf
rename-command FLUSHALL ""           # Disable completely
rename-command FLUSHDB ""
rename-command DEBUG ""
rename-command SHUTDOWN SHUTDOWN_b840fc02  # Rename
rename-command CONFIG CONFIG_b840fc02
rename-command KEYS ""               # Disable (use SCAN)
rename-command BGSAVE ""             # Control via ACL instead

ACL-Based Restrictions (Preferred)

# Better than rename-command
ACL SETUSER app_user on >password ~app:* +@all -@dangerous -CONFIG -DEBUG -SHUTDOWN

Security Checklist

Development

□ Set requirepass
□ Bind to localhost only
□ Enable protected-mode

Staging

□ Configure ACL users
□ Disable default user
□ Enable TLS
□ Restrict network access
□ Disable dangerous commands

Production

□ Strong unique passwords (32+ chars)
□ Per-application ACL users
□ mTLS with client certificates
□ Firewall/NetworkPolicy
□ No public internet exposure
□ Regular credential rotation
□ ACL audit logging enabled
□ Rename/disable admin commands
□ Regular security updates
□ Backup encryption

Security Headers Check Script

#!/bin/bash
# security-audit.sh

REDIS_HOST=${1:-localhost}
REDIS_PORT=${2:-6379}

echo "=== Redis Security Audit ==="

# Check authentication
echo -n "Authentication required: "
if redis-cli -h $REDIS_HOST -p $REDIS_PORT PING 2>&1 | grep -q "NOAUTH"; then
    echo "YES ✓"
else
    echo "NO ✗ (WARNING)"
fi

# Check protected mode
echo -n "Protected mode: "
redis-cli -h $REDIS_HOST -p $REDIS_PORT CONFIG GET protected-mode | grep -q "yes" && echo "YES ✓" || echo "NO ✗"

# Check TLS
echo -n "TLS enabled: "
redis-cli -h $REDIS_HOST -p $REDIS_PORT --tls INFO server 2>/dev/null && echo "YES ✓" || echo "NO ✗"

# Check dangerous commands
echo "Dangerous commands:"
for cmd in FLUSHALL FLUSHDB DEBUG KEYS CONFIG; do
    echo -n "  $cmd: "
    if redis-cli -h $REDIS_HOST -p $REDIS_PORT ACL CAT 2>/dev/null | grep -q "^$cmd$"; then
        echo "AVAILABLE ✗"
    else
        echo "RESTRICTED ✓"
    fi
done

Assets

  • acl-users.conf - ACL user definitions
  • security-checklist.md - Security audit checklist
  • generate-certs.sh - TLS certificate generation

References

  • SECURITY_GUIDE.md - Complete security guide

Troubleshooting Guide

Common Issues & Solutions

1. Authentication Failures

NOAUTH Authentication required

Fix:

AUTH password
# or
AUTH username password

2. ACL Permission Denied

NOPERM this user has no permissions to run the 'CONFIG' command

Diagnosis:

ACL WHOAMI
ACL LIST

Fix: Update user permissions

ACL SETUSER myuser +CONFIG

3. TLS Connection Failed

SSL_connect: certificate verify failed

Fixes:

# Check certificate dates
openssl x509 -in redis.crt -noout -dates

# Verify certificate chain
openssl verify -CAfile ca.crt redis.crt

# Check hostname matches
openssl x509 -in redis.crt -noout -text | grep DNS

4. Protected Mode Blocking

DENIED Redis is running in protected mode

Fix options:

  1. Bind to specific IP (not 0.0.0.0)
  2. Set password with requirepass
  3. Disable protected-mode (NOT recommended)

5. Client Certificate Required

SSL: certificate required

Fix: Provide client certificate

redis-cli --tls --cert client.crt --key client.key --cacert ca.crt

Debug Checklist

□ Password set? (CONFIG GET requirepass)
□ User exists? (ACL LIST)
□ User enabled? (ACL GETUSER username)
□ Correct permissions? (ACL GETUSER username)
□ TLS certs valid? (openssl verify)
□ Firewall allows connection?
□ Bind includes client IP? (CONFIG GET bind)
□ Protected mode appropriate? (CONFIG GET protected-mode)

Security Incident Response

1. Immediate Actions:
   □ Block compromised credentials (ACL SETUSER user off)
   □ Enable ACL LOG monitoring
   □ Check for unauthorized commands (MONITOR briefly)

2. Investigation:
   □ Review ACL LOG
   □ Check client list (CLIENT LIST)
   □ Audit data integrity (DBSIZE, SCAN)

3. Remediation:
   □ Rotate all credentials
   □ Update firewall rules
   □ Enable/strengthen TLS
   □ Review and restrict ACLs

Error Codes Reference

Code Name Description Recovery
SEC001 NOAUTH Not authenticated AUTH command
SEC002 WRONGPASS Invalid password Check credentials
SEC003 NOPERM ACL permission denied Update ACL
SEC004 TLS_CERT Certificate error Fix certificate
SEC005 PROTECTED Protected mode block Configure properly

Test Template

# test_redis_security.py
import redis
import pytest
import ssl

@pytest.fixture
def r_auth():
    return redis.Redis(
        host='localhost',
        port=6379,
        password='test_password',
        decode_responses=True
    )

class TestAuthentication:
    def test_auth_required(self):
        r = redis.Redis(decode_responses=True)
        with pytest.raises(redis.AuthenticationError):
            r.ping()

    def test_auth_success(self, r_auth):
        assert r_auth.ping() == True

    def test_wrong_password(self):
        r = redis.Redis(password='wrong_password')
        with pytest.raises(redis.AuthenticationError):
            r.ping()

class TestACL:
    def test_acl_whoami(self, r_auth):
        result = r_auth.acl_whoami()
        assert result is not None

    def test_acl_list(self, r_auth):
        users = r_auth.acl_list()
        assert len(users) > 0

    def test_permission_denied(self, r_auth):
        # Create limited user
        r_auth.acl_setuser(
            "limited_user",
            enabled=True,
            passwords=["+limited_pass"],
            keys=["allowed:*"],
            commands=["+get", "-set"]
        )

        # Connect as limited user
        r_limited = redis.Redis(
            username="limited_user",
            password="limited_pass",
            decode_responses=True
        )

        # Should fail
        with pytest.raises(redis.ResponseError, match="NOPERM"):
            r_limited.set("forbidden:key", "value")

        # Cleanup
        r_auth.acl_deluser("limited_user")

class TestTLS:
    def test_tls_connection(self):
        """Test TLS connection (requires TLS-enabled Redis)"""
        try:
            r = redis.Redis(
                host='localhost',
                port=6379,
                ssl=True,
                ssl_cert_reqs=ssl.CERT_REQUIRED,
                ssl_ca_certs='/path/to/ca.crt'
            )
            assert r.ping() == True
        except redis.ConnectionError:
            pytest.skip("TLS not configured")