attr Komutu ile Genişletilmiş Kullanıcı Öznitelikleri (xattr) Yönetimi
Dosya sistemlerinde metadata yönetimi denince çoğu sysadmin aklına hemen chmod, chown ya da stat gelir. Ama işin derinlerine indiğinizde, Linux’un dosya sistemlerine gömülü çok daha zengin bir metadata katmanı olduğunu görürsünüz: genişletilmiş öznitelikler (extended attributes, kısaca xattr). attr komutu ve kardeşi getfattr/setfattr araçları bu katmanı yönetmenizi sağlar. Ben bu araçları ilk kez bir güvenlik audit projesinde kullandım ve o günden beri araç kutusunun vazgeçilmez bir parçası haline geldi.
Genişletilmiş Öznitelikler Nedir?
Klasik POSIX dosya metadata’sı (sahip, grup, izinler, zaman damgaları) dosya hakkında sınırlı bilgi taşır. Genişletilmiş öznitelikler ise bu sınırı aşarak dosyaya key-value çiftleri şeklinde keyfi metadata bağlamanıza olanak tanır.
Dört temel namespace vardır:
- user: Kullanıcı tanımlı öznitelikler. Normal kullanıcılar tarafından ayarlanabilir, en sık kullanılan namespace budur.
- system: Çekirdek ve sistem bileşenleri tarafından kullanılır (örn. POSIX ACL’ler burada saklanır).
- security: SELinux etiketleri ve benzeri güvenlik bilgileri bu namespace’de tutulur.
- trusted: Yalnızca root tarafından erişilebilir, genellikle filesystem daemon’ları kullanır.
Önemli bir not: xattr desteği dosya sistemine göre değişir. ext2/3/4, XFS, Btrfs, ZFS bu özelliği destekler. FAT32 veya eski NFS mount’larında bu özellik çalışmaz.
Kurulum ve Hazırlık
Çoğu modern dağıtımda attr paketi zaten yüklüdür, ama yoksa:
# Debian/Ubuntu
sudo apt install attr
# RHEL/CentOS/Rocky Linux
sudo dnf install attr
# Arch Linux
sudo pacman -S attr
Kernel seviyesinde xattr desteğini kontrol etmek için:
# Mount seçeneklerinde user_xattr'ı arayın
mount | grep -i xattr
# Ya da doğrudan dosya sistemine bakın
tune2fs -l /dev/sda1 | grep -i features
ext4 dosya sistemlerinde xattr desteği varsayılan olarak etkindir, ama özellikle eski sistemlerde mount seçeneklerinde user_xattr parametresini açıkça belirtmeniz gerekebilir:
# /etc/fstab'da
UUID=xxxx-xxxx /data ext4 defaults,user_xattr 0 2
attr Komutunun Temel Kullanımı
attr komutu iki ana işlev sunar: öznitelik okuma ve öznitelik yazma.
Öznitelik Setleme
# Temel sözdizimi
attr -s öznitelik_adı -V "değer" dosya
# Örnek: Bir dosyaya versiyon bilgisi eklemek
attr -s version -V "1.0.3" /opt/myapp/config.conf
# Birden fazla öznitelik eklemek
attr -s author -V "mehmet.yilmaz" /opt/myapp/config.conf
attr -s environment -V "production" /opt/myapp/config.conf
attr -s last_reviewed -V "2024-01-15" /opt/myapp/config.conf
Öznitelik Okuma
# Belirli bir özniteliği oku
attr -g version /opt/myapp/config.conf
# Tüm öznitelikleri listele
attr -l /opt/myapp/config.conf
Öznitelik Silme
attr -r version /opt/myapp/config.conf
attr komutunun parametrelerine bakacak olursak:
- -s name: Öznitelik setler (set)
- -g name: Öznitelik değerini alır (get)
- -r name: Özniteliği siler (remove)
- -l: Tüm öznitelikleri listeler (list)
- -V value: Setlenecek değeri belirtir
- -q: Sessiz mod, sadece değeri döner
- -e enc: Çıktı encoding’i (hex, base64, text)
getfattr ve setfattr: Daha Güçlü Alternatifler
attr komutu kullanışlı olmakla birlikte, getfattr ve setfattr araçları daha detaylı kontrol imkanı verir ve namespace konusunda daha esnektir.
# Tüm öznitelikleri namespace dahil görmek
getfattr -d /opt/myapp/config.conf
# Belirli namespace'deki öznitelikleri görmek
getfattr -n user.version /opt/myapp/config.conf
# Recursive olarak bir dizindeki tüm dosyaların özniteliklerini görmek
getfattr -R -d /opt/myapp/
# setfattr ile öznitelik setlemek
setfattr -n user.deploy_date -v "2024-01-20" /opt/myapp/app.jar
# setfattr ile öznitelik silmek
setfattr -x user.deploy_date /opt/myapp/app.jar
Dikkat: attr komutu user. prefix’ini otomatik ekler, ama getfattr/setfattr ile namespace’i açıkça belirtmeniz gerekir.
Gerçek Dünya Senaryoları
Senaryo 1: Deployment Takibi
Özellikle CI/CD pipeline’ı olan ortamlarda, üretim sunucusundaki binary veya konfigürasyon dosyalarının tam olarak hangi commit’ten geldiğini bulmak ciddi bir sorun olabilir. xattr bu problemi zarif bir şekilde çözer:
#!/bin/bash
# deploy_tag.sh - Deployment sırasında çalıştırılır
DEPLOY_FILE="/opt/myapp/app.jar"
GIT_COMMIT=$(git rev-parse HEAD)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
DEPLOY_USER=$(whoami)
DEPLOY_DATE=$(date -Iseconds)
setfattr -n user.git_commit -v "$GIT_COMMIT" "$DEPLOY_FILE"
setfattr -n user.git_branch -v "$GIT_BRANCH" "$DEPLOY_FILE"
setfattr -n user.deployed_by -v "$DEPLOY_USER" "$DEPLOY_FILE"
setfattr -n user.deploy_timestamp -v "$DEPLOY_DATE" "$DEPLOY_FILE"
echo "Deployment metadata kaydedildi: $DEPLOY_FILE"
echo "Commit: $GIT_COMMIT"
Sonradan bu bilgilere ulaşmak için:
#!/bin/bash
# check_deploy.sh
DEPLOY_FILE="/opt/myapp/app.jar"
echo "=== Deployment Bilgileri: $DEPLOY_FILE ==="
echo "Git Commit: $(getfattr -n user.git_commit --only-values "$DEPLOY_FILE" 2>/dev/null)"
echo "Branch: $(getfattr -n user.git_branch --only-values "$DEPLOY_FILE" 2>/dev/null)"
echo "Deploy Eden: $(getfattr -n user.deployed_by --only-values "$DEPLOY_FILE" 2>/dev/null)"
echo "Deploy Tarihi: $(getfattr -n user.deploy_timestamp --only-values "$DEPLOY_FILE" 2>/dev/null)"
Bu yöntemi bir prodüksiyon ortamında kullanmaya başladığımızda, “Bu binary ne zaman deploy edildi?” sorusunun cevabını artık log dosyalarında aramak zorunda kalmıyoruz.
Senaryo 2: Dosya Güvenlik Sınıflandırması
Hassas belge yönetimi yapan ortamlarda dosyaların güvenlik sınıfını metadata olarak taşımak, audit süreçlerini kolaylaştırır:
#!/bin/bash
# classify.sh - Dosya güvenlik sınıflandırma aracı
classify_file() {
local file="$1"
local level="$2" # public, internal, confidential, restricted
local owner="$3"
case $level in
public|internal|confidential|restricted)
setfattr -n user.security_class -v "$level" "$file"
setfattr -n user.classified_by -v "$owner" "$file"
setfattr -n user.classified_date -v "$(date -Iseconds)" "$file"
echo "[OK] $file -> $level olarak sınıflandırıldı"
;;
*)
echo "[HATA] Geçersiz sınıflandırma seviyesi: $level"
return 1
;;
esac
}
# Kullanım
classify_file "/data/reports/q4_financials.xlsx" "confidential" "finance_team"
classify_file "/data/docs/onboarding.pdf" "internal" "hr_team"
# Tüm confidential dosyaları bul
find /data -type f -exec bash -c '
val=$(getfattr -n user.security_class --only-values "$1" 2>/dev/null)
[[ "$val" == "confidential" ]] && echo "$1"
' _ {} ;
Senaryo 3: Backup ve Arşiv Metadata Yönetimi
Backup sistemlerinde kaynak bilgilerini dosyayla birlikte taşımak istersiniz:
#!/bin/bash
# archive_with_meta.sh
SOURCE_DIR="/var/www/html"
ARCHIVE="/backup/www_$(date +%Y%m%d).tar.gz"
# Önce arşivi oluştur
tar czf "$ARCHIVE" "$SOURCE_DIR"
# Arşive metadata ekle
setfattr -n user.source_path -v "$SOURCE_DIR" "$ARCHIVE"
setfattr -n user.created_by -v "$(whoami)@$(hostname)" "$ARCHIVE"
setfattr -n user.creation_date -v "$(date -Iseconds)" "$ARCHIVE"
setfattr -n user.file_count -v "$(find $SOURCE_DIR -type f | wc -l)" "$ARCHIVE"
setfattr -n user.checksum -v "$(sha256sum $ARCHIVE | awk '{print $1}')" "$ARCHIVE"
echo "Arşiv oluşturuldu ve metadata eklendi: $ARCHIVE"
# Arşiv doğrulama
echo ""
echo "=== Arşiv Metadata ==="
getfattr -d "$ARCHIVE"
SELinux Context ve xattr İlişkisi
SELinux kullanan sistemlerde (RHEL, CentOS, Rocky Linux) güvenlik context’leri aslında security namespace’inde xattr olarak saklanır:
# Dosyanın SELinux context'ini xattr üzerinden doğrudan görmek
getfattr -n security.selinux /var/www/html/index.html
# Çıktı şuna benzer:
# security.selinux="system_u:object_r:httpd_sys_content_t:s0"
# Normal yoldan context görmek
ls -Z /var/www/html/index.html
Bu ilişkiyi anlamak, özellikle restorecon komutunun neden işe yaradığını kavramak açısından önemlidir. restorecon aslında SELinux policy’e göre doğru security.selinux xattr değerini yeniden yazar.
rsync ve cp ile xattr Kopyalama
Dikkat edilmesi gereken kritik bir nokta: standart cp ve rsync komutları varsayılan olarak xattr’ları kopyalamaz!
# cp ile xattr kopyalamak için --preserve=xattr
cp --preserve=xattr kaynak.txt hedef.txt
# Tüm öznitelikleri koruyarak kopyalamak
cp --preserve=all kaynak.txt hedef.txt
# rsync ile xattr kopyalamak için -X flag'i
rsync -avX /kaynak/ /hedef/
# Hem ACL hem xattr koruyarak rsync
rsync -avAX /kaynak/ /hedef/
Bir projede “neden deploy metadata’sı kayboldu?” diye saatlerce inceledikten sonra bulduğumuz sorun tam da buydu: deployment script’i cp ile dosyayı kopyalıyordu ama --preserve=xattr yoktu. Sonradan tüm deployment script’lerini gözden geçirdik.
tar ile xattr Yönetimi
# xattr'ları koruyarak arşivleme (GNU tar)
tar --xattrs -czf arsiv.tar.gz /veri/
# xattr'ları koruyarak çıkarma
tar --xattrs -xzf arsiv.tar.gz
# Hem xattr hem ACL koruyarak
tar --xattrs --acls -czf arsiv.tar.gz /veri/
Not: --xattrs flag’i GNU tar’a özgüdür, BSD tar (macOS’ta varsayılan) farklı davranır.
Güvenlik ve Sınırlamalar
xattr kullanımında göz önünde bulundurmanız gereken bazı pratik sınırlamalar var:
- Boyut limiti: Her öznitelik değeri genellikle 64KB ile sınırlıdır, toplam xattr boyutu ise dosya sistemine göre değişir (ext4’te genellikle 4KB).
- Güvenlik açığı:
usernamespace’indeki xattr’lar dosyaya yazma iznine sahip herkes tarafından değiştirilebilir, bu yüzden güvenlik sınıflandırması gibi kritik bilgileri audit olmadan kullanmayın. - Filesystem uyumluluğu: NFS, SMB/CIFS mount’larında xattr desteği konfigürasyona göre değişir.
- Uygulama farkındalığı: Çoğu uygulama xattr’ları bilmez ve yoksayar, bu hem bir avantaj (uygulamaları etkilemez) hem dezavantajdır (xattr’ları anlayan araçlar gerekmez).
# xattr boyutunu test etmek
python3 -c "
import os
# 4KB'dan büyük değer deneme
big_value = 'x' * 5000
os.setxattr('/tmp/test.txt', 'user.test', big_value.encode())
" 2>&1 || echo "Boyut limitine ulaşıldı"
# Dosya sistemindeki xattr limitlerini görmek
tune2fs -l /dev/sda1 2>/dev/null | grep -i "inode size"
Toplu xattr Operasyonları
Gerçek dünyada tek tek dosyalarla değil, binlerce dosyayla uğraşırsınız. İşte bunu yönetmek için bazı pratik yaklaşımlar:
#!/bin/bash
# bulk_xattr.sh - Toplu xattr yönetimi
# Belirli uzantılı tüm dosyalara metadata ekle
find /data/configs -name "*.conf" -type f | while read -r file; do
setfattr -n user.config_type -v "application" "$file"
setfattr -n user.managed_by -v "ansible" "$file"
done
# xattr değerine göre dosyaları bul ve işlem yap
find /var/log -type f | while read -r logfile; do
current_class=$(getfattr -n user.retention_days --only-values "$logfile" 2>/dev/null)
if [[ -z "$current_class" ]]; then
# Retention bilgisi yoksa varsayılan ekle
setfattr -n user.retention_days -v "30" "$logfile"
setfattr -n user.auto_tagged -v "true" "$logfile"
fi
done
echo "Toplu tagging tamamlandı."
# xattr dump raporu oluşturma
echo "=== xattr Envanter Raporu: $(date) ===" > /tmp/xattr_report.txt
getfattr -R -d /data/ 2>/dev/null >> /tmp/xattr_report.txt
echo "Rapor: /tmp/xattr_report.txt"
Troubleshooting
Sık karşılaşılan sorunlar ve çözümleri:
# "Operation not supported" hatası alıyorsanız
# Dosya sisteminin xattr destekleyip desteklemediğini kontrol edin
df -T /path/to/file
# tmpfs üzerinde xattr çalışmaz (genellikle /tmp)
# Test için /home veya /opt kullanın
# "No data available" hatası - öznitelik yok anlamına gelir
getfattr -n user.version /dosya 2>&1
# Root olmadan system/trusted namespace'e erişmeye çalışmak
# Bu işlemler permission denied verir, normal davranıştır
# Bir dosyanın tüm xattr'larını temizlemek
getfattr -d -m ".*" /dosya | grep "^user." | sed 's/=.*//' |
xargs -I{} setfattr -x {} /dosya
Sonuç
attr, getfattr ve setfattr araçları, Linux dosya sisteminin genellikle göz ardı edilen ama son derece güçlü bir katmanına erişmenizi sağlar. Deployment takibi, güvenlik sınıflandırması, backup metadata yönetimi gibi kullanım senaryolarında bu araçlar ciddi bir değer katabilir.
Bununla birlikte, xattr’ları sihirli bir çözüm olarak görmemek gerekir. Birkaç kritik gerçek var: xattr’lar dosya sistemine bağlıdır ve her yerde çalışmaz. Güvenlik açısından user namespace’i güvenilir bir erişim kontrolü mekanizması değildir. Ve en önemlisi, cp ve rsync gibi araçları ekstra flag’ler olmadan kullandığınızda xattr’larınızı kaybedebilirsiniz.
Ancak bu sınırlamaları bilerek, doğru bağlamda kullandığınızda xattr tabanlı metadata yönetimi altyapınıza ciddi bir gözlemlenebilirlik ve yönetilebilirlik katmanı ekler. Özellikle deployment pipeline’larında artifact tracking için bu aracı kesinlikle değerlendirmenizi öneririm.
