Restic ile Uzak SFTP Sunucusuna Yedekleme: Kurulum ve Otomasyon Rehberi
Sunucularınızda biriken verilerin bir gün kaybolabileceğini düşündüğünüzde, “acaba yedek var mı?” sorusunun cevabı kritik önem taşır. Rsync ile basit kopyalama yapabilirsiniz, tar.gz arşivleri oluşturabilirsiniz ama bunlar çoğu zaman ya çok yer kaplar ya da sürüm yönetimi açısından yetersiz kalır. İşte bu noktada Restic devreye giriyor. Deduplikasyon, şifreleme ve esnek depolama backend desteğiyle Restic, ciddi bir yedekleme çözümü arayan sysadminlerin gözdesi haline geldi. Bu yazıda SFTP üzerinden uzak bir sunucuya nasıl yedekleme yapacağınızı, bunu otomatikleştireceğinizi ve geri yükleme senaryolarını ele alacağız.
Restic Nedir ve Neden SFTP?
Restic, Go diliyle yazılmış, açık kaynaklı bir yedekleme aracıdır. Temel özellikleri şunlar:
- Deduplikasyon: Aynı veriyi iki kez saklamaz, değişen blokları tespit eder
- Şifreleme: AES-256-CTR ile her şey şifreli saklanır, backend sahibi verinizi göremez
- Anlık görüntüler (snapshots): Her yedekleme bağımsız bir snapshot oluşturur, istediğiniz noktaya dönebilirsiniz
- Doğrulama:
checkkomutuyla repository bütünlüğünü kontrol edebilirsiniz - Çoklu backend desteği: S3, B2, Azure, GCS, REST ve tabii ki SFTP
Peki neden SFTP? Çünkü çoğu şirkette zaten bir yedek sunucusu var, ya da bir VPS kiralıyorsunuz ve SSH erişiminiz mevcut. Ekstra bir servis kurmadan, standart SSH altyapısını kullanarak güvenli yedekleme yapabilmek büyük bir avantaj. Özellikle kurumsal ortamlarda firewall kurallarını minimumda tutmak istediğinizde SSH üzerinden giden SFTP trafiği oldukça tercih edilen bir yaklaşım.
Gereksinimler ve Kurulum
Önce ortamı netleştirelim. Senaryomuzda:
- Kaynak sunucu (yedeklenecek): Ubuntu 22.04, IP: 192.168.1.10
- Hedef sunucu (yedek depolama): Herhangi bir Linux sunucu, IP: 192.168.1.20
- Hedef sunucuda SSH daemon çalışıyor olmalı
- Kaynak sunucudan hedef sunucuya SSH erişimi olmalı
Restic Kurulumu
Ubuntu/Debian tabanlı sistemlerde:
# APT ile kurulum (eski sürüm gelebilir, dikkatli olun)
sudo apt update && sudo apt install restic -y
# En güncel sürüm için GitHub releases kullanın
RESTIC_VERSION=$(curl -s https://api.github.com/repos/restic/restic/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//')
wget https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2
bunzip2 restic_${RESTIC_VERSION}_linux_amd64.bz2
chmod +x restic_${RESTIC_VERSION}_linux_amd64
sudo mv restic_${RESTIC_VERSION}_linux_amd64 /usr/local/bin/restic
# Versiyonu doğrulayın
restic version
RHEL/CentOS/Rocky Linux için:
# EPEL reposundan kurulum
sudo dnf install epel-release -y
sudo dnf install restic -y
# Veya binary indirme yöntemi (aynı şekilde çalışır)
Hedef Sunucuda SFTP Kullanıcısı Oluşturma
Güvenlik açısından iyi bir pratik olarak, yedekleme için ayrı bir kullanıcı oluşturmanızı tavsiye ederim. Bu kullanıcının shell erişimi olmasına gerek yok, sadece SFTP yeterli.
# Hedef sunucuda (192.168.1.20) çalıştırın
sudo useradd -m -s /usr/sbin/nologin backupuser
sudo mkdir -p /backup/restic-repo
sudo chown backupuser:backupuser /backup/restic-repo
# SFTP jail için sshd_config ayarları (opsiyonel ama önerilir)
# /etc/ssh/sshd_config dosyasına ekleyin:
# Match User backupuser
# ChrootDirectory /backup
# ForceCommand internal-sftp
# AllowTcpForwarding no
# X11Forwarding no
SSH Key Tabanlı Kimlik Doğrulama Kurulumu
Otomasyonun olmazsa olmazı şifresiz SSH bağlantısıdır. Kaynak sunucuda:
# Kaynak sunucuda (192.168.1.10) root veya yedekleme yapacak kullanıcı olarak
ssh-keygen -t ed25519 -C "restic-backup-key" -f ~/.ssh/restic_backup_key -N ""
# Public key'i hedef sunucuya kopyalayın
ssh-copy-id -i ~/.ssh/restic_backup_key.pub [email protected]
# Bağlantıyı test edin
ssh -i ~/.ssh/restic_backup_key [email protected]
# SSH config dosyasına alias ekleyin, işleri kolaylaştırır
cat >> ~/.ssh/config << 'EOF'
Host backup-server
HostName 192.168.1.20
User backupuser
IdentityFile ~/.ssh/restic_backup_key
StrictHostKeyChecking yes
EOF
Repository Oluşturma ve İlk Yapılandırma
Restic’te her şey bir “repository” etrafında döner. Repository, tüm yedeklerinizin saklandığı şifreli veri deposudur.
# Repository şifresi için bir dosya oluşturun (otomasyonda kullanılacak)
echo "guclu-bir-sifre-buraya-yazin-123!" > /root/.restic-password
chmod 600 /root/.restic-password
# SFTP repository'yi başlatın
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
init
Başarılı çıktı şuna benzer görünmeli:
created restic repository 3a4b5c6d7e at sftp:backup-server:/backup/restic-repo
Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
Önemli: Bu repository ID’yi ve şifreyi güvenli bir yerde saklayın. Şifreyi kaybederseniz verilerinize erişemezsiniz.
İlk Yedekleme ve Temel Komutlar
Artık yedekleme almaya hazırız. Basit bir örnekle başlayalım:
# /etc ve /home dizinlerini yedekle
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
backup /etc /home
# Belirli dosya/dizinleri hariç tut
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
backup /var/www
--exclude="/var/www/html/cache"
--exclude="*.log"
--exclude="*.tmp"
--exclude-caches
# Snapshot listesini görüntüle
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
snapshots
snapshots çıktısında her yedeklemenin ID’si, tarihi, host adı ve hangi dizinlerin yedeklendiğini göreceksiniz.
Yedekleme Durumunu Kontrol Etme
# Repository bütünlüğünü kontrol et
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
check
# Belirli bir snapshot içeriğini listele
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
ls latest
# İstatistikleri gör (disk kullanımı, deduplikasyon oranı)
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
stats
Geri Yükleme Senaryoları
Yedek almak kadar önemli olan şey, geri yükleyebilmektir. Restic burada da oldukça esnek.
# En son snapshot'tan belirli bir dizine geri yükle
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
restore latest
--target /tmp/restore-test
# Belirli bir snapshot ID'siyle geri yükle
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
restore a1b2c3d4
--target /var/restore
# Sadece belirli dosyaları geri yükle
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
restore latest
--target /tmp/restore
--include "/etc/nginx"
Gerçek dünya senaryosu: Bir MySQL veritabanı sunucusunda /etc/mysql dizinini yanlışlıkla sildim. Restic olmadan saatlerce uğraşabilirdim. restore komutuyla 30 saniyede geri yükledim ve servisi ayağa kaldırdım. Yedek almak değil, geri yükleyebilmek önemli.
Otomasyon: Cron Job ile Düzenli Yedekleme
Şimdi işin gerçek önemli kısmına geliyoruz. Manuel yedekleme alırsınız, sonra unutursunuz. Otomasyon şart.
Yedekleme Scripti Oluşturma
cat > /usr/local/bin/restic-backup.sh << 'SCRIPT'
#!/bin/bash
# Restic Yedekleme Scripti
# Yazar: SysAdmin
# Tarih: $(date)
set -euo pipefail
# Degiskenler
REPOSITORY="sftp:backup-server:/backup/restic-repo"
PASSWORD_FILE="/root/.restic-password"
LOG_FILE="/var/log/restic-backup.log"
BACKUP_DIRS="/etc /home /var/www /opt"
EXCLUDE_PATTERNS=(
"--exclude=/home/*/.cache"
"--exclude=/var/www/*/cache"
"--exclude=*.log"
"--exclude=*.tmp"
"--exclude=*.swap"
"--exclude-caches"
)
RETENTION_DAILY=7
RETENTION_WEEKLY=4
RETENTION_MONTHLY=6
# Log fonksiyonu
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Hata durumunda bildirim (isteğe bagli, mail komutu kurulu olmalidir)
notify_error() {
log "HATA: $1"
# echo "Restic yedekleme hatasi: $1" | mail -s "BACKUP ERROR - $(hostname)" [email protected]
}
log "=== Yedekleme basliyor: $(hostname) ==="
# Yedekleme al
log "Dizinler yedekleniyor: $BACKUP_DIRS"
if restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
backup $BACKUP_DIRS
"${EXCLUDE_PATTERNS[@]}"
--tag "cron"
--tag "$(hostname)"
2>> "$LOG_FILE"; then
log "Yedekleme basarili"
else
notify_error "Yedekleme alınamadı!"
exit 1
fi
# Eski snapshot'lari temizle (retention politikasi)
log "Retention politikasi uygulanıyor..."
if restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
forget
--keep-daily "$RETENTION_DAILY"
--keep-weekly "$RETENTION_WEEKLY"
--keep-monthly "$RETENTION_MONTHLY"
--prune
2>> "$LOG_FILE"; then
log "Retention politikasi uygulandı"
else
notify_error "Forget/prune isleminde hata!"
exit 1
fi
# Repository kontrolu (haftada bir yapmak daha mantikli, ama ornek olsun)
if [ "$(date +%u)" -eq 7 ]; then
log "Haftalik repository kontrolu yapiliyor..."
restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
check 2>> "$LOG_FILE" && log "Repository saglikli"
fi
log "=== Yedekleme tamamlandi ==="
SCRIPT
chmod +x /usr/local/bin/restic-backup.sh
Cron Job Tanımlama
# Root crontab'a ekleyin
crontab -e
# Her gece 02:00'de yedekleme al
0 2 * * * /usr/local/bin/restic-backup.sh >> /var/log/restic-backup.log 2>&1
# Cron log'larını kontrol edin
tail -f /var/log/restic-backup.log
Systemd Timer ile Daha Gelişmiş Otomasyon
Cron işe yarasa da, systemd timer’lar daha fazla kontrol ve loglama imkanı sunar. Özellikle Ubuntu 20.04 ve üzeri sistemlerde systemd timer tercih edilmeli.
# Service dosyasını oluştur
cat > /etc/systemd/system/restic-backup.service << 'EOF'
[Unit]
Description=Restic SFTP Yedekleme Servisi
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
User=root
StandardOutput=journal
StandardError=journal
SyslogIdentifier=restic-backup
[Install]
WantedBy=multi-user.target
EOF
# Timer dosyasını oluştur
cat > /etc/systemd/system/restic-backup.timer << 'EOF'
[Unit]
Description=Gunluk Restic SFTP Yedekleme Zamanlayicisi
Requires=restic-backup.service
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=300
Persistent=true
[Install]
WantedBy=timers.target
EOF
# Servisleri etkinleştir ve başlat
systemctl daemon-reload
systemctl enable restic-backup.timer
systemctl start restic-backup.timer
# Timer durumunu kontrol et
systemctl list-timers restic-backup.timer
# Log'ları takip et
journalctl -u restic-backup.service -f
RandomizedDelaySec=300 parametresi önemli: Eğer çok sayıda sunucunuz varsa ve hepsi aynı anda yedeklemeye başlarsa hedef sunucuyu bunaltabilirsiniz. Bu parametre 0-300 saniye arasında rastgele bir gecikme ekler.
Ortam Değişkenleri ile Daha Temiz Yapılandırma
Uzun restic komutlarını her seferinde yazmaktan kurtulmak için ortam değişkenlerini kullanabilirsiniz:
# /etc/restic-env dosyası oluşturun
cat > /etc/restic-env << 'EOF'
export RESTIC_REPOSITORY="sftp:backup-server:/backup/restic-repo"
export RESTIC_PASSWORD_FILE="/root/.restic-password"
EOF
chmod 600 /etc/restic-env
# Kullanımı:
source /etc/restic-env
restic snapshots
restic backup /etc /home
restic check
Bu yöntemi scripte entegre edebilirsiniz:
#!/bin/bash
source /etc/restic-env
# Artık -r ve --password-file parametrelerine gerek yok
restic backup /etc /home --tag "auto"
restic forget --keep-daily 7 --keep-weekly 4 --prune
Çoklu Sunucu Yönetimi
Onlarca sunucunuz varsa ve hepsinin yedeklerini tek bir SFTP sunucusunda toplamak istiyorsanız, her sunucu için ayrı bir repository klasörü kullanın. Ortak bir scripti Ansible ile dağıtabilirsiniz:
# Her sunucu için hostname bazlı repository yolu
HOSTNAME=$(hostname -s)
REPOSITORY="sftp:backup-server:/backup/restic-repos/${HOSTNAME}"
# İlk kurulumda repository'yi init et (yoksa)
restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
cat config > /dev/null 2>&1 ||
restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
init
# Snapshot'larda hangi host'a ait olduğunu belirtmek için
restic -r "$REPOSITORY"
--password-file "$PASSWORD_FILE"
backup /etc /home
--host "$HOSTNAME"
Sorun Giderme
Karşılaşılan yaygın sorunlar ve çözümleri:
“repo already locked” hatası: Önceki bir yedekleme işlemi yarıda kaldıysa ve kilit kaldırılmadıysa:
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
unlock
SFTP bağlantı sorunları: Debug modunda çalıştırarak detaylı log alın:
restic -r sftp:backup-server:/backup/restic-repo
--password-file /root/.restic-password
-vvv snapshots 2>&1 | head -50
SSH timeout sorunları: ~/.ssh/config dosyasına şu satırları ekleyin:
Host backup-server
HostName 192.168.1.20
User backupuser
IdentityFile ~/.ssh/restic_backup_key
ServerAliveInterval 60
ServerAliveCountMax 3
ConnectTimeout 30
Yetersiz disk alanı uyarısı: prune işlemi düzenli yapılmazsa repository şişer. Bunu izlemek için:
# Repository boyutunu ve snapshot sayısını öğren
restic -r "$RESTIC_REPOSITORY"
--password-file "$PASSWORD_FILE"
stats --mode raw-data
Güvenlik Önerileri
Restic zaten şifreleme yapıyor ama ek katmanlar her zaman iyidir:
- Şifreyi asla script içine gömmeyin, her zaman dosyadan okuyun ve o dosyanın izinlerini
chmod 600yapın - Hedef sunucudaki SFTP kullanıcısını mümkünse
chrootile sınırlayın, shell erişimi vermeyin - SSH key’iniz için passphrase kullanmak istiyorsanız
ssh-agentile yönetin, otomasyonda sorun çıkarır - Repository şifresini ayrı bir yerde (örn: şifreli bir parola yöneticisinde veya başka bir sunucuda) yedekleyin
- Hedef sunucuda
authorized_keysdosyasında yetki kısıtlaması uygulayın:
# Hedef sunucuda backupuser'ın authorized_keys dosyasına şu şekilde ekleyin
# command="internal-sftp",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...
Sonuç
Restic ile SFTP yedeklemesi kurmak göründüğü kadar karmaşık değil. Birkaç saatlik kurulum çalışması sonrasında elinizde deduplikasyon yapan, şifreli, sürümlü ve otomatik çalışan bir yedekleme sistemi oluyor. Benim için en değerli özelliği restore sürecinin hızı ve güvenilirliği. Yedek aldığınızı bilmek güzel, ama gerçek felaket anında çalıştığını görmek daha güzel.
Şu üç maddeyi kesinlikle ihmal etmeyin: Yedeklerinizi düzenli olarak test edin, retention politikanızı ihtiyaçlarınıza göre ayarlayın ve log dosyalarını izleyin. Sessiz kalan bir yedekleme scripti çoğu zaman çalışmayan bir yedekleme scriptidir. journalctl veya log takip araçlarıyla (Prometheus + Alertmanager harika bir ikili) bildirim kurarsanız, gece uyurken bile yedeklerinizin sağlıklı çalıştığından emin olursunuz. Sıradaki yazıda Restic’i Rclone ile birlikte kullanarak aynı yedekleri birden fazla hedefe nasıl gönderebileceğimizi ele alacağım.
