Şifreli ve Sıkıştırılmış Yedekleme: Restic ile Verilerinizi Güvende Tutun

Yedekleme işini ciddiye almayan sistem yöneticilerinin ortak bir özelliği vardır: hepsinin bir “o gün”ü olmuştur. Disk çökmesi, yanlışlıkla silinen kritik dizin, ransomware saldırısı… Bu anlar geldiğinde elimizde sağlam, şifreli ve güvenilir bir yedek yoksa iş felakete dönüşür. Restic tam bu noktada devreye giriyor: hızlı, şifreli, artımlı ve modern bir yedekleme aracı. Bu yazıda Restic’i sıfırdan kurup, gerçek dünya senaryolarında nasıl kullanacağınızı, şifreleme ve sıkıştırma özelliklerini nasıl aktif edeceğinizi ve otomatik yedekleme sistemini nasıl kuracağınızı adım adım anlatacağım.

Restic Neden Farklı?

Piyasada onlarca yedekleme aracı var. rsync var, tar var, Bacula var, Amanda var. Peki Restic’i özel yapan ne?

Her yedek şifreli gelir. Restic’te şifreleme opsiyonel değil, zorunlu. Repository oluştururken bir parola belirliyorsunuz ve tüm veriler AES-256-CTR ile şifrelenerek depolanıyor. Bu, buluta yedek atarken veri güvenliği konusundaki endişeleri büyük ölçüde ortadan kaldırıyor.

Artımlı yedekleme akıllıca çalışır. Restic, içerik tabanlı adresleme (content-defined chunking) kullanır. Dosyaları blok blok böler ve her bloğa bir hash atar. Sonraki yedeklemede sadece değişen bloklar kaydedilir. Büyük bir dosyanın küçük bir kısmı değiştiyse, tüm dosyayı değil sadece değişen kısmı yükler.

Çoklu backend desteği sunar. Yerel disk, SFTP, S3, Backblaze B2, Azure, Google Cloud, rclone üzerinden desteklenen her servis… Hepsine aynı komutlarla yedek alabilirsiniz.

Snapshot tabanlı çalışır. Her yedekleme işlemi bir snapshot oluşturur. Eski snapshotları silmek için policy tanımlayabilirsiniz. Herhangi bir snapshot’a geri dönmek dakikalar içinde tamamlanır.

Kurulum

Restic Go ile yazılmış, tek binary bir uygulama. Kurulumu son derece basit.

Ubuntu/Debian üzerinde:

apt update && apt install restic -y

Ama repo sürümü bazen geride kalır. En güncel versiyonu doğrudan GitHub releases’ten çekmenizi öneririm:

