Dosya kopyalamak için scp kullanıyorsanız ve büyük dizinleri aktarırken bağlantı kopunca baştan başlamak zorunda kalıyorsanız, ya da her seferinde tüm dosyaları tekrar göndermekten bıktıysanız, doğru yerdesiniz. rsync over SSH bu sorunların hepsini çözen, profesyonel sistem yöneticilerinin vazgeçilmez aracıdır. Sadece değişen dosyaları transfer eder, kesintiden kaldığı yerden devam eder ve SSH’ın tüm güvenlik altyapısını kullanır.
rsync Nedir ve Neden SSH ile Kullanmalıyız?
rsync (Remote Sync), kaynak ile hedef arasındaki farkı hesaplayarak sadece değişen blokları ileten bir senkronizasyon aracıdır. 1996’dan beri hayatımızda olan bu araç, “delta transfer algoritması” sayesinde bant genişliğini son derece verimli kullanır.
Peki neden direkt rsync değil de SSH üzerinden? Çünkü rsync’in kendi protokolü (873/tcp) şifrelenmemiş çalışır. İnternet üzerinden dosya transferi yapıyorsanız bu ciddi bir güvenlik açığıdır. SSH tüneli kullandığınızda:
- Tüm veri akışı şifrelenir
- Kimlik doğrulama SSH’ın güçlü mekanizmalarıyla yapılır
- Ekstra bir daemon veya servis açmanıza gerek kalmaz
- Güvenlik duvarı kurallarını minimum tutabilirsiniz (sadece 22/tcp yeterli)
Temel Sözdizimi ve İlk Transfer
rsync’in temel sözdizimi şöyle:
rsync [seçenekler] kaynak hedef
SSH üzerinden uzak sunucuya dosya göndermek için:
rsync -avz -e ssh /yerel/dizin/ kullanici@sunucu:/uzak/dizin/
Uzak sunucudan yerel makineye çekmek için:
rsync -avz -e ssh kullanici@sunucu:/uzak/dizin/ /yerel/dizin/
Burada dikkat edilmesi gereken kritik bir nokta var: dizin sonundaki / işareti. Bu küçük karakter büyük fark yaratır.
# Dizinin kendisini kopyalar (hedefte /yedek/belgeler/ oluşur)
rsync -av /home/ahmet/belgeler /yedek/
# Dizinin içeriğini kopyalar (hedefte /yedek/ altına dosyalar gelir)
rsync -av /home/ahmet/belgeler/ /yedek/
Temel Parametreler
En sık kullanacağınız parametreleri açıklayalım:
- -a (–archive): Arşiv modu. İzinleri, sahipleri, zaman damgalarını, sembolik linkleri korur. Hemen her zaman kullanmanız gereken seçenek.
- -v (–verbose): Ne yapıldığını ekranda gösterir. Debug için kullanışlı.
- -z (–compress): Transfer sırasında veriyi sıkıştırır. Yavaş bağlantılarda işe yarar, LAN’da gereksiz CPU tüketir.
- -P:
--progressve--partialbirleşimi. İlerlemeyi gösterir ve yarım kalan dosyaları saklar. - -n (–dry-run): Gerçekten bir şey yapmaz, sadece ne yapacağını gösterir. Kritik işlemler öncesi mutlaka kullanın.
- -h (–human-readable): Boyutları insan okuyabilir formatta gösterir (MB, GB gibi).
- –delete: Kaynakta olmayan dosyaları hedeften siler. Tam senkronizasyon için gerekli.
- -r (–recursive): Alt dizinleri de kopyalar.
-azaten bunu içerir. - –exclude: Belirli dosya veya dizinleri atlar.
- –bwlimit: Bant genişliği limitini KB/s cinsinden belirler.
- –checksum: Zaman damgası yerine checksum karşılaştırması yapar. Yavaş ama kesin.
Gerçek Dünya Senaryo 1: Web Sunucusu Yedeği
Diyelim ki production web sunucunuzun /var/www/html dizinini her gece yedek sunucuya göndermeniz gerekiyor. Basit bir scp ile bunu yaparsanız her seferinde tüm site dosyaları transfer edilir. rsync ile sadece değişenler gider.
rsync -avzP
--delete
--exclude='.git/'
--exclude='*.log'
--exclude='cache/'
--exclude='tmp/'
-e "ssh -p 22 -i /root/.ssh/yedek_rsa"
/var/www/html/
[email protected]:/yedekler/web/$(date +%Y-%m-%d)/
Bu komutu inceleyelim:
--delete parametresi kaynakta silinmiş dosyaları hedefte de siler, gerçek bir ayna yedek oluşturur. .git/, *.log, cache/ ve tmp/ dizinlerini atlıyoruz çünkü bunları yedeklemek anlamsız. -i parametresi ile özel SSH anahtarı belirtiyoruz, şifre sormadan otomatik çalışsın diye.
Bunu cron’a ekleyelim:
# /etc/cron.d/web-yedek
0 2 * * * root /usr/local/bin/web-yedek.sh >> /var/log/web-yedek.log 2>&1
SSH Anahtar Tabanlı Kimlik Doğrulama Kurulumu
rsync’i otomatize etmek istiyorsanız şifresiz SSH anahtarı kurulumu şart. Şifre sorulursa cron job çalışmaz.
# Yedekleme için özel anahtar çifti oluştur
ssh-keygen -t ed25519 -f /root/.ssh/yedek_ed25519 -C "yedekleme-anahtari" -N ""
# Public key'i uzak sunucuya kopyala
ssh-copy-id -i /root/.ssh/yedek_ed25519.pub [email protected]
# Test et
ssh -i /root/.ssh/yedek_ed25519 [email protected] echo "Bağlantı başarılı"
Güvenliği bir adım ileri taşımak için uzak sunucudaki ~/.ssh/authorized_keys dosyasında bu anahtarı sadece rsync çalıştırabilecek şekilde kısıtlayabilirsiniz:
# authorized_keys dosyasına şu şekilde ekleyin
command="rsync --server --sender -avzlogDtprze.isfxC . /yedekler/",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...anahtariniz...
Bu sayede bu anahtar sadece rsync komutunu çalıştırabilir, sunucuya shell erişimi sağlayamaz. Production ortamında güçlü bir güvenlik katmanıdır.
Gerçek Dünya Senaryo 2: Büyük Dosya Transferinde Kesinti Yönetimi
10 GB’lık bir veritabanı dump’ını başka bir sunucuya gönderiyorsunuz ve bağlantı kesildi. scp ile baştan başlamanız gerekir. rsync ile kaldığı yerden devam eder:
rsync -avP
--partial-dir=/tmp/rsync-parcali
-e "ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3"
/yedekler/veritabani_dump_2024.sql.gz
kullanici@uzak-sunucu:/gelen/
--partial-dir parametresi yarım kalan dosyayı geçici dizinde saklar, transfer tamamlandığında hedef konuma taşır. ServerAliveInterval=60 ise SSH’ın her 60 saniyede bir keepalive paketi göndermesini sağlar, boşta bağlantı kesilmesini engeller.
Gerçek Dünya Senaryo 3: Çift Yönlü Senkronizasyon ve Bant Genişliği Yönetimi
Bir müşteri senaryosu: Gündüz production’da çalışan dosyalar var, gece bunları DR (Disaster Recovery) sitesine aktarmanız gerekiyor. Ama gece bile network %100 dolmasın çünkü başka şeyler de çalışıyor.
rsync -avz
--bwlimit=50000
--delete
--stats
--log-file=/var/log/dr-senkron.log
-e "ssh -c aes128-ctr -i /root/.ssh/dr_key"
/data/production/
[email protected]:/data/production/
--bwlimit=50000 bant genişliğini 50 MB/s ile sınırlar. --stats komut sonunda özet istatistik gösterir, kaç dosya işlendiğini, ne kadar veri gittiğini raporlar. -c aes128-ctr ise daha hafif bir şifreleme algoritması kullanır, CPU yükünü azaltır (güvenlik ihtiyacınıza göre seçin).
Dry Run ile Güvenli Test
Production sistemlerde --dry-run veya -n parametresi hayat kurtarır. Özellikle --delete kullanıyorsanız neyin silineceğini önceden görmek kritik önem taşır.
# Ne yapacağını göster ama yapma
rsync -avzn
--delete
/kaynak/dizin/
kullanici@sunucu:/hedef/dizin/
# Çıktıyı daha iyi analiz etmek için
rsync -avzn --delete /kaynak/ kullanici@sunucu:/hedef/ | grep "^deleting"
grep "^deleting" sadece silinecek dosyaları filtreler. Kritik bir yedekleme scriptini production’a almadan önce bu adımı atlamamanızı şiddetle tavsiye ederim. Bir --delete komutuyla yanlış dizini sildiğinizde geri dönüş olmayabilir.
Exclude Kalıpları ile İnce Ayar
rsync -avz
--exclude={'*.tmp','*.bak','*.swp','.DS_Store'}
--exclude='.git/'
--exclude='node_modules/'
--exclude='__pycache__/'
--exclude='*.pyc'
-e ssh
/projeler/uygulama/
deploy-kullanici@prod-sunucu:/var/www/uygulama/
Daha fazla exclude varsa bunları bir dosyaya yazıp --exclude-from ile kullanabilirsiniz:
# /etc/rsync-exclude.txt dosyası
*.tmp
*.bak
*.log
.git/
node_modules/
__pycache__/
.env
secrets/
rsync -avz
--exclude-from=/etc/rsync-exclude.txt
-e ssh
/projeler/
kullanici@sunucu:/hedef/
Snapshot Tarzı Yedekleme: –link-dest Kullanımı
rsync’in en güçlü özelliklerinden biri --link-dest parametresidir. Bu parametre ile Time Machine benzeri, her gün tam gibi görünen ama aslında sadece değişen dosyaları depolayan yedek sistemi kurabilirsiniz.
#!/bin/bash
# /usr/local/bin/snapshot-yedek.sh
KAYNAK="/home/"
HEDEF_SUNUCU="[email protected]"
HEDEF_DIZIN="/yedekler/snapshot"
TARIH=$(date +%Y-%m-%d)
DUN=$(date -d "yesterday" +%Y-%m-%d)
rsync -avz
--delete
--link-dest="${HEDEF_DIZIN}/${DUN}"
-e "ssh -i /root/.ssh/snapshot_key"
"${KAYNAK}"
"${HEDEF_SUNUCU}:${HEDEF_DIZIN}/${TARIH}/"
echo "Snapshot tamamlandi: ${TARIH}"
--link-dest parametresi önceki yedekteki değişmemiş dosyalar için hard link oluşturur. Yani disk alanı kullanmadan her gün “tam yedek” görünümlü snapshot elde edersiniz. 30 günlük snapshot tutmanız gerekse bile disk kullanımı gerçekte çok azdır.
rsync Çıktısını Okumak
Verbose modda rsync çıktısı ilk bakışta karmaşık görünebilir. --itemize-changes parametresi her dosya için ne yapıldığını kodlu olarak gösterir:
rsync -avz --itemize-changes -e ssh /kaynak/ kullanici@sunucu:/hedef/
Çıktıdaki kodlar şöyle okunur:
- >f+++++++++: Yeni dosya gönderildi
- >f.st……: Dosyanın boyutu ve zaman damgası değişti
- .f..t…..: Sadece zaman damgası değişti
- cd+++++++++: Yeni dizin oluşturuldu
- *deleting: Bu dosya silinecek
Bu kodları anlamak, büyük senkronizasyonlarda neyin neden transfer edildiğini anlamanızı sağlar.
Performans İpuçları
LAN içinde büyük miktarda veri kopyalıyorsanız şifreleme yükünü azaltmak için daha hızlı algoritmalar kullanabilirsiniz:
# LAN için daha hızlı ama yeterince güvenli
rsync -avz
-e "ssh -c [email protected]"
/kaynak/
kullanici@yerel-sunucu:/hedef/
# Çok güvenilir bir LAN'da şifrelemeyi tamamen atlayıp rsync daemon kullanmak mümkün
# ama internet üzerinden asla bunu yapmayın
Paralel transfer için birden fazla rsync işlemi başlatabilirsiniz:
# GNU Parallel ile farklı dizinleri aynı anda aktar
parallel rsync -avz -e ssh {} kullanici@sunucu:/hedef/ ::: /dizin1/ /dizin2/ /dizin3/
Monitoring ve Loglama
Production ortamda rsync işlemlerini loglamak ve izlemek önemlidir:
#!/bin/bash
# Gelişmiş yedekleme scripti
LOG_DOSYA="/var/log/rsync-yedek-$(date +%Y%m%d).log"
BASLA=$(date +%s)
echo "=== Yedekleme Başladı: $(date) ===" >> "${LOG_DOSYA}"
rsync -avz
--delete
--stats
--log-file="${LOG_DOSYA}"
--log-file-format="%t %o %f %b"
-e "ssh -i /root/.ssh/yedek_key"
/data/
[email protected]:/yedekler/data/
DURUM=$?
BITIS=$(date +%s)
SURE=$((BITIS - BASLA))
if [ "${DURUM}" -eq 0 ]; then
echo "=== Yedekleme Başarılı: ${SURE} saniye ===" >> "${LOG_DOSYA}"
# Başarı bildirimi gönderilebilir
else
echo "=== HATA: Yedekleme Başarısız (Kod: ${DURUM}) ===" >> "${LOG_DOSYA}"
# Alert gönderilebilir: mail, Slack webhook vb.
echo "rsync yedekleme HATASI: Çıkış kodu ${DURUM}" | mail -s "Yedek HATALI" [email protected]
fi
# 30 günden eski logları temizle
find /var/log/ -name "rsync-yedek-*.log" -mtime +30 -delete
Yaygın Sorunlar ve Çözümleri
“Permission denied” hatası: Hedef dizine yazma izniniz yoktur. Uzak sunucuda dizin izinlerini kontrol edin veya --rsync-path="sudo rsync" kullanın.
rsync -avz -e ssh
--rsync-path="sudo rsync"
/kaynak/
kullanici@sunucu:/root/korunan-dizin/
Uzak sunucuda sudo rsync için sudoers ayarı:
# /etc/sudoers.d/rsync-izin
kullanici ALL=NOPASSWD: /usr/bin/rsync
“Broken pipe” ve bağlantı kopmaları: Uzun transferlerde SSH timeout olabilir. SSH config dosyasına ekleyin:
# ~/.ssh/config
Host yedek-sunucu
HostName 192.168.1.50
User yedek-kullanici
IdentityFile ~/.ssh/yedek_key
ServerAliveInterval 60
ServerAliveCountMax 10
TCPKeepAlive yes
Farklı SSH portu kullanımı:
rsync -avz -e "ssh -p 2222" /kaynak/ kullanici@sunucu:/hedef/
Sembolik linklerin hedefte kopya olarak oluşturulması:
Sembolik linki takip edip içeriği kopyalamak istiyorsanız -L veya --copy-links ekleyin:
rsync -avzL -e ssh /kaynak/ kullanici@sunucu:/hedef/
Windows ile rsync Köprüsü
Windows yöneticileri de rsync’ten mahrum değil. WSL2 (Windows Subsystem for Linux) veya Cygwin ile Windows’tan Linux sunuculara rsync yapabilirsiniz.
WSL2 ile:
# WSL2 terminal içinde normal rsync komutu çalışır
rsync -avz -e ssh /mnt/c/Kullaniciler/Ahmet/Belgeler/ kullanici@linux-sunucu:/yedekler/belgeler/
Linux’tan Windows’a FreeFileSync veya Rsync for Windows (DeltaCopy) alternatifleri de mevcuttur ama gerçek rsync deneyimi için WSL2 açık ara en iyi seçenek.
Sonuç
rsync over SSH, sistem yöneticisinin araç kutusunda olmazsa olmaz bir araçtır. Basit bir dosya kopyalamanın çok ötesinde, akıllı delta transferi, bant genişliği yönetimi, snapshot yedekleme ve güvenli şifreli aktarım bir arada sunar.
Öğrenme eğrisi nispeten düz: Temel komutları öğrenmek birkaç saatinizi alır, ama --delete, --dry-run ve --link-dest gibi parametreler konusunda dikkatsiz olmak veri kaybına yol açabilir. Bu yüzden production’da her önemli rsync komutunu önce -n ile test etmeyi alışkanlık haline getirin.
Büyük dosya transferlerinde -P ile ilerleme takibi yapın, otomasyonda mutlaka SSH anahtar tabanlı kimlik doğrulaması kullanın ve kritik yedekleme scriptlerinizi loglamayla donatın. Gece 3’te patlayan bir yedekleme scripti hakkında “ne oldu, ne kadar gitti, neden durdu” sorularına loglar olmadan cevap vermek ciddi stres kaynağıdır.
rsync’i ne kadar çok kullanırsanız, eski cp ve scp alışkanlıklarınıza o kadar az dönmek isteyeceksiniz. Bu araçla hem zaman hem bant genişliği hem de sinir tasarrufu yapacaksınız.