Arşivleme İşlemlerinde Checksuma Dayalı Değişiklik Tespiti: sha256sum ve Manifest Dosyası ile Yedek Tutarlılığını Garantileme
Yıllar önce bir müşterinin sunucusundaki yedekleme sistemini incelediğimde şunu fark ettim: Sistem her gece düzenli olarak arşiv oluşturuyordu, log dosyaları “başarılı” yazıyordu, ama kimse o arşivlerin gerçekten sağlam olup olmadığını test etmemişti. Ta ki bir geri yükleme ihtiyacı çıkana kadar. O gün bozuk çıkan arşiv sayısı üçtü. Üç aydır bozuk arşiv alınıyordu ve kimsenin haberi yoktu. İşte bu yazı tam olarak o acı deneyimin ürünü.
Sorun: “Yedek Var” ile “Yedek Çalışır” Arasındaki Uçurum
Bir arşiv dosyasının var olması onun kullanılabilir olduğu anlamına gelmiyor. Disk hataları, ağ transferleri sırasında oluşan bozulmalar, yarım kalan yazma işlemleri, hatta bazen yazılım hataları arşivleri sessizce bozabiliyor. tar komutunuz çalışıyor, gzip sıkıştırma tamamlanıyor, ama sonuçta elinizde ne var? Bunu bilmiyorsanız yedeklemeden bahsedemezsiniz, sadece dosya kopyalamadan bahsedebilirsiniz.
Checksum tabanlı doğrulama bu sorunun cevabı. SHA-256, bir dosyanın içeriğini matematiksel olarak parmak izine çeviriyor. Dosyada tek bir bit değişse bile hash tamamen farklı bir değer üretiyor. Bu özelliği kullanarak arşiv oluşturma anında bir “parmak izi” alıyorsunuz, ve sonradan o arşivi kullandığınızda aynı parmak izini tekrar hesaplayıp karşılaştırıyorsunuz. Eşleşiyorsa arşiv sağlam. Eşleşmiyorsa elinizdeki arşiv zaten çöp, bunu öğrenmek için geri yükleme felaketini beklemenize gerek yok.
SHA-256 ve sha256sum Komutuna Hızlı Bakış
sha256sum komutu Linux sistemlerde genellikle coreutils paketiyle birlikte geliyor ve hemen hemen her dağıtımda hazır bulunuyor. Temel kullanımı son derece basit:
sha256sum yedek_2024.tar.gz
Çıktı şu formatta geliyor:
a3f8d2c1e9b7... yedek_2024.tar.gz
İki sütun: önce hash değeri, sonra dosya adı. Bu kadar. Ama işin püf noktası bu çıktıyı nasıl kullandığınızda saklı.
Birden fazla dosyanın checksum’ını tek seferde hesaplamak için:
sha256sum *.tar.gz > manifest.sha256
Bu komut, mevcut dizindeki tüm .tar.gz dosyalarının hash değerlerini manifest.sha256 adlı bir dosyaya yazıyor. Sonradan bu dosyayı kullanarak tüm arşivleri tek komutla doğrulayabiliyorsunuz:
sha256sum -c manifest.sha256
Çıktı her dosya için OK ya da FAILED yazıyor. Basit, etkili, güvenilir.
Manifest Dosyası Konsepti: Ne, Neden, Nasıl
Manifest dosyası aslında bir doğrulama listesi. Her satırda bir arşiv dosyasının hash değeri ve adı var. Bu dosyayı arşivlerinizle birlikte saklıyorsunuz ve her doğrulama işleminde referans alıyorsunuz.
Ama burada kritik bir nokta var: Manifest dosyasını arşivle aynı konuma koymak çoğu zaman yeterli değil. Eğer depolama ortamı bozulduysa hem arşiv hem manifest bozulabilir. İdeal senaryoda manifest dosyasını farklı bir konumda, hatta farklı bir sunucuda tutmanız gerekiyor.
Gerçek dünya senaryosu olarak şunu düşünelim: Bir e-ticaret şirketinin veritabanı yedekleme sistemi. Her gece 03:00’da tam yedek alınıyor, her saat başı artımlı yedek. Günlük onlarca arşiv dosyası oluşuyor. Bu dosyaların hepsini manuel kontrol etmek imkansız. Ama manifest tabanlı bir sistem kurarsanız, sabah 08:00’de işe geldiğinizde tek bir komutla tüm gecenin yedeklerinin sağlıklı olup olmadığını öğrenebilirsiniz.
Pratikte Arşiv Oluşturma ve Manifest Üretme
Gerçek bir senaryo üzerinden gidelim. PostgreSQL veritabanı yedeklerini arşivleyip doğruladığımız bir örnek:
#!/bin/bash
# db_backup.sh - Veritabanı yedekleme ve manifest oluşturma scripti
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="db_full_${DATE}.tar.gz"
MANIFEST_FILE="manifest_${DATE}.sha256"
LOG_FILE="/var/log/backup/backup_${DATE}.log"
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname $LOG_FILE)"
echo "[$(date)] Yedekleme başlıyor..." >> "$LOG_FILE"
# Veritabanı dump al
pg_dumpall | gzip > "${BACKUP_DIR}/${BACKUP_FILE}"
if [ $? -ne 0 ]; then
echo "[$(date)] HATA: pg_dumpall başarısız!" >> "$LOG_FILE"
exit 1
fi
echo "[$(date)] Dump tamamlandı, checksum hesaplanıyor..." >> "$LOG_FILE"
# SHA-256 hesapla ve manifest oluştur
cd "$BACKUP_DIR"
sha256sum "$BACKUP_FILE" > "$MANIFEST_FILE"
echo "[$(date)] Manifest oluşturuldu: $MANIFEST_FILE" >> "$LOG_FILE"
# Hemen doğrulama yap
sha256sum -c "$MANIFEST_FILE" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "[$(date)] Doğrulama başarılı. Yedek sağlam." >> "$LOG_FILE"
else
echo "[$(date)] KRITIK: Doğrulama başarısız! Yedek bozuk!" >> "$LOG_FILE"
# Burada alert gönder
exit 2
fi
Bu script’te dikkat edin: Arşivi oluşturduktan hemen sonra checksum hesaplanıyor ve hemen doğrulama yapılıyor. Bu adım gereksiz görünebilir ama değil. Dosya sistemi buffering’i nedeniyle bazen arşiv diske tam yazılmadan checksum hesaplanabiliyor. Bu hemen-doğrulama adımı hem bunu yakalıyor hem de ileriki doğrulamalar için referans hash’in doğru olduğunu garanti ediyor.
Çoklu Arşiv Senaryosu ve Toplu Manifest
Büyük sistemlerde tek bir arşiv değil, onlarca arşiv oluşturulabiliyor. Haftalık yedekleme sistemleri için şu yaklaşımı kullanıyorum:
#!/bin/bash
# weekly_backup_with_manifest.sh
BACKUP_ROOT="/backup/weekly"
WEEK=$(date +%Y_W%V)
WEEK_DIR="${BACKUP_ROOT}/${WEEK}"
MANIFEST="${WEEK_DIR}/MANIFEST.sha256"
mkdir -p "$WEEK_DIR"
# Farklı bileşenleri ayrı arşivlere al
declare -A COMPONENTS
COMPONENTS["db"]="/var/lib/postgresql"
COMPONENTS["config"]="/etc"
COMPONENTS["webroot"]="/var/www"
COMPONENTS["logs"]="/var/log/app"
for component in "${!COMPONENTS[@]}"; do
source_dir="${COMPONENTS[$component]}"
archive="${WEEK_DIR}/${component}_${WEEK}.tar.gz"
echo "Arşivleniyor: $component -> $archive"
tar czf "$archive"
--exclude='*.pid'
--exclude='*.sock'
"$source_dir" 2>/dev/null
# Her arşiv için checksum ekle
sha256sum "$archive" >> "$MANIFEST"
echo "$component arşivi eklendi: $(tail -1 $MANIFEST)"
done
echo ""
echo "=== Haftalık Manifest Oluşturuldu ==="
cat "$MANIFEST"
echo ""
echo "=== Toplu Doğrulama ==="
cd "$WEEK_DIR"
sha256sum -c MANIFEST.sha256
Bu yapıda manifest dosyası haftanın tüm arşivlerini kapsıyor. Sabah kontrol rutinine şunu ekliyorsunuz:
cd /backup/weekly/$(date +%Y_W%V)
sha256sum -c MANIFEST.sha256 && echo "TUM YEDEKLER SAGLIKLI" || echo "DIKKAT: BOZUK YEDEK VAR"
Uzak Sunucuya Transfer Sonrası Doğrulama
Arşivleri ağ üzerinden başka bir sunucuya veya bulut depolamaya gönderdiğinizde checksum doğrulaması kritik önem kazanıyor. Ağ transferleri sırasında veri bozulması nadir ama mümkün. rsync kullanıyorsanız zaten bir ölçüde korunuyorsunuz ama ekstra güvence için şu yaklaşımı öneriyorum:
#!/bin/bash
# transfer_and_verify.sh
SOURCE_DIR="/backup/postgresql"
REMOTE_USER="backup"
REMOTE_HOST="backup-server.internal"
REMOTE_DIR="/mnt/backup-storage/postgresql"
MANIFEST="manifest_$(date +%Y%m%d).sha256"
# Önce local manifest oluştur
cd "$SOURCE_DIR"
sha256sum *.tar.gz > "$MANIFEST"
echo "Local manifest oluşturuldu:"
cat "$MANIFEST"
# rsync ile transfer et (arşivler + manifest)
rsync -avz --progress
--checksum
"${SOURCE_DIR}/"
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"
if [ $? -ne 0 ]; then
echo "Transfer hatası!"
exit 1
fi
# Uzak sunucuda doğrulama yap
echo ""
echo "=== Uzak sunucuda doğrulama yapılıyor ==="
ssh "${REMOTE_USER}@${REMOTE_HOST}" "cd ${REMOTE_DIR} && sha256sum -c ${MANIFEST}"
if [ $? -eq 0 ]; then
echo "Transfer ve doğrulama başarılı."
else
echo "KRITIK: Uzak sunucudaki dosyalar bozuk veya eksik!"
exit 2
fi
Burada rsync --checksum parametresine dikkat edin. Rsync normalde dosya boyutu ve değişiklik zamanına bakarak karar veriyor. --checksum eklenince her dosyayı gerçekten karşılaştırıyor. Transfer süresi uzuyor ama bütünlük garantisi çok daha sağlam oluyor.
Otomatik Doğrulama ve Uyarı Sistemi
Manuel kontrol yapmak yetmez. Sistemin kendisi sorunları tespit edip sizi uyarmalı. Cron ile çalışan basit ama etkili bir doğrulama scripti:
#!/bin/bash
# verify_backups.sh - Cron ile her sabah 07:00'de çalışır
BACKUP_DIR="/backup"
ALERT_EMAIL="[email protected]"
HOSTNAME=$(hostname -f)
ISSUES=()
SUCCESS_COUNT=0
FAIL_COUNT=0
# Son 24 saatte oluşturulan manifest dosyalarını bul
find "$BACKUP_DIR" -name "*.sha256" -newer "$BACKUP_DIR" -mtime -1 | while read manifest; do
manifest_dir=$(dirname "$manifest")
manifest_name=$(basename "$manifest")
cd "$manifest_dir"
result=$(sha256sum -c "$manifest_name" 2>&1)
if echo "$result" | grep -q "FAILED"; then
FAIL_COUNT=$((FAIL_COUNT + 1))
failed_files=$(echo "$result" | grep "FAILED")
ISSUES+=("HATA - $manifest_dir: $failed_files")
# Anında e-posta gönder
echo -e "Sunucu: $HOSTNAMEnManifest: $manifestnSorun:n$result" |
mail -s "[KRITIK] Yedek Doğrulama Hatası - $HOSTNAME" "$ALERT_EMAIL"
else
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
fi
done
echo "Doğrulama tamamlandı. Başarılı: $SUCCESS_COUNT, Başarısız: $FAIL_COUNT"
Bu scripti crontab’a eklemek için:
# crontab -e
0 7 * * * /usr/local/bin/verify_backups.sh >> /var/log/backup/verify.log 2>&1
Arşiv Boyutu ve Hash’i Birlikte Kaydetme
Sadece hash değil, dosya boyutunu da kaydetmek iyi bir pratik. Boyut tutarsızlığı bazen hash hesaplanmadan önce bir şeylerin yanlış gittiğini gösteriyor:
#!/bin/bash
# enhanced_manifest.sh - Boyut + Hash manifest
create_manifest() {
local dir="$1"
local manifest="$2"
cd "$dir"
# Manifest header
echo "# Backup Manifest" > "$manifest"
echo "# Generated: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> "$manifest"
echo "# Hostname: $(hostname -f)" >> "$manifest"
echo "# ---" >> "$manifest"
for archive in *.tar.gz *.tar.bz2 *.tar.xz; do
[ -f "$archive" ] || continue
size=$(stat -c%s "$archive")
hash=$(sha256sum "$archive" | awk '{print $1}')
modified=$(stat -c%Y "$archive")
echo "FILE:$archive SIZE:$size MTIME:$modified SHA256:$hash" >> "$manifest"
echo "Eklendi: $archive ($((size / 1024 / 1024)) MB)"
done
echo "# EOF" >> "$manifest"
}
# Kullanım
create_manifest "/backup/postgresql" "/backup/postgresql/enhanced_manifest.txt"
cat /backup/postgresql/enhanced_manifest.txt
Bu gelişmiş manifest formatı standart sha256sum -c ile doğrudan çalışmıyor ama size çok daha fazla bilgi sunuyor. İki yaklaşımı paralel kullanmak mantıklı: standart sha256sum çıktısı otomatik doğrulama için, gelişmiş format ise audit ve sorun analizi için.
Eski Yedekleri Temizlerken Manifest Güncellemesi
Yedek rotasyonu yaparken manifest dosyalarını da güncellemeyi unutmayın. Aksi takdirde manifest eski dosyalara referans veriyor ve doğrulama hep başarısız görünüyor:
#!/bin/bash
# rotate_and_update_manifest.sh
BACKUP_DIR="/backup/postgresql"
KEEP_DAYS=30
MANIFEST="${BACKUP_DIR}/CURRENT_MANIFEST.sha256"
# Eski yedekleri sil
echo "30 günden eski yedekler siliniyor..."
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$KEEP_DAYS -delete
# Silinen dosyaların manifest kayıtlarını da kaldır
if [ -f "$MANIFEST" ]; then
tmp_manifest=$(mktemp)
while IFS= read -r line; do
filename=$(echo "$line" | awk '{print $2}')
if [ -f "${BACKUP_DIR}/${filename}" ]; then
echo "$line" >> "$tmp_manifest"
else
echo "Manifest'ten kaldırıldı: $filename"
fi
done < "$MANIFEST"
mv "$tmp_manifest" "$MANIFEST"
echo "Manifest güncellendi."
fi
# Güncel durumu göster
echo ""
echo "=== Mevcut Yedekler ve Durumları ==="
cd "$BACKUP_DIR"
sha256sum -c CURRENT_MANIFEST.sha256
Sık Yapılan Hatalar ve Dikkat Edilmesi Gerekenler
Yıllar içinde gördüğüm ve benim de düştüğüm hatalar:
- Relative vs absolute path sorunu:
sha256sumçalıştırırken hangi dizinde olduğunuza dikkat edin. Manifestyedek.tar.gzdiye kaydettiyse doğrulama da aynı dizinden yapılmalı. Absolute path kullandığınızda her yerden çalışır ama manifest daha uzun oluyor.
- Manifest’i arşivle aynı cihazda saklamak: Disk çökerse ikisi birden gidiyor. Manifest’in kopyasını en az bir farklı konumda tutun.
- Büyük dosyalarda hash süresi: 100 GB’lık bir arşivin sha256 hesabı dakikalar alabilir. Bunu planlama yaparkene hesaba katın, yedekleme penceresi buna göre ayarlanmalı.
- Checksum sonrası dosyaya dokunmamak: Hash hesaplandıktan sonra dosyayı touch etmek, sıkıştırma uygulamak veya ACL değiştirmek hash’i etkilemiyor. Ama içeriğe dokunursanız biter.
- sha256sum yerine md5sum kullanmak: MD5 collision saldırılarına karşı savunmasız. Güvenlik açısından kritik sistemlerde SHA-256 veya SHA-512 kullanın.
Sonuç
Checksum tabanlı yedek doğrulaması kulağa karmaşık gelebilir ama aslında son derece basit birkaç komutun disiplinli kullanımından ibaret. sha256sum ile manifest oluşturmak, transferin ardından doğrulamak ve bunu otomasyona bağlamak sizi o “üç aydır bozuk yedek alıyorduk” felaketinden koruyor.
Burada anlattıklarımı sıfırdan uygulamak isteyenler için öncelik sırası şu olmalı: Önce mevcut yedekleme scriptlerinize sha256sum satırını ekleyin, sonra manifest dosyasını farklı bir konumda sakladığınızdan emin olun, son olarak sabah doğrulama kontrolünü cron’a bağlayın. Bu üç adım, yedekleme güvenilirliğinizi dramatik biçimde artırıyor.
Yedekleriniz var olduğu için değil, doğrulandığı için güvenlidir. Bunu unutmayın.
