Zimbra’da Yedekleme ve Geri Yükleme Stratejileri
Yıllar önce bir müşterimizin Zimbra sunucusu çöktüğünde, üç günlük mail verisini kaybettik. O gün bir daha asla “zaten çalışıyor, yedek almaya gerek yok” cümlesini kurmadım. Zimbra yedekleme konusu, pek çok sysadmin’in ertelediği ama ilk ciddi olayda pişman olduğu bir alan. Bu yazıda teorik bilgiden ziyade, sahada işe yarayan stratejileri ve komutları paylaşacağım.
Zimbra Yedekleme Mimarisini Anlamak
Zimbra’yı yedeklemeden önce neyi yedeklediğinizi anlamanız gerekiyor. Zimbra, birkaç kritik bileşenden oluşur:
- LDAP dizini: Kullanıcı hesapları, dağıtım listeleri, domain ayarları
- Mesaj deposu: Gerçek mail verileri, ekler, takvim ve kişi bilgileri
- MySQL/MariaDB veritabanı: Posta kutusu metadata’sı, alias’lar, konfigürasyon tabloları
- Konfigürasyon dosyaları: LocalConfig, global config ayarları
Bunların hepsini ayrı ayrı yedeklemek yerine bütünleşik bir strateji kurmak, geri yükleme anında hayat kurtarır. Ben genellikle kurumsal ortamlarda iki katmanlı bir yaklaşım kullanıyorum: hot backup (servis ayakta iken) ve cold backup (servis durdurularak).
Hot Backup ile Servis Kesintisiz Yedekleme
Çoğu üretim ortamında posta sunucusunu durdurmak lüks sayılır. Zimbra bu ihtiyaca karşılık olarak kendi içinde bazı araçlar sunar.
zmmailbox ile Posta Kutusu Bazlı Yedek Alma
Tek bir kullanıcının verisini dışa aktarmak için zmmailbox aracı kullanılır. Bu özellikle “sadece şu kullanıcının maillerini kurtar” talepleri için biçilmiş kaftandır:
# zimbra kullanıcısına geç
su - zimbra
# Tek kullanıcı için tam yedek
zmmailbox -z -m [email protected] getRestURL '/?fmt=tgz' > /backup/kullanici_backup_$(date +%Y%m%d).tgz
# Belirli bir klasörü yedekle
zmmailbox -z -m [email protected] getRestURL '/Inbox?fmt=tgz' > /backup/kullanici_inbox_$(date +%Y%m%d).tgz
Bu yöntem küçük ölçekli geri yüklemelerde son derece pratik. Ancak büyük posta kutularında (50GB+ gibi) zaman alır ve Zimbra’nın REST API’si üzerinden çalıştığı için sunucu yükünü artırır.
Tüm Sunucu İçin Sıkıştırılmış Yedekleme Scripti
Gerçek bir üretim ortamı için kullandığım script şu şekilde:
#!/bin/bash
# /usr/local/sbin/zimbra_hot_backup.sh
BACKUP_DIR="/backup/zimbra"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/zimbra_backup.log"
ZIMBRA_HOME="/opt/zimbra"
echo "[$(date)] Zimbra hot backup başlatıldı" >> $LOG_FILE
# LDAP yedeği al
su - zimbra -c "zmlocalconfig -s zimbra_ldap_password" | grep -oP '(?<=zimbra_ldap_password = ).*' > /tmp/ldap_pass.tmp
su - zimbra -c "/opt/zimbra/libexec/zmslapcat $BACKUP_DIR/ldap_$DATE"
if [ $? -eq 0 ]; then
echo "[$(date)] LDAP yedeği alındı" >> $LOG_FILE
else
echo "[$(date)] HATA: LDAP yedeği başarısız!" >> $LOG_FILE
fi
# MySQL/MariaDB yedeği
MYSQL_PASS=$(su - zimbra -c "zmlocalconfig -s zimbra_mysql_password" | grep -oP '(?<=zimbra_mysql_password = ).*')
mysqldump -u zimbra -p"$MYSQL_PASS" --all-databases --single-transaction
> $BACKUP_DIR/mysql_$DATE.sql
gzip $BACKUP_DIR/mysql_$DATE.sql
echo "[$(date)] MySQL yedeği alındı" >> $LOG_FILE
# Konfigürasyon dosyalarını yedekle
tar -czf $BACKUP_DIR/config_$DATE.tar.gz
/opt/zimbra/conf/
/opt/zimbra/ssl/
/opt/zimbra/store/ 2>/dev/null
echo "[$(date)] Konfigürasyon yedeği alındı" >> $LOG_FILE
# 30 günden eski yedekleri temizle
find $BACKUP_DIR -type f -mtime +30 -delete
echo "[$(date)] Eski yedekler temizlendi" >> $LOG_FILE
echo "[$(date)] Hot backup tamamlandı" >> $LOG_FILE
Bu scripti crontab’a eklemek için:
# Her gece 02:00'da çalıştır
0 2 * * * /usr/local/sbin/zimbra_hot_backup.sh
Cold Backup: Tam Yedekleme İçin Doğru Yöntem
Kritik bakım pencerelerinde veya büyük versiyon güncellemelerinden önce cold backup şarttır. Servis durdurulduğunda alınan bu yedekler tutarlılık açısından çok daha güvenilirdir.
#!/bin/bash
# Cold backup scripti - servisi durdurarak tam yedek
BACKUP_DIR="/backup/zimbra/cold"
DATE=$(date +%Y%m%d)
echo "Zimbra servisleri durduruluyor..."
su - zimbra -c "zmcontrol stop"
sleep 30
# Zimbra'nın tüm dizinini yedekle
echo "Ana dizin yedekleniyor..."
rsync -avz --progress /opt/zimbra/ $BACKUP_DIR/zimbra_full_$DATE/
--exclude="*.pid"
--exclude="log/*.log"
--exclude="data/tmp/"
# LDAP yedeği (servis kapalıyken)
echo "LDAP dump alınıyor..."
slapcat -l $BACKUP_DIR/ldap_full_$DATE.ldif
echo "Zimbra servisleri başlatılıyor..."
su - zimbra -c "zmcontrol start"
echo "Cold backup tamamlandı: $BACKUP_DIR"
Burada rsync kullanmayı tercih ediyorum çünkü sonraki yedeklerde sadece değişen dosyaları kopyalıyor ve bu özellikle büyük posta depolarında ciddi zaman kazandırıyor.
Incremental Yedekleme: Gerçek Dünyada Kullanılabilir Strateji
Günlük tam yedek almak hem zaman hem depolama açısından pahalı. Incremental (artımlı) yedekleme ile sadece değişen verileri yedekleyebilirsiniz. Zimbra’nın mesaj deposu için şu yapıyı kullanıyorum:
#!/bin/bash
# Incremental yedekleme - rsync ile
BACKUP_ROOT="/backup/zimbra/incremental"
STORE_PATH="/opt/zimbra/store"
DATE=$(date +%Y%m%d)
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
# İlk tam yedek varsa artımlı al
if [ -d "$BACKUP_ROOT/base" ]; then
rsync -avz --link-dest=$BACKUP_ROOT/base
$STORE_PATH/
$BACKUP_ROOT/inc_$DATE/
echo "Artımlı yedek tamamlandı: inc_$DATE"
else
# İlk kez çalışıyorsa tam yedek al
rsync -avz $STORE_PATH/ $BACKUP_ROOT/base/
echo "Temel yedek oluşturuldu"
fi
# MySQL binlog'larını da yedekle
cp -r /opt/zimbra/db/data/mysql-bin.* $BACKUP_ROOT/binlogs_$DATE/ 2>/dev/null
--link-dest parametresi burada kritik: değişmeyen dosyalar için hard link oluşturur, böylece depolama alanı israf edilmez.
LDAP Verilerini Yönetmek
LDAP, Zimbra’nın iskeletidir. Kullanıcı listesi, domain yapısı, COS (Class of Service) tanımları burada durur. LDAP yedeklemesi ayrı bir önem taşır:
# LDAP'ı dışa aktar (Zimbra çalışırken)
su - zimbra -c "zmlocalconfig -s ldap_master_url"
# ldap verisini ldif formatında dışa aktar
su - zimbra -c "/opt/zimbra/libexec/zmslapcat /tmp/ldap_export"
# Üretilen dosyaları kontrol et
ls -lh /tmp/ldap_export/
# LDAP yedeğini başka bir sunucuya kopyala
scp /tmp/ldap_export/ldap.bak.gz backup-server:/backup/zimbra/ldap/
Bir projede LDAP’ı yanlışlıkla bozdum (evet, olur), ve sadece bu ldif dosyası sayesinde iki saat içinde sistemi eski haline getirebildim. O günden beri LDAP yedeğine özel önem veriyorum.
Geri Yükleme Senaryoları
Yedek almak işin yarısı, asıl mesele o yedeği geri yükleyebilmek. Farklı senaryolar için farklı yaklaşımlar gerekir.
Senaryo 1: Tek Kullanıcı Maillerini Geri Yüklemek
En sık karşılaşılan durum bu. Kullanıcı yanlışlıkla önemli mailleri silmiş ya da hesap başka bir sebepten bozulmuş:
# Kullanıcının TGZ yedeğini geri yükle
su - zimbra
zmmailbox -z -m [email protected] postRestURL '/?fmt=tgz&resolve=reset'
/backup/kullanici_backup_20240115.tgz
# Resolve parametreleri:
# reset: Mevcut veriyi sil, yedeği yükle
# ignore: Çakışmaları atla
# replace: Çakışanları üstüne yaz
# modify: Metadata'yı güncelle ama içeriği koru
resolve parametresini dikkatli kullanın. reset seçeneği mevcut posta kutusunu silerek başlar, bu çoğu zaman istediğiniz şeydir ama bazı durumlarda değil.
Senaryo 2: Veritabanı Geri Yükleme
MySQL/MariaDB bozulması durumunda:
# Zimbra servislerini durdur
su - zimbra -c "zmcontrol stop"
# MySQL'i tek başına başlat
su - zimbra -c "mysql.server start"
# Yedeği geri yükle
MYSQL_PASS=$(su - zimbra -c "zmlocalconfig -s zimbra_mysql_password" |
grep -oP '(?<=zimbra_mysql_password = ).*')
zcat /backup/zimbra/mysql_20240115.sql.gz |
mysql -u zimbra -p"$MYSQL_PASS"
# Tüm servisleri yeniden başlat
su - zimbra -c "zmcontrol start"
Senaryo 3: Tam Sunucu Geri Yükleme
Felaket senaryosu. Sunucu tamamen gitti, yeni bir makineye Zimbra kuruldu ve yedekten dönülecek:
# 1. Aynı hostname ve IP ile yeni sunucu hazırla
# 2. Aynı Zimbra versiyonunu kur (kritik!)
# 3. Servisleri durdur
su - zimbra -c "zmcontrol stop"
# 4. LDAP'ı geri yükle
su - zimbra -c "zmcontrol stop"
service slapd stop
# Mevcut LDAP verisini temizle
rm -rf /opt/zimbra/data/ldap/hdb/db/*
# Yedeği geri yükle
slapadd -l /backup/zimbra/ldap_full_20240115.ldif
# Dosya sahipliklerini düzelt
chown -R zimbra:zimbra /opt/zimbra/data/ldap/
# 5. Mesaj deposunu geri yükle
rsync -avz /backup/zimbra/cold/zimbra_full_20240115/store/
/opt/zimbra/store/
# 6. Tüm servisleri başlat
su - zimbra -c "zmcontrol start"
# 7. İndeksleri yeniden oluştur (büyük ortamlarda zaman alır)
su - zimbra -c "zmreindex -a start"
Yedek Doğrulama: Yedek Aldım ama Çalışıyor mu?
Asıl sorun burada. Pek çok ekip yedek alır ama hiç test etmez. Bunu otomatikleştirmek için basit bir doğrulama scripti:
#!/bin/bash
# /usr/local/sbin/zimbra_backup_verify.sh
BACKUP_DIR="/backup/zimbra"
ALERT_MAIL="[email protected]"
LOG="/var/log/zimbra_backup_verify.log"
echo "[$(date)] Yedek doğrulama başladı" >> $LOG
# En son yedek dosyalarının varlığını kontrol et
LATEST_MYSQL=$(ls -t $BACKUP_DIR/mysql_*.sql.gz 2>/dev/null | head -1)
LATEST_LDAP=$(ls -t $BACKUP_DIR/ldap_*/ldap.bak.gz 2>/dev/null | head -1)
if [ -z "$LATEST_MYSQL" ]; then
echo "HATA: MySQL yedeği bulunamadı!" |
mail -s "Zimbra Yedek Uyarisi" $ALERT_MAIL
echo "[$(date)] HATA: MySQL yedeği yok" >> $LOG
fi
# MySQL yedeğinin sağlığını kontrol et
if [ -n "$LATEST_MYSQL" ]; then
FILE_AGE=$(( ($(date +%s) - $(stat -c %Y $LATEST_MYSQL)) / 3600 ))
if [ $FILE_AGE -gt 26 ]; then
echo "UYARI: MySQL yedeği $FILE_AGE saat önce alınmış!" |
mail -s "Zimbra Yedek Uyarisi" $ALERT_MAIL
fi
# Dosya boyutu sıfır mı?
FILE_SIZE=$(stat -c %s $LATEST_MYSQL)
if [ $FILE_SIZE -lt 1000 ]; then
echo "HATA: MySQL yedek dosyası çok küçük ($FILE_SIZE bytes)!" |
mail -s "Zimbra Yedek Hatasi" $ALERT_MAIL
fi
fi
echo "[$(date)] Doğrulama tamamlandı" >> $LOG
Bu script’i haftada bir değil, her gün çalıştırın. Yedek sorununu ne kadar erken fark ederseniz o kadar iyi.
Uzak Sunucuya Yedek Aktarımı
Yedeğinizi aynı sunucuda tutmak, sunucu yandığında yedeği de kaybetmek demektir. Basit ama kritik bir nokta:
#!/bin/bash
# Yedekleri uzak sunucuya gönder
BACKUP_DIR="/backup/zimbra"
REMOTE_USER="backupuser"
REMOTE_HOST="192.168.1.100"
REMOTE_DIR="/backup/zimbra-from-prod"
# SSH key authentication kullandığınızı varsayıyoruz
rsync -avz --delete
--exclude="*.tmp"
-e "ssh -p 22 -i /root/.ssh/backup_key"
$BACKUP_DIR/
$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/
if [ $? -eq 0 ]; then
echo "[$(date)] Uzak yedek aktarımı başarılı" >> /var/log/zimbra_backup.log
else
echo "[$(date)] HATA: Uzak yedek aktarımı başarısız!" >> /var/log/zimbra_backup.log
# Burada alert mekanizmanızı tetikleyebilirsiniz
fi
--delete parametresi kullanırken dikkatli olun: uzak sunucuda silinen yerel dosyaların da silinmesini sağlar. Bir felaket senaryosunda bu istenmeyebilir. Uzun süreli saklama için --backup ve --backup-dir kombinasyonunu değerlendirin.
Zimbra Network Edition Kullanıcıları İçin
Eğer Zimbra Network Edition kullanıyorsanız, yerleşik backup aracı hayatı kolaylaştırır. Ama bu aracı da doğru yapılandırmak gerekir:
# Network Edition backup aracını yapılandır
su - zimbra
# Backup location ayarla
zmprov modifyConfig zimbraBackupTarget /backup/zimbra
# Backup modunu ayarla (auto veya standard)
zmprov modifyConfig zimbraBackupMode auto
# Otomatik backup zamanlamasını aktif et
zmprov modifyConfig zimbraBackupAutoGroupedNumGroups 7
# Manuel tam yedek başlat
zmbackup -f -a all
# Yedek durumunu kontrol et
zmbackupquery
# Geri yükleme
zmrestore -ra -ct mb -a [email protected] -lb <backup-label>
Network Edition’ın en büyük avantajı incremental mail-level backup yapabilmesi. Tek bir maili dahi geri yükleyebilirsiniz, bu açık kaynak sürümde mümkün değil.
Pratik Öneriler ve Öğrendiğim Dersler
Yıllar içinde Zimbra ortamlarında edindiğim bazı pratik notlar:
- Yedek öncesi servis durumunu kaydet:
zmcontrol status > /tmp/zimbra_status_before_backup.txtile hangi servislerin çalıştığını kaydedin. - Versiyon uyumluluğu kritiktir: Geri yükleme yapacağınız Zimbra versiyonu, yedeği aldığınız versiyon ile aynı olmalı. Versiyon farkı büyükse önce eski versiyona geri yükleyin, sonra yükseltin.
- Store dizini büyük olabilir:
/opt/zimbra/storedizini büyük ortamlarda terabaytlara ulaşabilir. Yedekleme sürenizi ve bant genişliğinizi buna göre planlayın. - Test geri yüklemesi yapın: Her ay bir test ortamında gerçek geri yükleme deneyin. “Yedek var” ile “yedekten geri dönebiliyorum” çok farklı şeyler.
- Log dosyalarını yedeklemeyin:
/opt/zimbra/logdizinini yedeklemenize gerek yok, sadece yer kaplar. - SSL sertifikalarını ayrıca yedekleyin:
/opt/zimbra/ssldizini özellikle ticari sertifika kullananlar için kritik.
Sonuç
Zimbra yedekleme stratejisi tek bir scriptten ibaret değil. LDAP, MySQL, mesaj deposu ve konfigürasyon olmak üzere dört farklı bileşenin koordineli şekilde yedeklenmesi ve en önemlisi periyodik olarak test edilmesi gerekiyor. Hot backup günlük operasyonel ihtiyacı karşılarken, cold backup büyük değişiklikler öncesi güvence sağlıyor. Uzak sunucuya aktarım ise tek nokta arızasını ortadan kaldırıyor.
Şunu net söyleyeyim: en iyi yedekleme stratejisi, test edilmiş olandır. Altta yatan komutları anlayın, scriptlerinizi kendi ortamınıza göre uyarlayın ve her geri yükleme senaryosunu en az bir kez gerçek ortamda deneyin. O an geldiğinde, ve er ya da geç gelir, paniklemek yerine adımları takip etmek isteyeceksiniz.
