Arşiv Oluştururken Dosya İzinlerini ve Sahiplik Bilgilerini Koruma: tar ve ACL Yönetimi
Yıllarca sistem yöneticiliği yapan herkesin başına en az bir kez gelmiştir: Geceleri aceleyle aldığınız bir yedekten geri dönüş yapıyorsunuz, dosyalar yerli yerinde, ama izinler alt üst olmuş. Web sunucusunun www-data kullanıcısına ait olması gereken dizinler root‘a ait, uygulama çalışmıyor, müşteri arıyor. İşte tam bu noktada “tar ile arşiv alırken izinleri korudum mu?” sorusu aklınıza geliyor ve cevabı bilmiyorsanız, o gece çok uzun geçecek.
Bu yazıda tar ile arşiv oluştururken dosya izinlerini, sahiplik bilgilerini ve ACL’leri nasıl düzgün koruyacağınızı, geri yükleme sırasında nelere dikkat etmeniz gerektiğini ve gerçek dünya senaryolarında bu bilgileri nasıl kullanacağınızı ele alacağız.
Temel Kavramlar: tar Varsayılan Davranışı
tar aracı varsayılan olarak dosya izinlerini (okuma/yazma/çalıştırma bitleri) arşive dahil eder. Yani standart bir tar czf arsiv.tar.gz /hedef/dizin komutu çalıştırdığınızda, POSIX izinleri arşivde saklanır. Ancak burada önemli bir nüans var: Sahiplik bilgileri (kullanıcı adı, grup adı, UID, GID) ve özellikle ACL (Access Control List) bilgileri varsayılan olarak her zaman beklediğiniz gibi korunmaz.
Bunu test etmek için basit bir senaryo:
# Test dizini oluşturalım
mkdir -p /tmp/test_izin
echo "test" > /tmp/test_izin/dosya.txt
chmod 640 /tmp/test_izin/dosya.txt
chown 1500:1500 /tmp/test_izin/dosya.txt
# Arşiv oluştur
tar czf /tmp/test_arsiv.tar.gz /tmp/test_izin/
# Arşiv içindeki izin bilgilerine bak
tar tzvf /tmp/test_arsiv.tar.gz
Çıktıda -rw-r----- ve kullanıcı/grup bilgilerini göreceksiniz. Peki geri yükleme sırasında bu bilgiler gerçekten korunuyor mu? İşte asıl soru bu.
Sahiplik Bilgilerini Koruma: –numeric-owner ve –same-owner
Arşivi oluştururken ve geri yüklerken sahiplik bilgilerini korumak için iki önemli parametre var:
–same-owner: Geri yükleme sırasında arşivdeki kullanıcı ve grup sahipliğini olduğu gibi uygular. Bu parametreyi root olarak çalıştırmazsanız, etkisi olmaz.
–numeric-owner: Kullanıcı adı ve grup adı yerine UID/GID numaralarını kullanır. Bu, farklı sistemler arasında yedek taşırken kritik önem taşır.
# Arşiv oluştururken numeric owner kullan
tar czf /backup/uygulama_backup.tar.gz
--numeric-owner
/var/www/html/
# Geri yüklerken sahiplik bilgilerini koru
tar xzf /backup/uygulama_backup.tar.gz
--numeric-owner
--same-owner
-C /var/www/
Neden –numeric-owner önemli? Diyelim ki kaynak sistemde appuser kullanıcısının UID’si 1001, hedef sistemde ise aynı isimli kullanıcının UID’si 1003. Eğer numeric owner kullanmazsanız, tar isim eşleştirmesi yapar ve yanlış UID’ye sahip bir geri yükleme yapabilirsiniz. Farklı sunucular arasında yedek taşıyan herkes bu durumla karşılaşmıştır.
Özel Bit’ler: SUID, SGID ve Sticky Bit
Standart rwx izinlerinin ötesinde, özel bitler de arşivde korunmalı. Özellikle SUID/SGID bitleri olan dosyalar (passwd, sudo gibi sistem araçları) yanlış yönetilirse güvenlik açıklarına veya işlev kayıplarına neden olabilir.
# SUID/SGID bitleri olan dosyaları listele
find /usr/bin -perm /6000 -ls
# Bu dosyaları içeren arşiv oluştur - özel bitleri korur
tar czf /backup/sistem_araclari.tar.gz
--preserve-permissions
/usr/bin/sudo
/usr/bin/passwd
# Arşiv içeriğini kontrol et
tar tzvf /backup/sistem_araclari.tar.gz
–preserve-permissions (ya da kısa haliyle -p): Arşivden çıkarırken izinleri tam olarak korur, umask uygulamaz. Root olarak çalışırken varsayılan olarak aktiftir, ancak açıkça belirtmek iyi bir alışkanlık.
# Geri yüklerken izinleri koru, umask uygulama
tar xzf /backup/sistem_araclari.tar.gz
-p
--same-owner
-C /
ACL Yönetimi: getfacl, setfacl ve tar Entegrasyonu
İşin gerçekten karmaşık kısmına geldik. ACL’ler, standart Unix izin modelinin ötesinde granüler erişim kontrolü sağlar. Ancak tar varsayılan olarak ACL bilgilerini arşive dahil etmez. Bu bilgileri korumak için iki yöntem var.
Yöntem 1: –acls Parametresi (GNU tar)
GNU tar 1.27 ve sonrasında ACL desteği yerleşik olarak geliyor:
# ACL'leri arşive dahil et
tar czf /backup/acl_korumali.tar.gz
--acls
--xattrs
--selinux
/var/www/uygulama/
# Geri yüklerken ACL'leri uygula
tar xzf /backup/acl_korumali.tar.gz
--acls
--xattrs
--selinux
-C /var/www/
–acls: POSIX ACL bilgilerini arşive dahil eder/geri yükler. –xattrs: Genişletilmiş özellik bilgilerini (extended attributes) korur. –selinux: SELinux güvenlik bağlamlarını korur (SELinux kullanan sistemlerde kritik).
Yöntem 2: getfacl/setfacl ile Manuel Yedekleme
Bazen daha granüler kontrol gerekir ya da tar versiyonunuz ACL desteğine sahip değildir. Bu durumda ACL bilgilerini ayrı bir dosyaya yedekleyip geri yükleme zamanı uygulayabilirsiniz:
# Bir dizin için ACL bilgilerini yedekle
getfacl -R /var/www/uygulama/ > /backup/acl_bilgileri.txt
# ACL bilgilerini geri yükle
setfacl --restore=/backup/acl_bilgileri.txt
Bu yöntemi özellikle tar arşivini sistem genelinde taşırken, ACL restore işlemini ayrı bir adım olarak yapmak istediğinizde tercih ediyorum. Daha kontrollü bir süreç sağlıyor.
Gerçek Dünya Senaryosu: Web Sunucusu Yedekleme
Bir üretim web sunucusunu düşünelim. Apache veya Nginx çalışıyor, www-data kullanıcısı var, bazı dizinlere özel ACL’ler tanımlanmış (örneğin geliştirici ekibinin belirli üyelerinin yazma yetkisi var):
#!/bin/bash
# web_backup.sh - Üretim web sunucusu tam yedekleme scripti
BACKUP_DIR="/backup/web"
TARIH=$(date +%Y%m%d_%H%M%S)
WEB_DIZIN="/var/www"
mkdir -p $BACKUP_DIR
# ACL bilgilerini ayrıca kaydet
echo "[INFO] ACL bilgileri kaydediliyor..."
getfacl -R $WEB_DIZIN > $BACKUP_DIR/acl_${TARIH}.txt
# Tam arşiv oluştur
echo "[INFO] Arşiv oluşturuluyor..."
tar czf $BACKUP_DIR/web_${TARIH}.tar.gz
--numeric-owner
--acls
--xattrs
--preserve-permissions
$WEB_DIZIN
echo "[INFO] Arşiv boyutu: $(du -sh $BACKUP_DIR/web_${TARIH}.tar.gz)"
echo "[TAMAM] Yedekleme tamamlandı: web_${TARIH}.tar.gz"
tar ile Arşiv Oluştururken Dikkat Edilmesi Gereken Durumlar
Sembolik Linkler
Sembolik linkler bazen sürpriz yapabilir. --dereference parametresi symlink’in kendisi yerine işaret ettiği dosyayı arşive ekler. Genellikle bu istemediğiniz bir davranıştır:
# Sembolik linkleri olduğu gibi koru (varsayılan - iyi)
tar czf arsiv.tar.gz /hedef/
# Sembolik linklerin gösterdiği dosyaları kopyala (dikkatli kullan)
tar czf arsiv.tar.gz --dereference /hedef/
Sparse Dosyalar
Veritabanı dosyaları veya disk imajları gibi büyük sparse dosyalar içeren dizinleri yedeklerken:
# Sparse dosyaları etkin biçimde işle
tar czf /backup/veritabani.tar.gz
--sparse
--numeric-owner
--acls
/var/lib/mysql/
–sparse: Sparse dosyaları etkili şekilde işler, gereksiz yere büyük arşivler oluşturmaz.
İzin Sorunlarını Tespit Etme ve Doğrulama
Arşiv oluşturduktan sonra içeriği doğrulamak kritik. Özellikle üretim ortamında geri yükleme yapmadan önce arşiv bütünlüğünü ve izin bilgilerini kontrol edin:
# Arşiv içeriğini izin bilgileriyle listele
tar tzvf /backup/web_backup.tar.gz | head -50
# Arşivden çıkarmadan ACL bilgilerini kontrol etmek için
# Önce geçici dizine çıkar, kontrol et
mkdir -p /tmp/test_restore
tar xzf /backup/web_backup.tar.gz
--acls
--xattrs
--numeric-owner
--same-owner
-C /tmp/test_restore/
# Geri yüklenen ACL'leri kontrol et
getfacl -R /tmp/test_restore/var/www/ | head -30
# Temizle
rm -rf /tmp/test_restore
Bu adımı atlamamanızı şiddetle tavsiye ederim. “Yedek aldım” demekle “yedek çalışıyor” demek arasındaki farkı öğrenmek için üretim kesintisi yaşamanız gerekmez.
Farklı Sistemler Arası Taşıma: Dikkat Noktaları
Arşivi bir sistemden alıp başka bir sisteme taşıdığınızda, özellikle farklı dağıtımlar arasında birkaç şeye dikkat etmeniz gerekiyor.
UID/GID Eşleşmesi
# Kaynak sistemde kullanıcı bilgilerini kaydet
getent passwd > /backup/passwd_kaynak.txt
getent group > /backup/group_kaynak.txt
# Hedef sistemde kullanıcıları oluşturmadan önce karşılaştır
diff /backup/passwd_kaynak.txt /etc/passwd
Dosya Sistemi Uyumluluğu
ACL desteği dosya sistemi seviyesinde de gereklidir. Hedef dosya sistemi ACL desteklemiyor olabilir:
# Dosya sisteminin ACL desteğini kontrol et
tune2fs -l /dev/sda1 | grep "Default mount options"
# Veya mount seçeneklerine bak
mount | grep "acl"
# ACL desteği yoksa mount ederken ekle
mount -o remount,acl /dev/sda1 /hedef/dizin
/etc/fstab‘da kalıcı hale getirmek için ilgili satıra acl seçeneğini eklemeyi unutmayın.
Kapsamlı Yedekleme ve Geri Yükleme Scripti
Tüm bu bilgileri bir araya getiren, üretimde kullanılabilecek bir script:
#!/bin/bash
# izin_korumali_yedek.sh
# Kullanim: ./izin_korumali_yedek.sh [yedekle|geri-yukle] [kaynak] [hedef]
set -euo pipefail
ISLEM="${1:-yedekle}"
KAYNAK="${2:-/var/www}"
HEDEF="${3:-/backup}"
TARIH=$(date +%Y%m%d_%H%M%S)
LOG="/var/log/yedekleme.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG
}
yedekle() {
local kaynak=$1
local hedef_dizin=$2
mkdir -p $hedef_dizin
log "Yedekleme basliyor: $kaynak"
log "ACL bilgileri kaydediliyor..."
# ACL bilgilerini ayrı dosyaya kaydet (yedek olarak)
getfacl -R "$kaynak" > "${hedef_dizin}/acl_${TARIH}.txt" 2>/dev/null ||
log "UYARI: ACL bilgileri kaydedilemedi"
# Sahiplik bilgilerini kaydet
find "$kaynak" -printf "%p %U %G %mn" >
"${hedef_dizin}/sahiplik_${TARIH}.txt"
log "Ana arsiv olusturuluyor..."
tar czf "${hedef_dizin}/arsiv_${TARIH}.tar.gz"
--numeric-owner
--acls
--xattrs
--preserve-permissions
--sparse
"$kaynak"
local boyut=$(du -sh "${hedef_dizin}/arsiv_${TARIH}.tar.gz" | cut -f1)
log "Yedekleme tamamlandi. Boyut: $boyut"
log "Arsiv: ${hedef_dizin}/arsiv_${TARIH}.tar.gz"
}
geri_yukle() {
local arsiv=$1
local hedef_dizin=$2
if [ ! -f "$arsiv" ]; then
log "HATA: Arsiv bulunamadi: $arsiv"
exit 1
fi
log "Geri yukleme basliyor: $arsiv -> $hedef_dizin"
# Arşiv bütünlüğünü test et
log "Arsiv butunlugu kontrol ediliyor..."
tar tzf "$arsiv" > /dev/null 2>&1 ||
{ log "HATA: Arsiv bozuk!"; exit 1; }
mkdir -p "$hedef_dizin"
tar xzf "$arsiv"
--numeric-owner
--same-owner
--acls
--xattrs
--preserve-permissions
-C "$hedef_dizin"
log "Geri yukleme tamamlandi."
}
case $ISLEM in
"yedekle")
yedekle "$KAYNAK" "$HEDEF"
;;
"geri-yukle")
geri_yukle "$KAYNAK" "$HEDEF"
;;
*)
echo "Kullanim: $0 [yedekle|geri-yukle] [kaynak] [hedef]"
exit 1
;;
esac
Sık Yapılan Hatalar
Yıllar içinde hem kendi hatalarımdan hem de başkalarından öğrendiklerimi listelemek istiyorum:
- Root olmadan geri yükleme yapmak:
--same-ownerparametresi root olmadan çalışmaz. Sahiplik bilgilerini geri yüklemek içinsudoveya doğrudanrootkullanın. - –acls parametresini unutmak: Arşiv alırken
--aclskullandınız ama geri yüklerken unuttunuz. Her iki tarafta da belirtmek zorunlu. - Dosya sistemi ACL desteğini kontrol etmemek: Hedef dosya sistemi ACL desteklemiyorsa,
--aclsile geri yükleme yapmaya çalıştığınızda sessizce başarısız olabilir ya da hata alırsınız. - Arşivi test etmemek:
tar tzf arsiv.tar.gzile arşiv içeriğini listelemek, geri yükleme öncesi en az yapmanız gereken kontrol. - Mutlak yol kullanırken dikkat:
tar czf arsiv.tar.gz /var/www/komutu/var/www/yolunu arşive dahil eder. Geri yükleme sırasında-Cparametresiyle hedef dizini belirtmezseniz, dosyalar orijinal konuma açılır. Bu bazen istediğiniz, bazen istemediğiniz bir davranıştır.
Sonuç
Dosya izinlerini ve ACL bilgilerini koruyarak arşiv almak, temel sistem yönetimi becerilerinden biri olmakla birlikte detayları göz ardı edilmesi en kolay konulardan da biri. --numeric-owner, --acls, --xattrs, --preserve-permissions ve --same-owner parametrelerini doğru kullanmak, bir felaketten geri dönüş sırasında saatlerce izin düzeltme işiyle uğraşmanızın önüne geçer.
Özetlemek gerekirse: Her zaman --numeric-owner kullanın (farklı sistemler arası taşıma güvenliği için), ACL kullanan sistemlerde --acls --xattrs ekleyin, geri yüklemeyi root olarak --same-owner ile yapın ve arşiv bütünlüğünü üretimde kullanmadan önce test edin. Bu dört kural sizi pek çok baş ağrısından kurtarır.
Bir de şunu söyleyeyim: En iyi zamanı boş zamandır. Üretim kesintisi yaşamadan önce bu komutları bir test ortamında çalıştırın, neyin nasıl davrandığını görün. O gece müşterinin aradığı anı yaşamamak için şimdiden hazır olun.
