Yerel ve Uzak Yedekleme Kurulumu: Restic Rehberi

Yedekleme konusuna gelince, çoğu sysadmin iki uç noktadan birinde takılıp kalıyor: ya hiç yedek almıyor ya da yedek alıyor ama o yedeklerin çalışıp çalışmadığını test etmiyor. Restic, bu iki problemi de çözmek için tasarlanmış modern bir yedekleme aracı. Hızlı, şifreli, deduplikasyon destekli ve neredeyse her depolama backend’iyle çalışıyor. Bu yazıda sıfırdan bir Restic kurulumu yapacak, hem yerel hem uzak yedekleme senaryolarını ele alacak ve işi otomatize edecek production-ready bir yapı kuracağız.

Restic Nedir ve Neden Kullanmalısınız

Klasik tar+gzip yedeklerinin aksine Restic, içerik adreslemeli depolama (content-addressable storage) kullanıyor. Yani her dosya bloklara ayrılıyor, SHA-256 ile hashleniyor ve sadece değişen bloklar yedekleniyor. Bu sayede hem disk alanından tasarruf ediyorsunuz hem de backup süresi dramatik biçimde kısalıyor.

Restic’in öne çıkan özellikleri:

  • Şifreleme: AES-256-CTR ile her şey client-side şifreleniyor, depolama tarafı hiçbir zaman düz veri görmüyor
  • Deduplikasyon: Aynı veri birden fazla snapshot’ta varsa tek kez saklanıyor
  • Bütünlük doğrulama: restic check komutuyla istediğiniz zaman repo bütünlüğünü test edebiliyorsunuz
  • Cross-platform: Linux, macOS, Windows hepsinde çalışıyor
  • Birden fazla backend: Local, SFTP, S3, Azure Blob, Google Cloud, Backblaze B2 ve Rclone üzerinden onlarca servis

Kurulum

Restic çoğu Linux dağıtımının resmi repo’larında mevcut, ancak bu repo’lardaki sürümler genellikle geride kalıyor. Ben her zaman GitHub releases’ten binary indirmeyi tercih ediyorum.

# En son sürümü GitHub'dan indir
wget https://github.com/restic/restic/releases/download/v0.16.4/restic_0.16.4_linux_amd64.bz2

# Sıkıştırmayı aç
bunzip2 restic_0.16.4_linux_amd64.bz2

# Çalıştırılabilir yap ve path'e taşı
chmod +x restic_0.16.4_linux_amd64
sudo mv restic_0.16.4_linux_amd64 /usr/local/bin/restic

# Versiyonu doğrula
restic version

Debian/Ubuntu kullanıcıları için apt ile de kurabilirsiniz:

sudo apt update && sudo apt install restic -y

# Kurulumu doğrula
restic self-update  # Binary'yi en son versiyona günceller

Repository Kavramı

Restic’te her şey repository (kısaca repo) etrafında dönüyor. Repo, tüm snapshot’larınızın şifreli biçimde saklandığı dizin veya uzak konumdur. Bir repo’yu kullanmaya başlamadan önce init komutuyla başlatmanız gerekiyor.

Yerel Repository Oluşturma

# Yerel bir repo başlat
restic init --repo /mnt/backup/my-repo

# Komut çalıştığında şifre belirlemenizi isteyecek
# Enter password for new repository:
# Enter password again:
# created restic repository abc123def at /mnt/backup/my-repo

Şifreyi girdikten sonra Restic size bir repository ID verecek. Bu ID’yi bir yere not edin, ilerleyen dönemlerde sorun yaşadığınızda işe yarıyor.

Önemli not: Şifreyi kaybederseniz yedeklerinize erişemezsiniz. Bu şifreyi mutlaka güvenli bir şekilde (KeePass, Bitwarden, ya da en azından başka bir lokasyonda şifreli text dosyası) saklayın.

Çevre Değişkenleriyle Kolaylık

Her komuta --repo ve --password-file parametresi geçmek can sıkıcı hale geliyor. Bunun yerine çevre değişkenlerini kullanabiliriz.

# /etc/restic/env adında bir dosya oluşturalım
sudo mkdir -p /etc/restic
sudo nano /etc/restic/env

# Dosya içeriği:
export RESTIC_REPOSITORY="/mnt/backup/my-repo"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

# Şifreyi ayrı dosyaya yaz
echo "cok-gizli-sifre-buraya" | sudo tee /etc/restic/password
sudo chmod 600 /etc/restic/password
sudo chmod 600 /etc/restic/env

