Awesome-omni-skill redis-security
Master Redis security - authentication, ACL, TLS encryption, network hardening, and production security best practices
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/testing-security/redis-security-majiayu000" ~/.claude/skills/diegosouzapw-awesome-omni-skill-redis-security && rm -rf "$T"
manifest:
skills/testing-security/redis-security-majiayu000/SKILL.mdsource content
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~*
- Keys starting with "app:"~app:*
- Variable pattern (Redis 7+)~user:${USER}:*
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 user definitionsacl-users.conf
- Security audit checklistsecurity-checklist.md
- TLS certificate generationgenerate-certs.sh
References
- Complete security guideSECURITY_GUIDE.md
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:
- Bind to specific IP (not 0.0.0.0)
- Set password with requirepass
- 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")