# Redis ACL (Access Control List) - Erkl?rung ## Was ist Redis ACL? **Redis ACL (Access Control List)** ist ein Authentifizierungs- und Autorisierungssystem, das in Redis 6.0 eingef?hrt wurde. Es erm?glicht feingranulare Kontrolle ?ber Benutzerrechte und Zugriff auf Redis-Befehle und -Daten. ### Unterschied: Legacy vs. ACL #### Legacy Authentication (vor Redis 6.0) **Wie es funktioniert:** - Ein einzelnes Passwort f?r die gesamte Redis-Instanz - Konfiguration via `requirepass` in `redis.conf` oder `--requirepass` Parameter - Alle verbundenen Clients haben **vollst?ndigen Zugriff** auf alle Daten und Befehle - Keine Unterscheidung zwischen Benutzern **Beispiel:** ```bash # redis.conf requirepass "mein-passwort-123" # Oder via Command Line redis-server --requirepass "mein-passwort-123" ``` **PHP Code:** ```php $redis = new Redis(); $redis->connect('localhost', 6379); $redis->auth('mein-passwort-123'); // Einfache Passwort-Auth // Jetzt hat der Client VOLLST?NDIGEN Zugriff ``` **Probleme:** - ? Keine Benutzer-Trennung - ? Keine feingranulare Kontrolle - ? Alle Clients haben Admin-Rechte - ? Keine M?glichkeit, verschiedene Berechtigungen zu vergeben #### Redis ACL (ab Redis 6.0) **Wie es funktioniert:** - Mehrere Benutzer mit unterschiedlichen Berechtigungen - Jeder Benutzer hat Username + Passwort - Feingranulare Kontrolle ?ber: - Welche Befehle erlaubt sind - Auf welche Keys/Datenbanken zugegriffen werden kann - Lese-/Schreib-Rechte - Spezifische Key-Patterns **Beispiel:** ```bash # Redis CLI ACL SETUSER cache-user on >cache-password123 ~cache:* +get +set +del +exists ACL SETUSER queue-user on >queue-password456 ~queue:* +lpush +rpop +llen ACL SETUSER admin on >admin-password789 ~* &* +@all ``` **PHP Code:** ```php // F?r Cache-Benutzer $redis = new Redis(); $redis->connect('localhost', 6379); $redis->auth('cache-user', 'cache-password123'); // Username + Password // F?r Admin $redis->auth('admin', 'admin-password789'); // Username + Password ``` ## ACL Konzepte im Detail ### 1. Benutzer (Users) **Standard-Benutzer:** - `default`: Voreingestellter Benutzer (ohne Passwort = kein Auth erforderlich) - Benutzer k?nnen aktiv (`on`) oder deaktiviert (`off`) sein **Beispiel:** ```redis ACL SETUSER myuser on >mypassword ``` ### 2. Passw?rter **Passwort-Formate:** - Plaintext: `>password123` - Hash: `#5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8` **Mehrere Passw?rter:** ```redis ACL SETUSER myuser on >password1 >password2 >password3 ``` ### 3. Key-Patterns (Zugriff auf Keys) **Pattern-Syntax:** - `~*`: Zugriff auf alle Keys - `~cache:*`: Zugriff nur auf Keys die mit `cache:` beginnen - `~user:*`: Zugriff nur auf Keys die mit `user:` beginnen - `~{user,cache}:*`: Zugriff auf mehrere Patterns **Beispiel:** ```redis ACL SETUSER cache-user on >pass ~cache:* ~session:* ``` ### 4. Befehle (Commands) **Berechtigungen:** - `+command`: Befehl erlauben (z.B. `+get`, `+set`) - `-command`: Befehl verbieten (z.B. `-flushdb`) - `+@category`: Alle Befehle einer Kategorie erlauben - `-@category`: Alle Befehle einer Kategorie verbieten - `+@all`: Alle Befehle erlauben (Admin) - `+@read`: Nur Lese-Befehle - `+@write`: Nur Schreib-Befehle - `+@keyspace`: Keyspace-Befehle - `+@string`: String-Befehle - `+@list`: List-Befehle - `+@set`: Set-Befehle - `+@sortedset`: Sorted Set-Befehle - `+@hash`: Hash-Befehle - `+@stream`: Stream-Befehle - `+@pubsub`: Pub/Sub-Befehle - `+@transaction`: Transaction-Befehle - `+@connection`: Connection-Befehle - `+@scripting`: Scripting-Befehle - `+@admin`: Admin-Befehle - `+@dangerous`: Gef?hrliche Befehle (flush, debug, etc.) **Beispiel:** ```redis # Cache-User: Nur GET, SET, DEL, EXISTS ACL SETUSER cache-user on >pass ~cache:* +get +set +del +exists # Queue-User: Nur List-Operationen ACL SETUSER queue-user on >pass ~queue:* +lpush +rpop +llen +lrange # Admin: Alle Befehle ACL SETUSER admin on >pass ~* &* +@all ``` ### 5. Datenbanken (Databases) **Standard:** - Alle Datenbanken sind erlaubt (`&*`) - Spezifische Datenbanken: `&0`, `&1`, `&2`, etc. **Beispiel:** ```redis # Nur Datenbank 1 erlauben ACL SETUSER myuser on >pass ~* &1 +@all ``` ## Praktische Beispiele ### Beispiel 1: Cache-User (nur Lese/Schreib auf Cache-Keys) ```redis ACL SETUSER cache-user on >cache-secret-password ~cache:* +get +set +del +exists +expire +ttl ``` **Was darf dieser User?** - ? `GET cache:user:123` - ? `SET cache:user:123 "value"` - ? `DEL cache:user:123` - ? `EXISTS cache:user:123` - ? `GET user:123` (nicht `cache:` Prefix) - ? `FLUSHDB` (nicht erlaubt) - ? `KEYS *` (nicht erlaubt) ### Beispiel 2: Queue-User (nur Queue-Operationen) ```redis ACL SETUSER queue-user on >queue-secret-password ~queue:* +lpush +rpop +llen +lrange +lrem +@list ``` **Was darf dieser User?** - ? `LPUSH queue:emails "task"` - ? `RPOP queue:emails` - ? `LLEN queue:emails` - ? `GET queue:emails` (String-Befehle nicht erlaubt) - ? `FLUSHDB` (nicht erlaubt) ### Beispiel 3: Admin-User (vollst?ndiger Zugriff) ```redis ACL SETUSER admin on >admin-secret-password ~* &* +@all ``` **Was darf dieser User?** - ? Alle Befehle - ? Alle Keys - ? Alle Datenbanken ### Beispiel 4: Read-Only User (nur Lese-Zugriff) ```redis ACL SETUSER readonly-user on >readonly-password ~* +@read ``` **Was darf dieser User?** - ? `GET`, `HGET`, `SMEMBERS`, etc. (Lese-Befehle) - ? `SET`, `DEL`, `FLUSHDB` (Schreib-Befehle) ## ACL vs. Legacy in unserem Framework ### Aktuelle Implementierung (Legacy) **Konfiguration:** ```yaml # docker-compose.staging.yml redis-server --requirepass "password123" ``` **PHP Code:** ```php // RedisConfig.php password: $env->get(EnvKey::REDIS_PASSWORD, null) // RedisConnection.php $redis->auth($this->config->password); // Einfache Passwort-Auth ``` **Problem:** - Alle Verbindungen (cache, queue, session) verwenden dasselbe Passwort - Alle haben vollst?ndigen Zugriff auf alle Daten - Keine Isolation zwischen verschiedenen Use Cases ### Potenzielle ACL-Implementierung **Konfiguration:** ```yaml # docker-compose.staging.yml # Redis startet mit ACL # ACL wird via init script oder config gesetzt: ACL SETUSER cache-user on >cache-password ~cache:* +@read +@write -@dangerous ACL SETUSER queue-user on >queue-password ~queue:* +@list +@read -@dangerous ACL SETUSER session-user on >session-password ~session:* +@read +@write -@dangerous ACL SETUSER admin on >admin-password ~* &* +@all ``` **Environment Variables:** ```env # F?r Cache-Connection REDIS_USERNAME=cache-user REDIS_PASSWORD=cache-password # F?r Queue-Connection REDIS_USERNAME=queue-user REDIS_PASSWORD=queue-password # F?r Session-Connection REDIS_USERNAME=session-user REDIS_PASSWORD=session-password ``` **PHP Code:** ```php // RedisConfig.php public ?string $username = null; public ?string $password = null; // RedisConnection.php if ($this->config->password) { if ($this->config->username) { // ACL: auth(username, password) $authResult = $this->client->auth( $this->config->username, $this->config->password ); } else { // Legacy: auth(password) $authResult = $this->client->auth($this->config->password); } } ``` **Vorteile:** - ? Isolation: Cache-User kann nicht auf Queue-Keys zugreifen - ? Sicherheit: Minimale Berechtigungen (Principle of Least Privilege) - ? Audit: Verschiedene User f?r verschiedene Operationen - ? Schutz: Kein User kann `FLUSHDB` ausf?hren (au?er Admin) ## Wann ACL verwenden? ### ACL ist sinnvoll wenn: 1. **Multi-Tenant Umgebungen** - Verschiedene Anwendungen teilen sich Redis - Jede Anwendung braucht isolierten Zugriff 2. **Sicherheits-Anforderungen** - Compliance-Anforderungen (z.B. PCI-DSS) - Feingranulare Zugriffskontrolle erforderlich 3. **Team-Isolation** - Verschiedene Teams haben verschiedene Bereiche - Cache-Team, Queue-Team, Session-Team 4. **Production vs. Staging** - Staging: Weniger restriktiv - Production: Strenge ACL-Regeln ### Legacy Auth ist ausreichend wenn: 1. **Single-Application** - Nur eine Anwendung nutzt Redis - Keine Multi-Tenant-Anforderungen 2. **Einfache Setups** - Entwicklungs-Umgebungen - Kleine Projekte ohne hohe Sicherheitsanforderungen 3. **Externe Isolation** - Redis l?uft in isoliertem Netzwerk - Zugriff wird auf Netzwerk-Ebene kontrolliert ## Migration von Legacy zu ACL ### Schritt 1: Redis mit ACL konfigurieren ```bash # Redis startet mit Legacy Auth # Dann ACL konfigurieren: # Legacy User erstellen (f?r Backward Compatibility) ACL SETUSER default on >legacy-password ~* &* +@all # Spezialisierte User erstellen ACL SETUSER cache-user on >cache-password ~cache:* +@read +@write ACL SETUSER queue-user on >queue-password ~queue:* +@list ``` ### Schritt 2: Code anpassen ```php // Schrittweise Migration: // 1. Code unterst?tzt beide Methoden (Backward Compatible) // 2. Neue Connections verwenden ACL // 3. Alte Connections k?nnen weiterhin Legacy Auth verwenden ``` ### Schritt 3: Testing ```php // Test mit verschiedenen Usern // Verifizieren dass Isolation funktioniert // Verifizieren dass Legacy Auth noch funktioniert ``` ## Zusammenfassung | Aspekt | Legacy Auth | Redis ACL | |--------|-------------|-----------| | **Benutzer** | 1 (implizit) | Viele (explizit) | | **Passwort** | 1 Passwort f?r alle | Passwort pro User | | **Berechtigungen** | Alles oder nichts | Feingranular | | **Key-Isolation** | Nein | Ja (Patterns) | | **Befehl-Kontrolle** | Nein | Ja (pro Command) | | **Komplexit?t** | Niedrig | Mittel-Hoch | | **Sicherheit** | Basis | Hoch | | **Verwaltung** | Einfach | Komplexer | ## Empfehlung f?r unser Framework **Aktuell (Staging):** - Legacy Auth ist ausreichend - Einfacher zu verwalten - Keine Multi-Tenant-Anforderungen **Zukunft (Production):** - ACL k?nnte sinnvoll sein f?r: - Bessere Isolation zwischen Cache/Queue/Session - Compliance-Anforderungen - Multi-Tenant-Szenarien **Code-Vorbereitung:** - Code sollte beide Methoden unterst?tzen (Backward Compatible) - `REDIS_USERNAME` optional machen - Wenn `username` gesetzt ? ACL Auth - Wenn nur `password` ? Legacy Auth ## Weitere Ressourcen - [Redis ACL Documentation](https://redis.io/docs/management/security/acl/) - [Redis ACL Commands](https://redis.io/commands/acl/) - [Redis Security Best Practices](https://redis.io/docs/management/security/)