# Kullanmak için:
source /etc/restic/env
restic snapshots  # Artık --repo parametresi gerekmez

İlk Yedeklemeyi Almak

Basit bir backup komutuyla başlayalım:

source /etc/restic/env

# Web sunucusu config ve veri dizinlerini yedekle
restic backup 
  /etc/nginx 
  /var/www/html 
  /home 
  --tag "production" 
  --tag "webserver" 
  --exclude "/home/*/.cache" 
  --exclude "/home/*/.local/share/Trash" 
  --exclude "*.tmp" 
  --exclude "*.log"

Çıktıda şöyle bir şey görmeniz gerekiyor:

repository abc123def opened (version 2, compression level auto)
no parent snapshot found, will read all files
Files:       1234 new,     0 changed,     0 unmodified
Dirs:          89 new,     0 changed,     0 unmodified
Added to the repository: 245.123 MiB (198.456 MiB stored)
snapshot 7f8e9a2b saved

Buradaki “stored” değeri deduplikasyon sonrası gerçek disk kullanımını gösteriyor. İkinci backup’ta değişen az dosya varsa bu fark çok daha belirgin olacak.

Snapshot Listesini Görüntüleme

restic snapshots

# Daha detaylı çıktı için
restic snapshots --verbose

# Belirli bir tag'e göre filtrele
restic snapshots --tag "production"

Uzak Yedekleme: SFTP Backend

Gerçek dünya senaryosunda sadece yerel yedek yeterli değil. 3-2-1 kuralı gereği en az 3 kopya, 2 farklı medya, 1 off-site olmalı. SFTP backend ile uzak bir sunucuya yedekleme yapabiliriz.

Önce SSH key-based authentication kuralım:

# Yedekleme için ayrı bir SSH key oluştur
ssh-keygen -t ed25519 -f /root/.ssh/restic_backup -N "" -C "restic-backup-$(hostname)"

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

# Bağlantıyı test et
ssh -i /root/.ssh/restic_backup [email protected] "echo Baglanti basarili"

Şimdi uzak sunucuda SFTP repo başlatalım:

# SFTP reposunu init et
restic -r sftp:[email protected]:/backups/server1-repo init

# Ya da env değişkeniyle
export RESTIC_REPOSITORY="sftp:[email protected]:/backups/server1-repo"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

restic init

SSH config dosyasını düzenleyerek SFTP bağlantısını daha temiz hale getirebiliriz:

# /root/.ssh/config dosyasına ekle
Host backup-server
    HostName 192.168.1.100
    User backup-user
    IdentityFile /root/.ssh/restic_backup
    Port 22
    ServerAliveInterval 60
    ServerAliveCountMax 3

# Artık bu şekilde kullanabilirsiniz
restic -r sftp:backup-server:/backups/server1-repo snapshots

Uzak Yedekleme: Backblaze B2 ile Bulut Yedeklemesi

SFTP iyi bir seçenek ama aynı ağdaki sunucu gerçek anlamda off-site değil. Backblaze B2 uygun fiyatlı (GB başına $0.006/ay) ve Restic ile native entegrasyonu olan bir bulut depolama servisi.

# B2 credentials'larını env'e ekle
export RESTIC_REPOSITORY="b2:my-bucket-name:server1-backup"
export B2_ACCOUNT_ID="your-b2-account-id"
export B2_ACCOUNT_KEY="your-b2-application-key"
export RESTIC_PASSWORD_FILE="/etc/restic/password"

# Repo'yu başlat
restic init

# İlk backup
restic backup /etc /var/www /home 
  --tag "$(hostname)" 
  --tag "cloud-backup"

Otomatik Yedekleme: Systemd Timer ile Production Kurulumu

Cron da çalışır ama systemd timer daha iyi logging, dependency yönetimi ve hata yönetimi sunuyor. Ben production’da her zaman systemd timer tercih ediyorum.

Önce bir backup script yazalım:

sudo nano /usr/local/bin/restic-backup.sh
#!/bin/bash
set -euo pipefail

# Logging
LOG_FILE="/var/log/restic/backup.log"
mkdir -p /var/log/restic
exec > >(tee -a "$LOG_FILE") 2>&1

echo "=== Backup basliyor: $(date '+%Y-%m-%d %H:%M:%S') ==="

# Environment
source /etc/restic/env

