Redis güvenlik yapılandırması, kurulum sırasında en çok atlanan adımdır ve bunun bedeli genellikle ağır olur. Sebebi şu: Redis paket olarak kurulduğunda çalışır durumda gelir, uygulamanız bağlanır, her şey yolunda görünür. Kimlik doğrulama yoktur, şifreleme yoktur, komut kısıtlaması yoktur — ama hiçbir hata mesajı da yoktur. Sunucunuzun 6379 portu bir şekilde dışarı açıldığında ise bu "sorunsuz" kurulum, saldırganın sunucunuza SSH anahtarı yazabildiği, cron görevi ekleyebildiği ve tüm verinizi tek komutla silebildiği bir kapıya dönüşür.
Bu rehberde bir Redis örneğini üretime hazır hâle getirmek için katman katman ne yapılması gerektiğini anlatacağım: ağ düzeyinde erişimi kapatmak, requirepass ve ACL ile kimlik doğrulaması kurmak, tehlikeli komutları devre dışı bırakmak, TLS ile trafiği şifrelemek, dosya izinlerini ve bellek sınırlarını doğru ayarlamak. Sonunda da sunucunuzun daha önce ele geçirilip geçirilmediğini anlamanız için somut bir kontrol listesi bulacaksınız. Örnekler Debian/Ubuntu üzerindeki standart paket yerleşimine (/etc/redis/redis.conf) göre verilmiştir; RHEL türevlerinde yol /etc/redis.conf olur, mantık değişmez.
Varsayılan Kurulum Neden Tehlikeli#
Redis'in tasarım felsefesi "güvenli bir ağın içinde, güvenilen istemcilerle çalışır" varsayımına dayanır. Bu varsayım kâğıt üzerinde makuldür ama pratikte iki şekilde çöker: ya sunucunun güvenlik duvarı yanlış yapılandırılır, ya da Redis konteyner içinde çalışırken portu yanlışlıkla ana makineye açılır. İkisi de saniyeler süren hatalardır ve sonuçları aynıdır.
Kimlik doğrulaması olmayan bir Redis'te saldırganın yapabileceklerini somutlaştırayım, çünkü teorik anlatım kimseyi ikna etmiyor. Redis'in CONFIG SET komutu, çalışma dizinini ve kalıcılık dosyasının adını çalışırken değiştirmenize izin verir. Saldırgan bunu şu şekilde kullanır: dizini /root/.ssh, dosya adını authorized_keys yapar, kendi genel anahtarını bir anahtara yazar ve SAVE komutuyla diske döker. RDB dosyasının başında ve sonunda çöp baytlar olsa da SSH, satır bazlı okuduğu için geçerli anahtar satırını kabul eder. Sonuç: saldırgan artık sunucunuza root olarak SSH yapabiliyordur. Aynı numara /var/spool/cron/crontabs dizinine yazılarak da uygulanır ve bu kez sunucunuzda bir kripto madenci çalışmaya başlar.
Bu senaryonun ürkütücü yanı, hiçbir açıktan (zafiyet) yararlanmaması. Redis'in belgelenmiş, normal komutlarını kullanır. Yani yamalarınızı güncel tutmanız sizi korumaz; sizi koruyacak tek şey erişimi kapatmak ve kimlik doğrulaması açmaktır. Aynı disiplin diğer veritabanları için de geçerlidir; MariaDB tarafındaki karşılığını MariaDB kurulumu ve güvenliği yazısında bulabilirsiniz.
Ağ Katmanı: bind, protected-mode ve Güvenlik Duvarı#
Güvenliğin ilk ve en etkili katmanı ağdır. Redis'e ulaşamayan bir saldırgan, parolayı da denemez. Yapılandırmada iki anahtar bu işi görür:
# /etc/redis/redis.conf
# Yalnızca yerel arayüzlerden dinle. Birden fazla adresi boşlukla ayırın.
# Uygulama başka bir sunucudaysa, o sunucunun ulaşabileceği ÖZEL ağ adresini yazın.
bind 127.0.0.1 -::1
# Parola yoksa ve bind kısıtlıysa dışarıdan gelen bağlantıları reddet.
# Asla "no" yapmayın; bu ayar son savunma hattıdır.
protected-mode yes
# Varsayılan port. Değiştirmek gerçek bir güvenlik önlemi değildir ama
# otomatik tarayıcıların gürültüsünü belirgin biçimde azaltır.
port 6379
bind satırındaki yaygın hata 0.0.0.0 yazmaktır. Uygulama sunucusu farklı bir makinedeyse doğru çözüm tüm dünyaya açmak değil, yalnızca özel ağ arayüzünün adresini eklemektir: bind 127.0.0.1 10.0.0.5. Bu satırı değiştirdikten sonra servisi yeniden başlatmanız gerekir; CONFIG SET ile değiştirilemeyen az sayıdaki ayardan biridir.
İkinci savunma güvenlik duvarıdır ve bind doğru ayarlanmış olsa bile mutlaka kurulmalıdır, çünkü tek bir yanlış yapılandırma dosyası dağıtımı bind satırını geri alabilir. Ubuntu'da UFW ile:
# Varsayılan olarak gelen her şeyi reddet
sudo ufw default deny incoming
sudo ufw allow OpenSSH
# Redis'e yalnızca uygulama sunucusunun özel IP'sinden izin ver
sudo ufw allow from 10.0.0.7 to any port 6379 proto tcp
sudo ufw enable
sudo ufw status numbered
Docker kullanıyorsanız ekstra dikkat gerekir: -p 6379:6379 ile yayınlanan bir port, Docker kendi iptables kurallarını UFW'den önce yazdığı için güvenlik duvarını atlayabilir. Konteyner içindeki Redis'e yalnızca diğer konteynerler erişecekse portu hiç yayınlamayın, ortak bir Docker ağı kullanın; ana makineden erişim gerekiyorsa -p 127.0.0.1:6379:6379 yazarak bağlamayı yerel arayüze sabitleyin. Dışarıdan gelen trafiği süzmek için ayrıca DDoS koruma katmanını devreye almak, servis portlarına yönelen otomatik taramaların büyük bölümünü kaynağında keser.
Kimlik Doğrulama: requirepass ve ACL#
Ağ kapalı olsa bile parola şarttır; aynı sunucudaki başka bir uygulamanın ele geçirilmesi durumunda ikinci savunma hattınız budur. En basit yöntem tek parolalı klasik yapılandırmadır:
# Uzun ve rastgele olsun. Redis saniyede yüz binlerce deneme işleyebilir,
# yani kısa parola pratikte parolasız demektir.
requirepass 9f3aQ7pR2xLmVt8ZcH4bNs6UwEy1KdJv
Parolayı oluşturmak için sunucuda openssl rand -base64 32 komutunu kullanabilir ya da tarayıcıdan şifre üretici aracıyla üretebilirsiniz. Redis 6 ve sonrasında ise gerçek kullanıcı sistemi (ACL) vardır ve tek parola yerine bunu kullanmanızı öneririm. ACL ile her uygulamaya yalnızca ihtiyacı olan komutları ve anahtar kalıplarını verirsiniz:
# Varsayılan kullanıcıyı tamamen kapat
redis-cli ACL SETUSER default off
# Uygulama kullanıcısı: yalnızca "uygulama:" ile başlayan anahtarlar,
# yalnızca okuma-yazma komutları, tehlikeli sınıflar hariç
redis-cli ACL SETUSER uygulama on '>UygulamaParolasi123' \
'~uygulama:*' '+@read' '+@write' '+@string' '+@hash' '+@list' '+@set' \
'-@admin' '-@dangerous'
# Salt okunur rapor kullanıcısı
redis-cli ACL SETUSER rapor on '>RaporParolasi456' '~*' '+@read' '-@dangerous'
# Kontrol
redis-cli ACL LIST
redis-cli ACL GETUSER uygulama
ACL tanımlarını kalıcı hâle getirmek için ya redis-cli ACL SAVE çalıştırıp aclfile kullanmalı ya da CONFIG REWRITE ile yapılandırmaya yazmalısınız; aksi hâlde servis yeniden başladığında tanımlarınız kaybolur. Ayrı bir ACL dosyası kullanmak daha temizdir:
# redis.conf içinde
aclfile /etc/redis/users.acl
Uygulama tarafında bağlanırken artık kullanıcı adı da göndermeniz gerekir. redis-cli ile test:
redis-cli -u 'redis://uygulama:[email protected]:6379'
127.0.0.1:6379> ACL WHOAMI
"uygulama"
127.0.0.1:6379> SET uygulama:test 1
OK
127.0.0.1:6379> SET baska:test 1
(error) NOPERM this user has no permissions to access one of the keys used as arguments
Son satır, ACL'in işini yaptığını gösteren en güzel kanıttır. Başarısız yetkilendirme denemelerini redis-cli ACL LOG komutuyla görebilirsiniz; bu kayıt, sızma denemelerini fark etmenin en hızlı yoludur.
Tehlikeli Komutları Kısıtlamak#
Bazı komutlar, yetkili bir kullanıcının elinde bile kaza riski taşır. Aşağıdaki tablo en kritik olanları ve neden kısıtlanmaları gerektiğini özetliyor.
| Komut | Riski | Önerilen davranış |
|---|---|---|
FLUSHALL / FLUSHDB | Tüm veriyi tek satırda siler | Uygulama kullanıcısından kaldır |
CONFIG | Çalışma dizinini ve dosya adını değiştirir | Yalnızca yönetici kullanıcı |
KEYS | Tüm anahtar alanını tarar, sunucuyu kilitler | Kaldır, yerine SCAN |
DEBUG | Sunucuyu çökertebilir, bellek bozabilir | Tamamen kapat |
SHUTDOWN | Servisi durdurur | Yalnızca yönetici |
MONITOR | Tüm komutları sızdırır, yük bindirir | Yalnızca teşhis anında |
SCRIPT / EVAL | Rastgele Lua çalıştırır | İhtiyaç yoksa kapat |
REPLICAOF | Sunucuyu başkasının replikası yapar | Yalnızca yönetici |
ACL kullanıyorsanız bunları komut sınıflarıyla kapatmak en temiz yoldur; -@admin -@dangerous zaten çoğunu kapsar, kalanları tek tek ekleyebilirsiniz:
redis-cli ACL SETUSER uygulama '-flushall' '-flushdb' '-keys' '-config' '-debug' '-monitor'
ACL kullanamadığınız eski bir sürümdeyseniz klasik yöntem komutları yeniden adlandırmaktır:
# Boş dize vermek komutu tamamen kaldırır
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command DEBUG ""
# Yönetici için tahmin edilemez bir isme taşımak da mümkündür
rename-command CONFIG CONFIG_a7f2c91e4b
Bu yöntemi bir geçiş çözümü olarak görün: yeni sürümlerde ACL varken rename-command kullanmak, hem yönetimi zorlaştırır hem de bazı istemci kütüphanelerini bozar (birçok kütüphane bağlanırken CONFIG GET çağırır). Mümkünse ACL'e geçin.
TLS ile Şifreli Bağlantı#
Redis 6 ile birlikte TLS artık yerleşiktir; ayrı bir stunnel katmanına gerek yoktur. Uygulama sunucunuz Redis ile aynı özel ağda değilse ya da trafiğin geçtiği ağa tam güvenmiyorsanız TLS'i açın. Önce sertifikaları hazırlayın; iç ağ için kendi imzaladığınız bir CA yeterlidir, dışa açık bir uç nokta için gerçek bir sertifika kullanın:
# Basit bir iç CA ve sunucu sertifikası
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
-subj "/CN=Redis Ic CA" -out ca.crt
openssl genrsa -out redis.key 2048
openssl req -new -key redis.key -subj "/CN=redis.firmaniz.com" -out redis.csr
openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out redis.crt -days 825 -sha256
sudo install -o redis -g redis -m 640 redis.key /etc/redis/tls/redis.key
sudo install -o redis -g redis -m 644 redis.crt ca.crt /etc/redis/tls/
Ardından yapılandırmayı güncelleyin. Buradaki kritik satır port 0; şifresiz portu kapatmazsanız TLS yalnızca isteğe bağlı bir seçenek olarak kalır ve eski istemciler şifresiz bağlanmaya devam eder:
# Şifresiz portu tamamen kapat
port 0
tls-port 6379
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
# İstemcinin de sertifika sunmasını zorunlu kıl (karşılıklı TLS)
tls-auth-clients yes
# Eski protokol sürümlerini kapat
tls-protocols "TLSv1.2 TLSv1.3"
Bağlantıyı test ederken redis-cli de TLS bayraklarını almalıdır:
redis-cli --tls \
--cert /etc/redis/tls/istemci.crt \
--key /etc/redis/tls/istemci.key \
--cacert /etc/redis/tls/ca.crt \
-h redis.firmaniz.com -p 6379 PING
# PONG
Bir uyarı: TLS desteği paketin nasıl derlendiğine bağlıdır. Dağıtımınızın paketi TLS'siz derlenmişse tls-port satırıyla servis başlamaz ve günlükte açık bir hata verir. Bu durumda resmî Redis deposundan kurulum yapmanız gerekir. TLS'in yaklaşık yüzde beş ile on arası ek işlemci maliyeti getirdiğini de hesaba katın; çok yüksek işlem hacimlerinde bunu ölçerek karar verin.
Dosya İzinleri, Bellek Sınırı ve Servis Sıkılaştırma#
Yapılandırma dosyanız artık parola içeriyor; okuma izinleri buna göre olmalı. Ayrıca veri dizini yalnızca Redis kullanıcısına ait olmalıdır:
# Yapılandırma: root sahibi, redis grubu okuyabilir, başkası okuyamaz
sudo chown root:redis /etc/redis/redis.conf
sudo chmod 640 /etc/redis/redis.conf
# Veri dizini yalnızca redis kullanıcısına açık
sudo chown -R redis:redis /var/lib/redis
sudo chmod 750 /var/lib/redis
# Doğrulama
ls -ld /etc/redis/redis.conf /var/lib/redis
Bellek sınırı da bir güvenlik konusudur: sınırsız Redis, sunucunun tüm belleğini tüketip OOM killer'ın devreye girmesine ve başka servislerin ölmesine yol açabilir. Toplam belleğin yaklaşık dörtte üçünü aşmayan bir sınır koyun ve bir çıkarma politikası belirleyin:
# Örnek: 8 GB RAM'li sunucuda 4 GB sınır
maxmemory 4gb
# Önbellek kullanımı için uygun politika; kalıcı veri tutuyorsanız noeviction seçin
maxmemory-policy allkeys-lru
Son olarak systemd birim dosyasına birkaç sıkılaştırma direktifi ekleyin. Debian/Ubuntu paketlerinde bunların bir kısmı zaten gelir, systemctl cat redis-server ile kontrol edin ve eksikleri bir üstyapı (override) dosyasıyla tamamlayın:
sudo systemctl edit redis-server
[Service]
# Dosya sistemine yazmayı sınırla
ProtectSystem=full
PrivateTmp=yes
NoNewPrivileges=yes
ProtectHome=yes
# Yalnızca veri dizinine yazabilsin
ReadWritePaths=/var/lib/redis
Bu direktifler, Redis süreci bir şekilde ele geçirilse bile saldırganın dosya sistemine yazma alanını daraltır — yani rehberin başında anlattığım SSH anahtarı yazma saldırısını doğrudan engeller. Bu tür sistemsel sıkılaştırmayı tüm servisleriniz için tek tek yapmak istemiyorsanız sunucu yönetimi hizmetimiz bu işi standart bir prosedüre bağlar.
Sunucunuz Ele Geçirilmiş mi: Kontrol Listesi#
Redis'i uzun süre açık bıraktıysanız, sıkılaştırmadan önce mevcut durumu denetlemekte fayda var. Aşağıdaki adımlar birkaç dakika sürer ve bilinen saldırı izlerini yakalar.
- Şüpheli anahtarları arayın. Otomatik saldırı araçları genellikle
backup1,backup2,backup3,crackitgibi isimler bırakır.
redis-cli --scan --pattern '*' | head -50
redis-cli --scan --pattern 'backup*'
redis-cli --scan --pattern 'crackit*'
- Kalıcılık ayarlarının değiştirilip değiştirilmediğine bakın. Çalışma dizini
/var/lib/redisdışında bir yeri gösteriyorsa alarm zilleri çalsın.
redis-cli CONFIG GET dir
redis-cli CONFIG GET dbfilename
- SSH anahtarlarını ve cron görevlerini denetleyin. Tanımadığınız bir anahtar ya da görev varsa sunucu ele geçirilmiştir.
sudo cat /root/.ssh/authorized_keys
sudo crontab -l
sudo ls -la /var/spool/cron/crontabs/
sudo cat /etc/cron.d/* 2>/dev/null
- Beklenmeyen süreçleri ve giden bağlantıları arayın. Kripto madencileri yüksek işlemci kullanır ve bilinmeyen adreslere bağlanır.
ps aux --sort=-%cpu | head -10
sudo ss -tunap | grep ESTAB
- Kimlik doğrulama günlüklerine bakın. Redis günlüğünde art arda gelen hatalı
AUTHdenemeleri, birinin kapıyı zorladığını gösterir.
sudo journalctl -u redis-server --since "7 days ago" | grep -iE 'auth|denied|error'
redis-cli ACL LOG 20
Bu kontrollerden herhangi biri kirli çıkarsa, en güvenli yol sunucuyu sıfırdan kurmak ve veriyi temiz bir yedekten geri yüklemektir; ele geçirilmiş bir sistemi temizlediğinizden asla tam emin olamazsınız. Düzenli ve sunucudan bağımsız bir kopya için yedekleme hizmetimiz tam da bu durumlar için vardır.
Sıkça Sorulan Sorular#
Redis'e şifre koymak zorunlu mu#
Pratik olarak evet. bind 127.0.0.1 ile dışarıya kapatmış olsanız bile, aynı sunucudaki başka bir uygulama ele geçirildiğinde Redis'iniz savunmasız kalır. Parola ya da ACL kullanıcısı, bu "yanal hareket" riskini kesen en ucuz önlemdir. Parolayı uzun ve rastgele seçin; Redis saniyede yüz binlerce komut işleyebildiği için kısa bir parola kaba kuvvet saldırısına dakikalar içinde teslim olur.
requirepass ile ACL arasındaki fark nedir#
requirepass tek bir parola tanımlar ve o parolayı bilen herkes her komutu çalıştırabilir. ACL ise Redis 6 ile gelen gerçek kullanıcı sistemidir: her kullanıcıya ayrı parola, erişebileceği anahtar kalıpları ve çalıştırabileceği komut sınıfları verirsiniz. Üretimde ACL kullanmak açık ara daha iyidir, çünkü uygulamanın ele geçirilmesi durumunda saldırgan yalnızca o uygulamanın yetkileriyle sınırlı kalır.
Redis portunu değiştirmek güvenlik sağlar mı#
Tek başına gerçek bir güvenlik önlemi değildir, çünkü port taraması saniyeler sürer. Ancak internet üzerindeki otomatik botların büyük çoğunluğu yalnızca 6379'u tarar, dolayısıyla portu değiştirmek günlüklerinizdeki gürültüyü belirgin biçimde azaltır. Bunu bir ek konfor olarak düşünün; asıl korumayı bind, güvenlik duvarı ve kimlik doğrulama sağlar.
Redis'i internete açmam gerekiyorsa ne yapmalıyım#
Mümkünse yapmayın; uygulama ile Redis arasına özel ağ ya da VPN koymak her zaman daha iyidir. Zorunluysa üç şeyi birlikte uygulayın: yalnızca bilinen kaynak IP'lere izin veren bir güvenlik duvarı kuralı, karşılıklı TLS (tls-auth-clients yes) ve dar yetkili bir ACL kullanıcısı. Ayrıca CONFIG, DEBUG, SCRIPT gibi komutları bu kullanıcıdan tamamen kaldırın.
Şifreyi değiştirdikten sonra uygulamalarım neden bağlanamıyor#
CONFIG SET requirepass ile yapılan değişiklik anında etkili olur ve mevcut bağlantılar kopmaz, ama yeni bağlantılar parola ister. Uygulama yapılandırmasını güncellemeyi unuttuysanız hata NOAUTH Authentication required biçiminde gelir. Ayrıca CONFIG SET ile yapılan değişiklik yeniden başlatmada kaybolur; kalıcı olması için CONFIG REWRITE çalıştırmanız ya da doğrudan yapılandırma dosyasını düzenlemeniz gerekir.
Redis günlüklerinde saldırı izlerini nasıl kontrol ederim#
Üç kaynağa bakın. Birincisi redis-cli ACL LOG, başarısız kimlik doğrulama ve yetki ihlallerini kaydeder. İkincisi servis günlüğüdür; journalctl -u redis-server çıktısında art arda gelen AUTH hataları ya da beklenmeyen REPLICAOF satırları şüphelidir. Üçüncüsü veritabanının kendisidir: redis-cli --scan ile tanımadığınız anahtar kalıpları arayın ve CONFIG GET dir çıktısının hâlâ normal veri dizinini gösterdiğini doğrulayın.
Kapanış#
Redis güvenliği tek bir ayara değil, üst üste binen birkaç katmana dayanır. Aklınızda kalması gereken pratik alışkanlıklar şunlar: kurulumdan hemen sonra bind ve güvenlik duvarını kapatın, requirepass yerine dar yetkili ACL kullanıcıları tanımlayın, FLUSHALL ve CONFIG gibi komutları uygulama kullanıcısından kaldırın, veri dizini ile yapılandırma dosyasının izinlerini sıkın ve maxmemory sınırı koyarak sunucunun tamamını riske atmayın. Ağ güvenilmezse TLS ekleyin, güvenilirse bile parolayı asla atlamayın.
Bu adımların tamamını her yeni sunucuda elle uygulamak zahmetliyse, kurulum ve sıkılaştırmayı standart bir prosedüre bağlamak en iyisidir. Tam root erişimiyle kendi Redis örneğinizi kurmak isterseniz VDS ve bulut sunucu paketlerimiz uygun bir zemin sağlar; işletim ve güncelleme yükünü devretmek isterseniz sunucu yönetimi, veri kaybı riskine karşı ise yedekleme hizmetimiz devreye girer.