# Son versiyonu kontrol et
RESTIC_VERSION=$(curl -s https://api.github.com/repos/restic/restic/releases/latest | grep tag_name | cut -d '"' -f 4 | tr -d 'v')

# Binary'i indir
wget https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2

# Çıkart ve yerleştir
bunzip2 restic_${RESTIC_VERSION}_linux_amd64.bz2
mv restic_${RESTIC_VERSION}_linux_amd64 /usr/local/bin/restic
chmod +x /usr/local/bin/restic

# Versiyonu kontrol et
restic version

macOS üzerinde:

brew install restic

Windows üzerinde ise Chocolatey ile kurulum yapabilirsiniz:

choco install restic

Repository Oluşturmak

Restic’te her şey bir repository içinde tutulur. Repository, şifreli bir veri deposudur. Önce yerel bir repository ile başlayalım, ardından uzak sunucu senaryosuna geçeceğiz.

# Yerel repository oluştur
restic init --repo /opt/backups/myrepo

# Komut çalışınca parola isteyecek
# Enter password for new repository:
# Enter password again:
# created restic repository abc123def at /opt/backups/myrepo

Parolayı kaybetmeyin. Kaybederseniz verilerinize bir daha ulaşamazsınız, Restic’in kurtarma mekanizması yok bu konuda.

SFTP Üzerinden Uzak Sunucuya Repository

Gerçek dünya senaryosunda yedeklerinizi uzak bir sunucuda tutmak isteyeceksiniz. Restic SFTP’yi natively destekliyor.

Önce SSH key tabanlı erişim kurun:

# Key oluştur (yoksa)
ssh-keygen -t ed25519 -C "backup-key" -f ~/.ssh/backup_key -N ""

# Public key'i uzak sunucuya kopyala
ssh-copy-id -i ~/.ssh/backup_key.pub [email protected]

Şimdi uzak sunucuda SFTP üzerinden repository oluşturun:

restic init --repo sftp:[email protected]:/backups/webserver01

# SSH config dosyasını kullanmak daha temiz olur
# ~/.ssh/config'e ekleyin:
# Host backup-server
#     HostName backup-server.example.com
#     User backupuser
#     IdentityFile ~/.ssh/backup_key
#     Port 22

restic init --repo sftp:backup-server:/backups/webserver01

İlk Yedeklemeyi Almak

Repository hazır, şimdi yedek alalım. Bir web sunucusunun kritik dizinlerini yedeklediğimizi düşünelim:

# Temel yedekleme
restic backup --repo sftp:backup-server:/backups/webserver01 /var/www /etc /home

# Verbose çıktı için
restic backup -v --repo sftp:backup-server:/backups/webserver01 /var/www /etc /home

# Çıktı örneği:
# Files:        1523 new,   234 changed,  8901 unmodified
# Dirs:          234 new,    45 changed,   567 unmodified
# Data Blobs:   1456 new
# Tree Blobs:    198 new
# Added to the repo: 287.432 MiB
# processed 10658 files, 1.823 GiB in 0:45
# snapshot a1b2c3d4 saved

Şimdi bir saat sonra küçük değişiklikler yapıldıktan sonra tekrar yedek alalım:

restic backup --repo sftp:backup-server:/backups/webserver01 /var/www /etc /home

# İkinci çalışmada çok daha az veri transfer edildiğini göreceksiniz:
# Files:           0 new,     3 changed,  10655 unmodified
# Data Blobs:      2 new
# Added to the repo: 45.123 KiB

Artımlı yedekleme bu kadar etkili çalışıyor. 1.8 GB’lık veri için sadece 45 KB transfer edildi.

Sıkıştırma Ayarları

Restic 0.14.0 sürümünden itibaren sıkıştırma desteği geldi. Varsayılan olarak auto modda çalışır ama bunu açıkça belirtmek daha güvenli:

# Maksimum sıkıştırma ile yedek al
restic backup 
  --repo sftp:backup-server:/backups/webserver01 
  --compression max 
  /var/www /etc /home

# Sıkıştırma seçenekleri:
# auto   - Restic karar verir (önerilen)
# max    - Maksimum sıkıştırma, daha yavaş ama daha az disk kullanımı
# off    - Sıkıştırma kapalı

# Repository seviyesinde de ayarlayabilirsiniz:
restic init --repo /opt/backups/myrepo --compression max

Metin dosyaları, log dosyaları ve config dosyaları sıkıştırmadan büyük fayda sağlar. Zaten sıkıştırılmış dosyalar (JPEG, MP4, ZIP) için off veya auto tercih edin.

Snapshot Yönetimi

Zamanla çok sayıda snapshot birikir. Bunları yönetmek için birkaç önemli komut var:

# Tüm snapshotları listele
restic snapshots --repo sftp:backup-server:/backups/webserver01

# Çıktı:
# ID        Time                 Host        Tags        Paths
# ----------------------------------------------------------------
# a1b2c3d4  2024-01-15 02:00:01  webserver01             /var/www, /etc, /home
# e5f6g7h8  2024-01-16 02:00:01  webserver01             /var/www, /etc, /home
# i9j0k1l2  2024-01-17 02:00:01  webserver01             /var/www, /etc, /home

# Belirli bir snapshot'ın içeriğini gör
restic ls --repo sftp:backup-server:/backups/webserver01 a1b2c3d4

# Belirli bir dosyayı ara
restic find --repo sftp:backup-server:/backups/webserver01 "*.conf"

Retention Policy ile Eski Yedekleri Temizlemek

Sonsuz yedek tutmak disk doldurmak demek. forget komutuyla akıllı bir temizleme politikası tanımlayabilirsiniz:

# Politika tanımla ve uygula
restic forget 
  --repo sftp:backup-server:/backups/webserver01 
  --keep-daily 7 
  --keep-weekly 4 
  --keep-monthly 6 
  --keep-yearly 2 
  --prune

# Bu politika şunu yapar:
# Son 7 günün her birinden 1 snapshot tut
# Son 4 haftanın her birinden 1 snapshot tut
# Son 6 ayın her birinden 1 snapshot tut
# Son 2 yılın her birinden 1 snapshot tut
# --prune ile fiziksel silme işlemini de gerçekleştirir

--prune olmadan forget sadece snapshotları işaretler, gerçek veriyi silmez. Disk alanı kazanmak için mutlaka --prune ekleyin veya ayrıca restic prune çalıştırın.

Geri Yükleme

Felaket anı geldi. Dosyaları geri yükleyelim:

# Son snapshot'tan tüm veriyi geri yükle
restic restore latest 
  --repo sftp:backup-server:/backups/webserver01 
  --target /

# Belirli bir snapshot'tan geri yükle
restic restore a1b2c3d4 
  --repo sftp:backup-server:/backups/webserver01 
  --target /tmp/restore

# Sadece belirli dizinleri geri yükle
restic restore latest 
  --repo sftp:backup-server:/backups/webserver01 
  --include /var/www/html 
  --target /

# Tek bir dosyayı geri yükle
restic restore latest 
  --repo sftp:backup-server:/backups/webserver01 
  --include /etc/nginx/nginx.conf 
  --target /tmp/restore

Geri yükleme işlemini test ortamında düzenli olarak deneyin. Hiç test etmediğiniz yedekler, yedek değildir.

Otomatik Yedekleme: Bash Script ve Systemd

Manuel çalıştırmak uzun süre yetmez. Bunu otomatikleştirmenin en temiz yolu systemd timer kullanmak. Önce bir script yazalım:

cat > /usr/local/bin/restic-backup.sh << 'EOF'
#!/bin/bash

# Restic Yedekleme Scripti
# /usr/local/bin/restic-backup.sh

set -euo pipefail

# Log fonksiyonu
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/restic-backup.log
}