# Yerel repo backup
echo "[1/2] Yerel repo backup..."
restic backup 
  /etc 
  /var/www 
  /home 
  --tag "$(hostname)" 
  --tag "local" 
  --tag "$(date +%Y-%m)" 
  --exclude "/home/*/.cache" 
  --exclude "/home/*/.mozilla" 
  --exclude "/home/*/.config/google-chrome" 
  --exclude "*.pyc" 
  --exclude "__pycache__" 
  --one-file-system 
  --verbose

# Uzak repo backup (B2)
echo "[2/2] Bulut backup..."
export RESTIC_REPOSITORY="b2:my-bucket:$(hostname)-backup"
export B2_ACCOUNT_ID="$(cat /etc/restic/b2_account_id)"
export B2_ACCOUNT_KEY="$(cat /etc/restic/b2_account_key)"

restic backup 
  /etc 
  /var/www 
  /home 
  --tag "$(hostname)" 
  --tag "cloud" 
  --exclude "/home/*/.cache" 
  --one-file-system 
  --verbose

echo "=== Backup tamamlandi: $(date '+%Y-%m-%d %H:%M:%S') ==="
sudo chmod +x /usr/local/bin/restic-backup.sh

Systemd service dosyası:

sudo nano /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic Backup Service
After=network-online.target
Wants=network-online.target

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

# Timeout: 4 saat
TimeoutStartSec=14400

[Install]
WantedBy=multi-user.target

Systemd timer dosyası:

sudo nano /etc/systemd/system/restic-backup.timer
[Unit]
Description=Restic Backup Timer
Requires=restic-backup.service

[Timer]
# Her gece 02:30'da çalış
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=900
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable restic-backup.timer
sudo systemctl start restic-backup.timer

# Timer durumunu kontrol et
sudo systemctl status restic-backup.timer
sudo systemctl list-timers restic-backup.timer

Retention Policy: Eski Yedekleri Temizleme

Sonsuz yedek tutmak ne pratikte ne de maddi açıdan sürdürülebilir. Restic’in forget komutu buna mükemmel bir çözüm sunuyor.

source /etc/restic/env

# Retention policy uygula
restic forget 
  --keep-last 5 
  --keep-daily 7 
  --keep-weekly 4 
  --keep-monthly 12 
  --keep-yearly 3 
  --tag "production" 
  --prune

# --dry-run ile önce neyin silineceğini gör
restic forget 
  --keep-last 5 
  --keep-daily 7 
  --keep-weekly 4 
  --keep-monthly 12 
  --prune 
  --dry-run

Bu policy şunu söylüyor:

  • –keep-last 5: Son 5 snapshot’ı her koşulda tut
  • –keep-daily 7: Son 7 günün günlük snapshot’larını tut
  • –keep-weekly 4: Son 4 haftanın haftalık snapshot’larını tut
  • –keep-monthly 12: Son 12 ayın aylık snapshot’larını tut
  • –keep-yearly 3: Son 3 yılın yıllık snapshot’larını tut
  • –prune: Referanssız kalan blokları fiziksel olarak sil

Veri Doğrulama: En Önemli Adım

Yedekleyen herkes kahramandır, test eden ise gerçek sysadmin. Backup almak işin yarısı, diğer yarısı düzgün çalıştığını doğrulamak.

source /etc/restic/env

# Repository bütünlüğünü kontrol et
restic check

# Daha kapsamlı kontrol (tüm pack dosyalarını oku)
restic check --read-data

# Belirli bir snapshot'tan dosya listesi
restic ls 7f8e9a2b

# Belirli bir dosyayı restore et (test amaçlı)
restic restore 7f8e9a2b 
  --target /tmp/restic-test 
  --include /etc/nginx/nginx.conf

# Restore sonrası kontrol
ls -la /tmp/restic-test/etc/nginx/
diff /etc/nginx/nginx.conf /tmp/restic-test/etc/nginx/nginx.conf

# Test dizinini temizle
rm -rf /tmp/restic-test

Aylık doğrulama script’i:

#!/bin/bash
source /etc/restic/env

echo "=== Aylik Backup Dogrulama: $(date) ==="

# Repo check
if restic check; then
  echo "BASARILI: Repository butunlugu dogrulandi"
else
  echo "HATA: Repository check basarisiz!"
  # Buraya e-posta veya Slack bildirimi eklenebilir
  exit 1
fi

