Restic ile Bulut Depolamaya Şifreli Yedekleme
Yedekleme konusu sysadmin’lerin en çok ertelediği ama en çok pişman olduğu konuların başında gelir. “Şu an çalışıyor, yedek almak için zaman yok” dersin, ta ki o korkunç gün gelene kadar. Bu yazıda, Restic ile bulut depolamaya nasıl şifreli, güvenilir ve otomatik yedekler alabileceğini adım adım anlatacağım. Restic’i daha önce duymadıysan şunu söyleyeyim: Bu araç, yedekleme dünyasında gerçekten oyun değiştirici.
Restic Nedir ve Neden Kullanmalısın?
Restic, Go ile yazılmış, açık kaynaklı bir yedekleme aracıdır. Sadece başka bir yedekleme scripti değil; deduplikasyon, şifreleme ve sürüm yönetimini bir arada sunuyor. Rakiplerine göre öne çıkan birkaç noktası var:
- Şifreleme varsayılan olarak gelir: AES-256-CTR ile her şey şifrelenir, seçenek değil zorunluluktur
- Deduplikasyon: Aynı içeriği tekrar tekrar yüklemez, sadece değişen blokları gönderir
- Çoklu backend desteği: S3, Backblaze B2, Azure, Google Cloud Storage, SFTP ve daha fazlası
- Anlık görüntüler (snapshots): Her yedek bir snapshot’tır, istediğin noktaya dönebilirsin
- Bütünlük doğrulama:
restic checkkomutuyla yedeklerin sağlığını test edebilirsin
Gerçek dünya senaryosunu düşün: Bir e-ticaret sitesi çalıştırıyorsun, PostgreSQL veritabanı, Nginx konfigürasyonları, uygulama kodları ve kullanıcı yüklemeleri var. Bunların tamamını şifreli şekilde AWS S3’e yedeklemek istiyorsun. İşte tam da bu senaryo üzerinden ilerleyeceğiz.
Kurulum
Restic’i çoğu Linux dağıtımının paket yöneticisinden kurabilirsin.
# Ubuntu/Debian
sudo apt update && sudo apt install restic -y
# RHEL/CentOS/AlmaLinux
sudo dnf install restic -y
# macOS (Homebrew ile)
brew install restic
# En güncel sürümü doğrudan indirmek istersen
wget https://github.com/restic/restic/releases/download/v0.16.4/restic_0.16.4_linux_amd64.bz2
bunzip2 restic_0.16.4_linux_amd64.bz2
chmod +x restic_0.16.4_linux_amd64
sudo mv restic_0.16.4_linux_amd64 /usr/local/bin/restic
Kurulumu doğrulamak için:
restic version
# restic 0.16.4 compiled with go1.21.5 on linux/amd64
AWS S3 Üzerinde Repository Oluşturma
Önce AWS tarafında bir S3 bucket ve IAM kullanıcısı oluşturman gerekiyor. Bunu CLI ile yapalım:
# AWS CLI ile bucket oluştur (bölgeyi ihtiyacına göre değiştir)
aws s3api create-bucket
--bucket sirket-yedekleri-2024
--region eu-west-1
--create-bucket-configuration LocationConstraint=eu-west-1
# Bucket versioning'i etkinleştir (ekstra güvenlik katmanı)
aws s3api put-bucket-versioning
--bucket sirket-yedekleri-2024
--versioning-configuration Status=Enabled
# Bucket'ı public erişime kapat
aws s3api put-public-access-block
--bucket sirket-yedekleri-2024
--public-access-block-configuration
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
IAM politikası için minimum yetkiyle çalışan bir kullanıcı oluşturuyoruz. Aşağıdaki JSON politikasını restic-policy.json olarak kaydet:
cat > /tmp/restic-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::sirket-yedekleri-2024"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::sirket-yedekleri-2024/*"
}
]
}
EOF
# Politikayı oluştur
aws iam create-policy
--policy-name ResticBackupPolicy
--policy-document file:///tmp/restic-policy.json
# IAM kullanıcısı oluştur
aws iam create-user --user-name restic-backup-user
# Politikayı kullanıcıya bağla
aws iam attach-user-policy
--user-name restic-backup-user
--policy-arn arn:aws:iam::HESAP_ID:policy/ResticBackupPolicy
# Access key oluştur ve kaydet
aws iam create-access-key --user-name restic-backup-user
Ortam Değişkenlerini Ayarlama
Kimlik bilgilerini script içine gömmek yerine ortam değişkenlerini kullanmak en sağlıklı yöntem. /etc/restic/env adında bir dosya oluşturalım:
sudo mkdir -p /etc/restic
sudo tee /etc/restic/env << 'EOF'
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/sirket-yedekleri-2024"
export RESTIC_PASSWORD="cok-guclu-ve-uzun-bir-sifre-buraya"
EOF
# Sadece root okuyabilsin
sudo chmod 600 /etc/restic/env
sudo chown root:root /etc/restic/env
Önemli: RESTIC_PASSWORD değerini bir yere not et ve güvenli bir yerde sakla. Bu şifreyi kaybedersen yedeklerine bir daha erişemezsin. LastPass, 1Password veya fiziksel bir kasada tutmanı öneririm.
Repository’yi Başlatma ve İlk Yedek
# Ortam değişkenlerini yükle
source /etc/restic/env
# Repository'yi başlat (bu komutu sadece bir kez çalıştırırsın)
restic init
# Çıktı şuna benzer:
# created restic repository abc123def456 at s3:s3.amazonaws.com/sirket-yedekleri-2024
# Please note that knowledge of your password is required to access the repository.
# Losing your password means that your data is irrecoverably lost.
# İlk yedeği al
restic backup /var/www /etc/nginx /home
# Daha detaylı çıktı için --verbose ekle
restic backup --verbose /var/www /etc/nginx /home
Repository ID’sini de güvenli bir yerde saklaman gerekiyor. Bu ID, yedek doğrulama ve sorun giderme aşamasında işe yarar.
Gerçek Dünya Senaryosu: PostgreSQL Yedekleme
Çalışan bir veritabanını doğrudan yedeklemek yerine önce dump alıp sonra yedeklemek gerekiyor. Bunun için bir wrapper script yazalım:
sudo tee /usr/local/bin/backup-postgresql.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
source /etc/restic/env
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
DUMP_DIR="/tmp/pg_dumps"
LOG_FILE="/var/log/restic/backup_$(date +%Y%m%d).log"
mkdir -p "$DUMP_DIR"
mkdir -p "/var/log/restic"
echo "[$(date)] Yedekleme basliyor..." >> "$LOG_FILE"
# Tum PostgreSQL veritabanlarini dump al
sudo -u postgres pg_dumpall --clean --if-exists > "$DUMP_DIR/all_databases_${BACKUP_DATE}.sql"
if [ $? -eq 0 ]; then
echo "[$(date)] PostgreSQL dump alindi." >> "$LOG_FILE"
else
echo "[$(date)] HATA: PostgreSQL dump basarisiz!" >> "$LOG_FILE"
exit 1
fi
# Dump'i sikistir
gzip "$DUMP_DIR/all_databases_${BACKUP_DATE}.sql"
# Restic ile yedekle
restic backup
--tag postgresql
--tag production
--verbose
"$DUMP_DIR"
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "[$(date)] Restic yedekleme tamamlandi." >> "$LOG_FILE"
# Gecici dosyalari temizle
rm -f "$DUMP_DIR"/all_databases_*.sql.gz
else
echo "[$(date)] HATA: Restic yedekleme basarisiz!" >> "$LOG_FILE"
# Gecici dosyalari yine de temizle
rm -f "$DUMP_DIR"/all_databases_*.sql.gz
exit 1
fi
# Eski yedekleri temizle (politikaya gore)
restic forget
--tag postgresql
--keep-daily 7
--keep-weekly 4
--keep-monthly 12
--prune
>> "$LOG_FILE" 2>&1
echo "[$(date)] Yedekleme tamamlandi." >> "$LOG_FILE"
SCRIPT
sudo chmod +x /usr/local/bin/backup-postgresql.sh
Snapshot Yönetimi ve Saklama Politikaları
Restic’in en güçlü özelliklerinden biri snapshot yönetimi. Hangi yedeklerin ne kadar süre tutulacağını forget komutuyla kontrol edersin:
source /etc/restic/env
# Mevcut snapshot'lari listele
restic snapshots
# Tag'e gore filtrele
restic snapshots --tag postgresql
# Saklama politikasini uygula (--prune olmadan sadece isaretler, silmez)
restic forget
--keep-last 3 # Son 3 yedegi her zaman tut
--keep-daily 7 # Her gunun son yedeğini 7 gun tut
--keep-weekly 4 # Her haftanin son yedeğini 4 hafta tut
--keep-monthly 12 # Her ayin son yedeğini 12 ay tut
--keep-yearly 3 # Her yilin son yedeğini 3 yil tut
--prune # Kullanilmayan verileri fiziksel olarak sil
# Tek bir snapshot'i sil
restic forget abc123def456
# Dry-run ile ne silineceğini once kontrol et
restic forget --keep-daily 7 --keep-weekly 4 --dry-run
Saklama politikasını belirlerken iş gereksinimlerini göz önünde bulundur. Bir e-ticaret sitesi için şöyle bir politika mantıklı olabilir:
- –keep-last 5: Beklenmedik sorunlar için son 5 yedek her zaman elinizin altında
- –keep-daily 14: İki haftalık günlük granülarite
- –keep-weekly 8: İki aylık haftalık granülarite
- –keep-monthly 24: İki yıllık aylık granülarite
Yedekten Geri Yükleme
Yedek almanın yarısı geri yükleyebilmek. Bunu test etmeden yedek aldığını zannetme:
source /etc/restic/env
# Belirli bir snapshot'tan geri yukle
restic restore latest --target /tmp/restore-test
# Belirli bir snapshot ID'si ile
restic restore abc123def456 --target /var/restore/
# Sadece belirli dosyalari geri yukle
restic restore latest
--target /tmp/restore
--include "/var/www/html/wp-content/uploads"
# Snapshot icindeki dosyalara goz at (geriye yüklemeden)
restic ls latest
# Belirli bir dosyanin farkli snapshot'lardaki versiyonlarini bul
restic find --long "*.sql.gz"
# Snapshot'lari karsilastir
restic diff abc123 def456
Geri yükleme testi senaryosu: Ayda en az bir kez /tmp/restore-test gibi bir dizine tam geri yükleme yap ve dosyaların bütünlüğünü kontrol et. Bu testi otomatize etmek de mümkün.
Yedek Bütünlüğünü Doğrulama
source /etc/restic/env
# Repository'nin genel sagligini kontrol et
restic check
# Veri bloklarini da dogrula (daha kapsamli ama yavas)
restic check --read-data
# Sadece rastgele bir orneklem dogrula (%10)
restic check --read-data-subset=10%
# Son snapshot'in istatistiklerini goster
restic stats latest
# Tum repository istatistikleri
restic stats --mode raw-data
restic check komutunu haftada bir cron ile çalıştırmanı öneririm. Sorun varsa e-posta veya Slack bildirimi alman gerekiyor.
Systemd Timer ile Otomatik Yedekleme
Cron yerine systemd timer kullanmak daha modern ve izlenebilir bir yaklaşım. Hem başarısız yedekler için log tutulur hem de systemctl status ile kolayca durumu görebilirsin:
# Service dosyasini olustur
sudo tee /etc/systemd/system/restic-backup.service << 'EOF'
[Unit]
Description=Restic Bulut Yedekleme Servisi
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
EnvironmentFile=/etc/restic/env
ExecStart=/usr/local/bin/backup-postgresql.sh
ExecStartPost=/bin/bash -c 'source /etc/restic/env && restic check --read-data-subset=5%%'
# Basarisiz olursa bildirim gonder (mail komutunun kurulu olmasi gerekir)
OnFailure=restic-backup-failure@%n.service
StandardOutput=journal
StandardError=journal
SyslogIdentifier=restic-backup
EOF
# Timer dosyasini olustur
sudo tee /etc/systemd/system/restic-backup.timer << 'EOF'
[Unit]
Description=Restic Yedekleme Zamanlayicisi
Requires=restic-backup.service
[Timer]
# Her gun saat 02:30'da calistir
OnCalendar=*-*-* 02:30:00
# Sistem kapaliysa, acildiginda calistir
Persistent=true
# Yukun az oldugu zamanlarda calistir
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target
EOF
# Servisleri aktif et
sudo systemctl daemon-reload
sudo systemctl enable restic-backup.timer
sudo systemctl start restic-backup.timer
# Durumu kontrol et
sudo systemctl status restic-backup.timer
sudo systemctl list-timers restic-backup.timer
Timer’ı elle tetiklemek istersen:
sudo systemctl start restic-backup.service
journalctl -u restic-backup.service -f
Backblaze B2 ile Alternatif Konfigürasyon
AWS S3 maliyetli gelebilir, özellikle küçük ve orta ölçekli işletmeler için. Backblaze B2 çok daha uygun fiyatlıdır ve Restic ile mükemmel çalışır:
# B2 icin ortam degiskenlerini ayarla
sudo tee /etc/restic/env-b2 << 'EOF'
export B2_ACCOUNT_ID="hesap-id-buraya"
export B2_ACCOUNT_KEY="uygulama-anahtari-buraya"
export RESTIC_REPOSITORY="b2:bucket-adi:yedekler"
export RESTIC_PASSWORD="sifre-buraya"
EOF
sudo chmod 600 /etc/restic/env-b2
# Repository'yi bashlat
source /etc/restic/env-b2
restic init
# Yedek al
restic backup --verbose /var/www /etc/nginx
B2’nin avantajı, ilk 10 GB depolama ücretsiz ve transfer maliyeti S3’e göre çok daha düşük. Production ortamında hem S3 hem B2 kullanarak 3-2-1 yedekleme stratejisi uygulamak en sağlam yaklaşım.
Çoklu Hedef Yedekleme (3-2-1 Stratejisi)
3-2-1 stratejisi: 3 kopya, 2 farklı medya, 1 offsite. Bunu Restic ile otomatize etmek mümkün:
sudo tee /usr/local/bin/backup-3-2-1.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
LOG_FILE="/var/log/restic/backup_3-2-1_$(date +%Y%m%d).log"
mkdir -p "/var/log/restic"
BACKUP_FAILED=0
backup_to_target() {
local env_file=$1
local target_name=$2
echo "[$(date)] ${target_name} yedeklemesi basliyor..." >> "$LOG_FILE"
source "$env_file"
restic backup
--tag production
--tag "$(hostname)"
--exclude="/proc"
--exclude="/sys"
--exclude="/dev"
--exclude="/tmp"
--exclude="*.log"
/var/www /etc /home
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "[$(date)] ${target_name}: Basarili" >> "$LOG_FILE"
# Saklama politikasini uygula
restic forget
--keep-daily 7
--keep-weekly 4
--keep-monthly 12
--prune >> "$LOG_FILE" 2>&1
else
echo "[$(date)] ${target_name}: HATA!" >> "$LOG_FILE"
BACKUP_FAILED=1
fi
}
backup_to_target "/etc/restic/env-s3" "AWS S3"
backup_to_target "/etc/restic/env-b2" "Backblaze B2"
if [ $BACKUP_FAILED -ne 0 ]; then
echo "Yedekleme basarisiz!" | mail -s "KRITIK: Yedekleme Hatasi - $(hostname)" [email protected]
exit 1
fi
echo "[$(date)] Tum yedeklemeler tamamlandi." >> "$LOG_FILE"
SCRIPT
sudo chmod +x /usr/local/bin/backup-3-2-1.sh
Monitoring ve Alerting
Yedeklemenin çalışıp çalışmadığını izlemek, yedek almak kadar önemli. Healthchecks.io ile basit bir entegrasyon:
# backup-postgresql.sh scriptine ekle
HEALTHCHECK_URL="https://hc-ping.com/uuid-buraya"
# Yedek baslarken
curl -fsS --retry 3 "${HEALTHCHECK_URL}/start" > /dev/null 2>&1
# ... yedekleme islemleri ...
# Basarili bitis
curl -fsS --retry 3 "$HEALTHCHECK_URL" > /dev/null 2>&1
# Hata durumunda
curl -fsS --retry 3 "${HEALTHCHECK_URL}/fail" --data-raw "Hata detayi burada" > /dev/null 2>&1
Alternatif olarak Prometheus ve node_exporter ile metrikleri Grafana’ya göndermek de mümkün, ama küçük ortamlar için Healthchecks.io yeterinden fazla.
Sık Karşılaşılan Sorunlar
“repository already exists” hatası: restic init komutunu zaten başlatılmış bir repository’ye çalıştırmaya çalıştığında alırsın. Sorun değil, mevcut repository’yi kullanmaya devam edebilirsin.
Yavaş yedekleme: İlk yedek her zaman yavaştır çünkü tüm veriler yüklenir. Sonraki yedekler deduplikasyon sayesinde çok daha hızlı tamamlanır.
“lock” hatası: Bir önceki yedekleme düzgün bitmemişse repository kilitli kalabilir. restic unlock ile çözülür ama önce başka bir yedekleme işleminin aktif olmadığından emin ol.
Yüksek bellek kullanımı: Çok büyük dosya yapılarında Restic fazla bellek kullanabilir. --limit-upload ve --pack-size parametrelerini ayarlayarak optimize edebilirsin.
Sonuç
Restic, bulut depolamaya şifreli yedekleme konusunda bugün elimizdeki en olgun araçlardan biri. Kurulumu kolay, güvenilir ve gerçekten ihtiyaç duyduğunda hayat kurtarıyor. Burada anlattıklarımı özetleyeyim:
- Repository’yi doğru yapılandır, şifreyi güvenli bir yerde sakla
- IAM yetkilerini minimum tutarak güvenlik açığı riskini azalt
- Otomatik yedeklemeyi systemd timer ile kur, cron’a güvenme
- 3-2-1 stratejisini uygula, tek hedefe yedek yetmez
- Düzenli olarak
restic checkçalıştır ve geri yükleme testleri yap - Monitoring olmadan yedekleme kör uçuştur
Son olarak şunu söyleyeyim: Yedekleme sistemi kurduğunda bitmez, ayda bir geri yükleme testi yapmazsan yedek almamışsın demektir. “Yedek var” demek ile “yedekten geri yükleyebildim” demek çok farklı şeyler. Test et, doğrula, içini rahat tut.