# Değişkenler
export RESTIC_REPOSITORY="sftp:backup-server:/backups/$(hostname)"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

# Repository erişim kontrolü
if ! restic snapshots > /dev/null 2>&1; then
    log "HATA: Repository'e erişilemiyor!"
    exit 1
fi

log "Yedekleme başlıyor..."

# Yedekleme al
restic backup 
    --compression auto 
    --tag "$(hostname)" 
    --tag "systemd" 
    --exclude-file /etc/restic/excludes.txt 
    /var/www 
    /etc 
    /home 
    /opt

log "Yedekleme tamamlandı."

# Eski yedekleri temizle
log "Retention policy uygulanıyor..."
restic forget 
    --keep-daily 7 
    --keep-weekly 4 
    --keep-monthly 3 
    --prune 
    --tag "$(hostname)"

log "Temizleme tamamlandı."

# Repository bütünlüğünü kontrol et (ayda bir)
if [ "$(date +%d)" = "01" ]; then
    log "Aylık check başlıyor..."
    restic check
    log "Check tamamlandı."
fi

log "Tüm işlemler başarıyla tamamlandı."
EOF

chmod +x /usr/local/bin/restic-backup.sh

Parola dosyasını güvenli şekilde oluşturun:

mkdir -p /etc/restic
echo "cok-guclu-parola-buraya" > /etc/restic/password
chmod 600 /etc/restic/password

