Dosyalar .locked uzantısıyla belirmiş, masaüstünde bir README.txt var ve aklına gelen ilk şey şu: "Yedekten geri döneyim." İşte tam o anda yedek sürücüsünün de aynı sunucuya mount edildiğini ve şifrelendiğini fark ediyorsun. Bu makale tam o an hakkında; yedeğin önemli olduğu hakkında değil.
Güvenli bir yedek için üç şeyin aynı anda doğru olması gerekir: ağın erişemeyeceği bir sürüm, root erişimiyle bile saklama süresi boyunca değiştirilemeyen bir sürüm ve son 90 gün içinde gerçekten çalıştırılmış bir geri yükleme. Bu üçünden biri yoksa gerisi süslemedir.
Aynı ağdaki yedek neden yedek değildir
Günümüz fidye yazılımları şifrelemeden önce ilk olarak yedek hedefini arar. Script'leri mount point'leri, ~/.aws/credentials içinde saklanan kimlik bilgilerini, restic yapılandırmasını ve .env dosyalarındaki parolaları okur. Yedek sunucusu aynı SSH anahtarı veya aynı S3 token'ı ile erişilebilirse, saldırgan tam olarak senin script'inin yaptığını yapar: önceki sürümü siler, yeni sürümü şifreler.
Belirtisi her zaman geç fark edilir. Yedek sunucusunun log'u başarılı job'larla doludur, dashboard yeşildir ve ancak restore etmek istediğinde son yedi günün snapshot'larının hepsinin sıfır byte veya şifrelenmiş olduğunu görürsün. Burada hata yapılır: "job başarılı"nın "yedek sağlam" anlamına geldiği varsayılır. Başarılı job, dosyanın taşındığı anlamına gelir; içeriği hakkında hiçbir şey söylemez.
Gerçek test, kontrol listesi değil
Ayda bir kez, ayrı bir makinede en son snapshot'ı restore et ve belirli bir dosyayı aç. Not etmen gereken sayı iki şeydir: ilk sağlam byte'a kadar geçen süre ve checksum'ı kaynakla uyuşmayan dosya sayısı. Bunu yapmadıysan test edilmemiş yedeğin var demektir ve test edilmemiş yedek yedek değildir.
restic -r s3:s3.example.com/bucket restore latest \
--target /tmp/restore-test --include /var/www/html/index.php
sha256sum /tmp/restore-test/var/www/html/index.php
Değiştirilemez sürüm: immutability nasıl gerçekten uygulanır
"Değiştirilemez", saklama süresi boyunca hiç kimsenin — admin anahtarına sahip sen dahil — objeyi silememesi veya üzerine yazamaması anlamına gelir. Üç pratik yol vardır ve aralarındaki seçim bütçeye ve acıya tahammül seviyesine bağlıdır.
| Yöntem | Nasıl çalışır | Gerçek maliyet |
|---|---|---|
| S3'te Object Lock | Compliance modu, örneğin 30 gün retention | Süre bitene kadar admin bile silemez; alan serbest kalmaz |
| Döngüsel çevrimdışı sürücü | Haftalık disk takılır, sync edilir, çıkarılır, kasaya konur | Manuel ve unutulur |
| Pull-only yedek sunucusu | Yedek sunucusu kaynağa bağlanır, tersi değil | SSH yapılandırması ve ayrı anahtar gerektirir |
Birini seçmek zorunda kalsam, üretim siteleri için Compliance modunda Object Lock'u seçerim, çünkü otomatiktir ve insan hafızasına bağlı değildir. Governance modunu seçmem; o modda s3:BypassGovernanceRetention iznine sahip herkes kilidi açabilir ve o erişim tam olarak saldırganın aradığı şeydir.
SSH ile pull-only deseni
Bu desende yedek sunucusunun anahtarı vardır ve üretim sunucusuna bağlanır. Üretim sunucusunun yedeğe yazmak için hiçbir anahtarı yoktur. Saldırgan üretim sunucusunda root olursa yedek hedefini görmez.
# Yedek sunucusunda, /etc/ssh/sshd_config içinde kaynak:
Match User backupuser
AllowTcpForwarding no
PermitOpen none
# Yedek sunucusunda, günlük cron:
rsync -a --delete --link-dest=/backup/current \
backupuser@prod:/var/www/html/ /backup/$(date +\%F)/
İnce nokta: --link-dest alanı azaltır ama kaynak dosyanın üzerine yazarsa eski sürüm el değmemiş kalır. Şifreleme saldırısında seni kurtaran tam olarak budur.
Veritabanı yedeği: en çok bozulmanın yaşandığı yer
Çalışan bir veritabanında /var/lib/mysql dosyalarını kopyalamak, restore anına kadar sağlam görünen bozuk bir yedek üretir. MySQL için mantıksal dump almalı ve checksum ile doğrulamalısın.
mysqldump --single-transaction --quick --routines --triggers \
--all-databases | gzip > /backup/db-$(date +\%F).sql.gz
gzip -t /backup/db-$(date +\%F).sql.gz && echo OK
--single-transaction flag'i yalnızca InnoDB'de anlamlıdır. MyISAM tablon varsa bu flag kilit almaz ve dump tutarsız olur; orada --lock-tables koymalı ve bakım pencereni kısaltmalısın. Bu, dokümantasyonda az görülen trade-off'un ta kendisidir.
Yedek şifreleme ve anahtar yönetimi
Bulut alanında şifrelenmemiş yedek, bucket sızarsa her şey sızmış demektir. Ama şifrelemenin de tuzağı var: anahtarı nerede tutuyorsun? Anahtar yedeğin yanındaysa şifreleme sadece süs bir katmandır. Anahtar başka bir yerde, bir ekip password manager'ında veya KMS'de olmalı ve en az iki kişinin erişiminde olmalıdır.
restic ve borg için parolayı ayrı bir dosyadan oku ve o dosyayı yedeğe koyma:
export RESTIC_PASSWORD_FILE=/etc/restic/pass
restic -r s3:... backup /var/www --exclude-caches
Anahtarı kaybedersen yedek sonsuza kadar kurtarılamaz. Bunu runbook'a yaz, aklına değil.
3-2-1 kuralı ve çevrimdışı sürüm
Üç sürüm, iki farklı ortam, bir site dışı sürüm. Çevrimdışı sürüm, en kötü senaryoda seni kurtaran şeydir: saldırganın hem üretim sunucusunda hem de bulut hesabında erişim elde ettiği durumda. Haftada bir takılan ve sonra fiziksel olarak ayrılan bir NVMe veya HDD diski, herhangi bir yazılım ayarından daha güçlüdür, çünkü takılı olmayan bir diske ağ saldırısı mümkün değildir.
Maliyetini de söyleyeyim: bu yöntem manueldir ve pratikte unutulur. Benim çözümüm bunu takvim hatırlatıcısı olan bir kişiye emanet etmek ve her seferin sonucunu tarihle birlikte bir log dosyasına kaydetmek. Kimse kaydetmediyse o hafta çevrimdışı yedek yoktur.
İzleme: bir olaydan önce yedeğin bozuk olduğunu nasıl anlarsın
Üç sinyali izle. Birincisi, son başarılı snapshot'ın yaşı; 26 saati geçtiyse uyarı ver. İkincisi, snapshot boyutu; örneğin 40 gigabayttan 2 gigabayta ani düşüş, kaynakta bir şeyin bozuk olduğu anlamına gelir. Üçüncüsü, aylık test restore'unun sonucu.
Küçük bir script yeterli:
restic snapshots --json | jq -r '.[-1].time'
Çıktı 24 saatten eskiyse cron'da uyarı gönder. Ağ yolunu ve erişimleri kontrol etmek için de DNS ve ağ kontrol araçlarını kullanarak yedek hedefinin dışarıdan erişilebilir olmadığından emin olabilirsin.
Erişimler: yedek yalnızca en az yetkiyle
Yedek alan hesap silememelidir. S3'te policy'yi yalnızca PutObject ve ListBucket'a izin verecek ve DeleteObject'i açıkça reddedecek şekilde yaz. Sunucuda yedek kullanıcısı sudo grubunun üyesi olmamalı ve tercihen chroot veya ayrı bir container'da çalıştırılmalıdır.
Kendi altyapında çalışıyorsan, yedek ağını üretim ağından ayırmak en etkili işlerden biridir. Yedek sunucusunda ağ katmanı ve kötü niyetli trafiğe karşı da DDoS korumasını ciddiye al; dışarıdan görünen bir yedek sunucusu iyi bir hedeftir.
Yanı sıra, denetim log'unu el değmemiş tut. Bir gün snapshot'ların silindiğini fark edersen ilk sorun şu olur: "Kim ve nereden?" Log olmadan cevabın yok. Doğru saklanması hakkında denetim log'u ve onu el değmemiş tutma yöntemi yazısında yazdık.
Geri yükleme: gerçekten işe yarayan tatbikat
Geri yüklemeyi üretimle hiçbir bağlantısı olmayan bir ortamda çalıştır. İş sırası: önce veritabanı, sonra dosyalar, sonra yapılandırmalar ve anahtarlar. Sırayı ters çevirirsen site açılır ama verisi olmaz ve bu en kötü durumdur, çünkü başarılı olduğunu sanırsın.
- Aynı OS sürümü ve aynı MySQL sürümüyle yeni bir makine kur.
- Dump'ı restore et ve üç ana tablonun kayıt sayısını üretimle karşılaştır.
- Dosyaları restore et ve rastgele on dosyanın checksum'ını al.
- Siteyi geçici DNS ile ayağa kaldır ve gerçek bir işlem test et.
- Toplam süreyi kaydet; bu sayı senin gerçek RTO'n, belgeye yazdığın sayı değil.
Geri yükleme süresi işletmenin tahammülünden fazlaysa sorun yedek değil, mimaridir. Orada hazır replica veya daha hızlı snapshot'ları düşünmelisin.
Sürekli tekrarlanan hatalar
- Yedek parolasını üretim sunucusundaki aynı script'in içinde tutmak.
- Retention'ı ihlal tespit süresinden kısa tutmak; 7 gün saklar ve saldırı 20 gün önce başlamışsa sağlam sürümün yoktur.
- Kendisi başka bir yere symlink olan bir yoldan yedek almak ve yanlış dosyaların restore edilmesi.
- Tek sürüm olarak provider snapshot'larına güvenmek; snapshot da hesap silinince yok olur.
WordPress üzerinde çalışıyorsan, saldırı yüzeyinin bir kısmı uygulamanın kendisidir. Kullanıcı sızıntısı yollarını kapatmayı WordPress REST API güvenliği ve genel sıkılaştırmayı wp-config'ten eklentilere WordPress güvenliği yazılarında ayrıca oku; zaten açık bir site üzerindeki iyi yedek yalnızca olayın tarihini geriye atar.
Ve sunucunun yönetim erişimi dışarıdan açıksa, her şeyden önce onu kapat: port değiştirmekten fail2ban ve açık anahtara SSH güvenliği.
Sık sorulan sorular
Bulut snapshot'ı güvenli yedek için yeterli mi?
Hayır, tek sürümse. Snapshot genellikle aynı hesapta ve aynı kontrol düzlemindedir; hesaba erişim elde eden bir saldırgan onu silebilir. Snapshot'ı hız katmanı olarak tut, ama en az bir değiştirilemez veya ayrı çevrimdışı sürümün olsun.
Immutable backup ne demek ve nasıl etkinleştirilir?
Saklama süresi boyunca objenin silinmesi veya üzerine yazılması mümkün değil demektir. S3'te Object Lock ve retention mode belirleyerek etkinleştirilir. Compliance modunu seç, çünkü Governance modunda bypass izni olan herkes kilidi açabilir.
Geri yüklemeyi ne sıklıkla test etmeliyim?
En az ayda bir kez bir dosya için ve her üç ayda bir kez ayrı ortamda tam geri yükleme için. Aylık test hızlıdır ve erken başarısızlıkları gösterir; üç aylık test gerçek RTO süresini ortaya koyar.
Şifrelenmiş yedek anahtar kaybolursa ne olur?
Sonsuza kadar kurtarılamaz hale gelir; etrafından dolaşmanın yolu yoktur. Bu yüzden anahtarı yedekten ayrı bir yerde, en az iki kişinin erişiminde ve kasada bir basılı kopyayla sakla.
Bugün yapabileceğin şey şu: bir snapshot'ı ayrı bir makinede restore et ve süresini yaz. Sonuç vermiyorsa geri kalan tartışmalar boşunadır.
Yorumlar 0
Henüz yorum yok — ilk siz olun!