# En son snapshot'tan rastgele bir dosyayı restore et ve test et
LATEST=$(restic snapshots --json | python3 -c "import sys,json; snaps=json.load(sys.stdin); print(snaps[-1]['id'])")
TEMP_DIR=$(mktemp -d)

restic restore "$LATEST" 
  --target "$TEMP_DIR" 
  --include /etc/hostname

if [ -f "$TEMP_DIR/etc/hostname" ]; then
  echo "BASARILI: Restore testi gecti - $(cat $TEMP_DIR/etc/hostname)"
else
  echo "HATA: Restore testi basarisiz!"
  exit 1
fi

rm -rf "$TEMP_DIR"
echo "=== Dogrulama tamamlandi ==="

Veritabanı Yedeklemesi: MySQL/PostgreSQL

Dosya sistemi yedeği alırken veritabanı dosyalarını olduğu gibi kopyalamak tutarsız yedeklere yol açar. Bunun yerine önce dump alıp sonra Restic ile yedekleyin.

#!/bin/bash
source /etc/restic/env

DUMP_DIR="/var/backups/db-dumps"
mkdir -p "$DUMP_DIR"
DATE=$(date +%Y%m%d_%H%M%S)

# MySQL dump
if command -v mysqldump &> /dev/null; then
  echo "MySQL dump aliniyor..."
  mysqldump 
    --defaults-file=/etc/mysql/backup.cnf 
    --all-databases 
    --single-transaction 
    --routines 
    --triggers 
    | gzip > "$DUMP_DIR/mysql_all_$DATE.sql.gz"
fi

# PostgreSQL dump
if command -v pg_dumpall &> /dev/null; then
  echo "PostgreSQL dump aliniyor..."
  sudo -u postgres pg_dumpall 
    | gzip > "$DUMP_DIR/postgres_all_$DATE.sql.gz"
fi

# Eski dump'ları temizle (7 günden eski)
find "$DUMP_DIR" -name "*.sql.gz" -mtime +7 -delete

# Restic ile dump dizinini yedekle
restic backup "$DUMP_DIR" 
  --tag "database" 
  --tag "$(hostname)"

echo "Veritabani yedeklemesi tamamlandi"

Sorun Giderme

Zaman zaman karşılaşılan yaygın sorunlar ve çözümleri:

  • “repository is already locked” hatası: Başka bir Restic işlemi çökmüş ve kilidi bırakmış olabilir. restic unlock ile kilidi kaldırın, ancak gerçekten başka bir işlem çalışmadığından emin olun.
  • SFTP bağlantısı düşüyor: SSH config’e ServerAliveInterval 60 ve ServerAliveCountMax 3 ekleyin. Büyük yedeklemeler için --limit-upload ile bant genişliğini sınırlandırın.
  • Backup çok yavaş: --compression max yerine --compression auto kullanın. Zaten şifreli veri (HTTPS trafiği, JPEG, ZIP) tekrar sıkıştırılamaz.
  • Repository check hata veriyor: Önce restic check --read-data-subset 10% ile kısmi kontrol yapın. Sorun devam ederse restic repair komutlarını inceleyin.
  • Disk doldu: restic prune ile gereksiz blokları temizleyin. Öncesinde restic stats ile repo boyutunu analiz edin.
# Repository istatistiklerini görüntüle
restic stats

# Mode seçenekleriyle daha detaylı
restic stats --mode raw-data
restic stats --mode blobs-per-file

Sonuç

Restic, modern bir yedekleme altyapısı için gereken tüm özellikleri tek bir binary içinde sunuyor. Şifreleme, deduplikasyon, çoklu backend desteği ve bütünlük doğrulama ile hem küçük VPS’lerden hem de büyük kurumsal sunuculardan ciddi bir yedekleme çözümü olarak kullanılabilir.

Bu yazıda kurduğumuz yapıyı özetleyecek olursak: yerel repo ile hızlı erişim sağladık, SFTP veya B2 ile off-site kopya oluşturduk, systemd timer ile otomasyonu kurduk, retention policy ile disk yönetimini hallettik ve en önemlisi doğrulama script’iyle yedeklerin çalıştığını test ettik.

Son olarak şunu söyleyelim: test etmediğiniz yedek, yedek değildir. Ayda bir otomatik restore testini muhakkak çalıştırın. Felaket anında o test sizi kurtaracak, backup log’larındaki yeşil checkmark’lar değil.

Bir yanıt yazın

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