# Hariç tutulacak dosyalar listesi
cat > /etc/restic/excludes.txt << EOF
/var/www/cache
/home/*/.cache
/home/*/.local/share/Trash
*.tmp
*.log.gz
*.pid
node_modules
__pycache__
EOF

Şimdi systemd service ve timer dosyalarını oluşturalım:

# Service dosyası
cat > /etc/systemd/system/restic-backup.service << EOF
[Unit]
Description=Restic Backup Service
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
StandardOutput=journal
StandardError=journal
SyslogIdentifier=restic-backup

# Güvenlik ayarları
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/log
EOF

# Timer dosyası
cat > /etc/systemd/system/restic-backup.timer << EOF
[Unit]
Description=Restic Backup Timer
Requires=restic-backup.service

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Timer'ı etkinleştir
systemctl daemon-reload
systemctl enable --now restic-backup.timer

# Durumu kontrol et
systemctl status restic-backup.timer

RandomizedDelaySec=1800 parametresi sayesinde birden fazla sunucunuz varsa, hepsi aynı anda yedek almaya başlamaz. 30 dakikalık rastgele gecikme ile backup sunucusunuzu ezmezsiniz.

S3 Uyumlu Depolama ile Kullanım

Hetzner Object Storage, Cloudflare R2, Wasabi veya AWS S3 kullanıyorsanız:

# Ortam değişkenlerini ayarla
export AWS_ACCESS_KEY_ID="access-key-buraya"
export AWS_SECRET_ACCESS_KEY="secret-key-buraya"
export RESTIC_PASSWORD="repository-parolaniz"

# Hetzner Object Storage örneği
restic init 
  --repo s3:https://fsn1.your-objectstorage.com/bucket-adi/restic

# AWS S3 örneği
restic init 
  --repo s3:s3.amazonaws.com/bucket-adi/restic

# Yedek al
restic backup 
  --repo s3:https://fsn1.your-objectstorage.com/bucket-adi/restic 
  --compression max 
  /var/www /etc

Bu bilgileri doğrudan script içine koymak yerine /etc/restic/env gibi bir dosyaya taşıyın:

cat > /etc/restic/env << EOF
export RESTIC_REPOSITORY="s3:https://fsn1.your-objectstorage.com/bucket-adi/restic"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
export AWS_ACCESS_KEY_ID="access-key-buraya"
export AWS_SECRET_ACCESS_KEY="secret-key-buraya"
EOF

chmod 600 /etc/restic/env

# Script başına ekleyin:
source /etc/restic/env

Repository Bütünlük Kontrolü

Yedek aldık ama düzgün mü? Restic’in check komutu tam burada devreye giriyor:

# Hızlı metadata kontrolü
restic check --repo sftp:backup-server:/backups/webserver01

# Kapsamlı veri kontrolü (tüm pack dosyalarını okur, yavaş ama güvenilir)
restic check --read-data --repo sftp:backup-server:/backups/webserver01

# Rastgele %10'unu kontrol et (denge için ideal)
restic check --read-data-subset=10% --repo sftp:backup-server:/backups/webserver01

check komutunu ayda en az bir kez çalıştırın. Benim tercihim her hafta --read-data-subset=10% ile çalıştırmak, ayda bir de tam --read-data ile geçmek.

Birden Fazla Sunucudan Merkezi Yedekleme

10 sunucunuz var diyelim. Her biri aynı backup sunucusuna yedek atıyor. Organizasyonu şöyle yapabilirsiniz:

Her sunucuda /etc/restic/env dosyasına sunucuya özgü repository path tanımlayın:

# webserver01 için
export RESTIC_REPOSITORY="sftp:backup-server:/backups/webserver01"

# dbserver01 için
export RESTIC_REPOSITORY="sftp:backup-server:/backups/dbserver01"

Backup sunucusunda her sunucu için ayrı dizin oluşturun ve izinleri sınırlı tutun:

# Backup sunucusunda
useradd -m -s /bin/bash backupuser
mkdir -p /backups/{webserver01,dbserver01,mailserver01}
chown backupuser:backupuser /backups/*

# Her sunucu için ayrı SSH key kullanmak daha güvenli
# authorized_keys'e şunu ekleyin (komutu kısıtlamak için):
# command="restic serve sftp --path /backups/webserver01",restrict ssh-ed25519 AAAA...

Monitoring: Yedekleme Başarısız Olursa Haber Al

Yedekleme çalışıyor gibi görünüp aslında hata veriyor olabilir. Monitoring şart:

# Script sonuna ekleyin - Healthchecks.io ile entegrasyon
HEALTHCHECK_URL="https://hc-ping.com/uuid-buraya"

# Script başında başlangıç pingleri
curl -fsS --retry 3 "${HEALTHCHECK_URL}/start" > /dev/null 2>&1 || true

# Script sonunda başarı pingi
curl -fsS --retry 3 "${HEALTHCHECK_URL}" > /dev/null 2>&1 || true

# Hata durumunda failure pingi
# set -e ile birlikte trap kullanın:
trap 'curl -fsS --retry 3 "${HEALTHCHECK_URL}/fail" > /dev/null 2>&1' ERR

Alternatif olarak systemd’nin kendi mekanizmasını kullanabilirsiniz:

# Yedekleme durumunu kontrol et
systemctl status restic-backup.service

# Son çalışma loglarına bak
journalctl -u restic-backup.service --since "24 hours ago"

# Başarısız son çalışma var mı?
systemctl show restic-backup.service --property=ExecMainStatus

Sık Karşılaşılan Sorunlar ve Çözümleri

Repository kilitleniyor: Yedekleme ortasında kesintiye uğrarsa repository kilitli kalır:

restic unlock --repo sftp:backup-server:/backups/webserver01

“no space left on device” hatası: Prune çalıştırılmamış olabilir:

restic forget --keep-last 10 --prune --repo sftp:backup-server:/backups/webserver01

Yavaş yedekleme: Bant genişliği sınırlıysa upload hızını kısıtlayabilirsiniz. Doğrudan Restic’te bant genişliği limiti yok ama sistemi ezmemek için ionice ve nice kullanabilirsiniz:

nice -n 19 ionice -c 3 restic backup --repo ... /var/www

Parola yanlış hatası: Farklı environment’larda parola dosyası bulunamıyor olabilir. RESTIC_PASSWORD_FILE yerine doğrudan RESTIC_PASSWORD kullanmak debug sırasında işe yarar ama production’da kesinlikle dosya kullanın.

Sonuç

Restic, modern bir sysadmin’in araç çantasında kesinlikle bulunması gereken bir yedekleme aracı. Kurulumu basit, şifreleme zorunlu ve akıllı, artımlı yapısı sayesinde hem zaman hem bant genişliği tasarrufu sağlıyor.

Bu yazıda anlattıklarımı özetlersek: SFTP veya S3 uyumlu bir backend seçin, repository’nizi şifreli oluşturun, sıkıştırmayı auto olarak bırakın, retention policy’nizi belirleyin ve sistemd timer ile otomatize edin. En az ayda bir check çalıştırın ve en kritik adımı unutmayın: geri yüklemeyi test edin.

Yedekleme sistemleri ancak başarılı bir geri yükleme yapılabildiğinde gerçek değerini kanıtlar. Ayda bir, 10 dakikanızı ayırıp test ortamında bir restore deneyin. O 10 dakika bir gün tüm mesai saatlerinizi kurtarabilir.

Bir yanıt yazın

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