- Add `FileOwnership` to encapsulate file owner and group information. - Add `ProcessUser` to represent and manage system process user details. - Enhance ownership matching and debugging with structured data objects. - Include new documentation on file ownership handling and permission improvements. - Prepare infrastructure for enriched error handling in filesystem operations.
389 lines
10 KiB
Markdown
389 lines
10 KiB
Markdown
# 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/)
|