UZMAN
Security - Authentication, ACL & TLS
Redis 8 ve .NET 10 ile caching, veri yapıları, messaging, ölçekleme, dayanıklılık ve production operasyonları.
Kod örneği görünümü
Bu sayfadaki eşleşen örnekleri seçilen istemciye göre gösterir.
| Kullan | Kullanma | Gerçek Hayat |
|---|---|---|
| ACL (Redis 6+) — Her servis kendi user'ı ile bağlanır | Tek shared password tüm servislere | Fintech: payment-service sadece pay: prefix'e yazabilir, analytics read-only |
| TLS — Redis dış network'ten erişilebilir veya compliance gerekli | Aynı VPC/host içinde, performance-critical | SaaS multi-tenant: Data center arası replikasyon — TLS zorunlu |
| requirepass — Redis 5 legacy veya tek uygulama bağlanıyor | Multi-service environment (ACL tercih et) | Monolith: Tek .NET app → tek şifre yeterli, ACL overhead gereksiz |
| Network isolation (VPC/firewall) — Her zaman, ek güvenlik katmanı | "Şifre var, firewall gereksiz" düşüncesi | Startup: Redis public IP'de, şifresiz → cryptominer 20 dakikada bulur |
| Key prefix ACL — Multi-tenant data separation | Tenant isolation sadece application code'da | E-ticaret marketplace: seller:123:* sadece ilgili servise açık |
Gerçek hayat senaryosu — Healthcare SaaS: HIPAA compliance → TLS zorunlu + ACL ile audit trail + her microservice ayrı user. Bir servis compromise olsa bile diğer tenant verisine erişemez.
Security — Authentication, ACL & TLS
Şifre Atama (requirepass)
# === Basit şifre (Redis 5 ve öncesi uyumlu) ===
# redis.conf
requirepass MyStr0ngP@ssw0rd!2026
# Runtime'da değiştir (restart'a kadar)
CONFIG SET requirepass "NewP@ssw0rd"
# Bağlantı
redis-cli -a MyStr0ngP@ssw0rd!2026
# veya bağlandıktan sonra:
AUTH MyStr0ngP@ssw0rd!2026
# === ACL (Redis 6+ — ÖNERİLEN) ===
# Varsayılan kullanıcıya şifre ata
ACL SETUSER default on >MyStr0ngP@ssw0rd!2026
# Uygulama için read-only kullanıcı
ACL SETUSER app-cache-reader on >CacheR3ad0nly! ~cache:* ~product:* &* +@read +ping +info
# Uygulama için yazma yetkili kullanıcı
ACL SETUSER app-writer on >Wr1t3rP@ss! ~* &* +@all -@dangerous -@admin
# Admin kullanıcı (ops team)
ACL SETUSER ops-admin on >0psAdm1n!Str0ng ~* &* +@all
# Sadece pub/sub yetkisi
ACL SETUSER event-publisher on >PubP@ss! resetchannels &events:* +publish +subscribe +ping
# Kullanıcı listesi
ACL LIST
ACL WHOAMI
ACL GETUSER app-writer
ACL CAT # tüm komut kategorileri
ACL CAT dangerous # dangerous kategorisindeki komutlar
# ACL'i dosyaya kaydet (restart'ta korunur)
ACL SAVE
# /etc/redis/users.acl dosyası
# Dangerous komutları tamamen kapat
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
rename-command DEBUG ""
rename-command SHUTDOWN ""
# === TLS/SSL ===
# redis.conf
port 0 # plaintext kapat
tls-port 6380
tls-cert-file /tls/redis.crt
tls-key-file /tls/redis.key
tls-ca-cert-file /tls/ca.crt
tls-auth-clients optional # client cert opsiyonel
tls-protocols "TLSv1.2 TLSv1.3"
# Test
redis-cli --tls --cert /tls/client.crt --key /tls/client.key -p 6380 PING
// === Basit şifre ===
var config = ConfigurationOptions.Parse("redis:6379");
config.Password = builder.Configuration["Redis:Password"];
// Connection string formatı
// "redis:6379,password=MyStr0ngP@ssw0rd!2026,abortConnect=false"
// === ACL kullanıcı adı + şifre (Redis 6+) ===
var config = new ConfigurationOptions
{
EndPoints = { "redis:6379" },
User = "app-writer", // ACL username
Password = "Wr1t3rP@ss!", // ACL password
AbortOnConnectFail = false,
ClientName = "myapp-api-v2"
};
// === TLS bağlantı ===
var config = new ConfigurationOptions
{
EndPoints = { "redis:6380" },
User = "app-writer",
Password = builder.Configuration["Redis:Password"],
Ssl = true,
SslProtocols = System.Security.Authentication.SslProtocols.Tls13,
AbortOnConnectFail = false
};
// Client certificate (mTLS) — event subscription initializer dışında yapılır
config.CertificateSelection += (sender, targetHost, localCerts, remoteCert, acceptableIssuers) =>
new X509Certificate2("/tls/client.pfx", "cert-password");
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect(config));
// === Secret yönetimi (production) ===
// appsettings.Production.json — ASLA düz şifre koyma!
// Azure Key Vault / AWS Secrets Manager / HashiCorp Vault kullan
builder.Configuration.AddAzureKeyVault(
new Uri("https://myvault.vault.azure.net/"),
new DefaultAzureCredential());
var redisPassword = builder.Configuration["Redis:Password"]; // vault'tan gelir
// === Ortam bazlı güvenlik ===
public static ConfigurationOptions BuildRedisConfig(IConfiguration config, IHostEnvironment env)
{
var options = new ConfigurationOptions
{
AbortOnConnectFail = false,
ConnectRetry = 3,
ConnectTimeout = 5000,
SyncTimeout = 3000,
AsyncTimeout = 3000
};
if (env.IsDevelopment())
{
options.EndPoints.Add("localhost:6379");
// Dev'de şifre opsiyonel
}
else
{
options.EndPoints.Add(config["Redis:Host"] ?? "redis:6380");
options.User = config["Redis:User"] ?? "app-writer";
options.Password = config["Redis:Password"];
options.Ssl = true;
options.SslProtocols = SslProtocols.Tls13;
options.ClientName = $"myapp-{Environment.MachineName}";
}
return options;
}
ACL Komut Kategorileri
| Kategori | İçerik | Kime Verilir |
|---|---|---|
| @read | GET, MGET, HGETALL, LRANGE... | Read-only service |
| @write | SET, HSET, LPUSH, DEL... | Write service |
| @set | SADD, SREM, SINTER... | Set ops |
| @sortedset | ZADD, ZRANGE... | Leaderboard |
| @hash | HSET, HGET, HDEL... | User/session |
| @pubsub | PUBLISH, SUBSCRIBE... | Event bus |
| @admin | CONFIG, SHUTDOWN, REPLICAOF... | Ops team only |
| @dangerous | FLUSHALL, KEYS, DEBUG... | Kimseye verme |
| @stream | XADD, XREAD, XGROUP... | Stream consumer |
Güvenlik Checklist
| # | Kontrol | Seviye |
|---|---|---|
| 1 | requirepass veya ACL aktif |
Minimum |
| 2 | Servis bazlı ACL kullanıcıları | Önerilen |
| 3 | ~key-pattern* ile key erişimi kısıtla |
Önerilen |
| 4 | TLS/SSL aktif | Production |
| 5 | Private network (VPC/VLAN) | Production |
| 6 | FLUSHALL/CONFIG/KEYS rename/disable | Production |
| 7 | bind 127.0.0.1 veya private IP |
Zorunlu |
| 8 | protected-mode yes (şifresizse) |
Varsayılan |
| 9 | Secret manager (Vault/KV) ile şifre | Production |
| 10 | Client name atama (ClientName) |
Debug kolaylığı |
| 11 | Idle timeout (timeout 300) |
Resource leak |
| 12 | maxclients limiti |
DoS koruması |
Redis'i ASLA public internet'e açma! Şifresiz Redis internete açıldığında dakikalar içinde crypto-miner bulaşır. Her zaman: private network + firewall + TLS + ACL.
Production Config
# redis.conf — production template
bind 10.0.1.50 # sadece private IP
protected-mode yes
port 0
tls-port 6380
requirepass "" # ACL kullanıyorsan boş bırak
maxmemory 4gb
maxmemory-policy allkeys-lru
timeout 300
tcp-keepalive 60
maxclients 10000
# Persistence
appendonly yes
aof-use-rdb-preamble yes
save 3600 1 300 100
# Logging
loglevel notice
logfile /var/log/redis/redis.log
# Slow query log
slowlog-log-slower-than 10000 # 10ms
slowlog-max-len 128
// Production-ready connection
var config = new ConfigurationOptions
{
EndPoints = { "redis-primary:6380" },
User = "app-writer",
Password = builder.Configuration["Redis:Password"],
Ssl = true,
SslProtocols = SslProtocols.Tls13,
AbortOnConnectFail = false,
ConnectRetry = 3,
ConnectTimeout = 5000,
SyncTimeout = 3000,
AsyncTimeout = 3000,
ReconnectRetryPolicy = new ExponentialRetry(5000),
DefaultDatabase = 0,
ClientName = $"myapp-{Environment.MachineName}",
// Sentinel
// ServiceName = "mymaster",
// EndPoints = { "sentinel1:26379", "sentinel2:26379", "sentinel3:26379" }
};
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect(config));
// appsettings.Production.json
{
"Redis": {
"Host": "redis-primary:6380",
"User": "app-writer",
"Password": "— Azure Key Vault / AWS Secrets Manager —"
},
"ConnectionStrings": {
"Redis": "redis-primary:6380,user=app-writer,password=***,ssl=true,abortConnect=false"
}
}
Production Checklist
| # | Kontrol | Neden |
|---|---|---|
| 1 | maxmemory = RAM × 0.75 |
OOM koruması |
| 2 | maxmemory-policy = allkeys-lru |
Otomatik eviction |
| 3 | AOF + RDB hybrid | Veri güvenliği |
| 4 | ACL user/pass | Yetkisiz erişim |
| 5 | TLS aktif | Şifreli iletişim |
| 6 | Private network | Public erişim yok |
| 7 | FLUSHALL/CONFIG disable | Kazara silme |
| 8 | abortConnect=false |
Graceful reconnect |
| 9 | Health check | Monitoring |
| 10 | Polly retry + circuit breaker | Resilience |
| 11 | Key TTL her zaman | Memory leak önleme |
| 12 | KEYS komutu disable | O(N) blokaj |
| 13 | RDB backup → S3/Blob (cron) | Disaster recovery |
| 14 | Backup restore testi (aylık) | Backup'ın gerçekten çalıştığını doğrula |
| 15 | slowlog-log-slower-than 10000 |
Yavaş komutları logla (10ms+) |