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. Manifest yedek.tar.gz diye 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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir