getfacl ve setfacl ile Genişletilmiş Dosya Erişim Kontrol Listeleri (ACL) Yönetimi
Standart Unix izinleri çoğu zaman yeterli gelir. Ama bir gün gelir, patronunuz size şöyle bir şey söyler: “Muhasebe klasörüne hem finans ekibi hem de dış denetçiler erişmeli, ama denetçiler sadece okuyabilmeli, finans ekibi her şeyi yapabilmeli, bir de o klasörde oluşturulan yeni dosyalar otomatik olarak bu kurallara uysun.” Siz de chmod ve chown ile bunu çözmeye çalışırken kendinizi bir çıkmaz sokakta bulursunuz. İşte tam bu noktada ACL devreye girer.
ACL Nedir ve Neden İhtiyacınız Var?
Geleneksel Unix izin modeli üç katmandan oluşur: dosya sahibi, grup ve diğerleri. Bu model 1970’lerin ihtiyaçları için tasarlanmıştı. Günümüzün kurumsal ortamlarında ise tek bir dosyaya birden fazla kullanıcı veya grup için farklı izin seviyeleri tanımlamanız gerekebilir. İşte POSIX ACL (Access Control List) bu boşluğu doldurmak için var.
ACL’ler, standart izinlerin üzerine ek bir katman ekler. Bir dosyaya alice‘e okuma, bob‘a okuma-yazma, developers grubuna çalıştırma izni verirken others‘a hiçbir şey vermeyebilirsiniz. Bunları aynı anda, tek bir dosya üzerinde yönetebilirsiniz.
Linux’ta ACL desteği çoğu modern dosya sisteminde (ext4, xfs, btrfs) varsayılan olarak gelir. Eski sistemlerde veya bazı mount noktalarında acl mount seçeneğini açmanız gerekebilirdi, ancak günümüz dağıtımlarında bu neredeyse her zaman hazır gelir. Kontrol etmek için:
tune2fs -l /dev/sda1 | grep "Default mount options"
# veya
mount | grep "acl"
Eğer çıktıda acl görmüyorsanız, /etc/fstab dosyanıza mount seçeneği olarak acl ekleyebilirsiniz.
getfacl: Mevcut ACL’leri Okumak
getfacl komutu, bir dosya veya dizinin mevcut ACL kurallarını gösterir. Kullanımı oldukça basittir:
getfacl /var/www/html/proje
Tipik bir çıktı şöyle görünür:
# file: var/www/html/proje
# owner: www-data
# group: www-data
user::rwx
user:alice:rwx
user:bob:r-x
group::r-x
group:developers:rwx
mask::rwx
other::---
default:user::rwx
default:group::r-x
default:other::---
Şimdi bu çıktıyı satır satır anlayalım:
- user:: Dosya sahibinin izinleri (standart owner izniyle aynı)
- user:alice:rwx Alice kullanıcısına özel tanımlanmış izin
- user:bob:r-x Bob kullanıcısına özel tanımlanmış izin
- group:: Dosyanın grubunun izinleri
- group:developers:rwx developers grubuna özel izin
- mask::rwx Efektif izin maskesi, bu konuya birazdan döneceğiz
- other::— Diğer herkes için izin
- default: ile başlayanlar ise bu dizin içinde oluşturulacak yeni dosyaların kalıtsal olarak alacağı izinler
getfacl komutunun işime yarayan birkaç parametresi var:
- -R: Dizinleri özyinelemeli olarak tarar
- -t: Daha kompakt, tablo benzeri çıktı verir
- -s: Sadece ACL girişi olan dosyaları gösterir
- -p: Dosya yolunu baştan (/) itibaren gösterir, path stripping yapmaz
- –omit-header:
# file,# ownergibi yorum satırlarını atlar
Bir dizindeki tüm dosyaların ACL durumunu toplu görmek için:
getfacl -R /var/www/html/proje 2>/dev/null | grep -E "^(# file|user:|group:)" | head -50
setfacl: ACL Kuralları Oluşturmak ve Yönetmek
setfacl komutu ACL kurallarını eklemek, değiştirmek ve silmek için kullanılır. Temel sözdizimi şöyledir:
setfacl [seçenekler] [kural] dosya
Kural formatı u:kullanıcı:izinler veya g:grup:izinler şeklindedir. Kullanışlı parametreler:
- -m: Kural ekler veya değiştirir (modify)
- -x: Belirtilen kuralı siler (remove)
- -b: Tüm ACL kurallarını temizler (remove all)
- -k: Sadece default ACL’leri siler
- -R: İşlemi özyinelemeli uygular
- -d: Default ACL kuralı tanımlar (dizinler için kalıtım)
- –set: Mevcut tüm ACL’yi siler ve yeniden yazar
- –restore: getfacl çıktısından ACL’leri geri yükler
Basit bir kullanıcı kuralı ekleyelim:
# alice'e proje dizini üzerinde tam yetki ver
setfacl -m u:alice:rwx /var/www/html/proje
# bob'a sadece okuma ve çalıştırma izni ver
setfacl -m u:bob:r-x /var/www/html/proje
# developers grubuna tam yetki ver
setfacl -m g:developers:rwx /var/www/html/proje
Birden fazla kuralı tek seferde de ekleyebilirsiniz:
setfacl -m u:alice:rwx,u:bob:r-x,g:developers:rwx /var/www/html/proje
Mask Kavramı: Sık Atlanan Ama Kritik Detay
ACL’de en sık kafaları karıştıran konu mask değeridir. Mask, ACL’de tanımlanan kullanıcı ve grup izinleri için bir üst sınır belirler. Yani bir kullanıcıya rwx versek de mask r-x ise, efektif izin r-x olur.
ls -l çıktısında gördüğünüz grup izni aslında ACL varken mask değerini gösterir, grubun kendisinin iznini değil. Bu kafa karışıklığının kaynağıdır.
# mask'ı açıkça ayarlamak
setfacl -m m::r-x /var/www/html/proje
Mask’ı manuel değiştirmenizi önermem. ACL’e kural eklediğinizde sistem mask’ı otomatik günceller. Manuel müdahale sadece sorun çıkarır. Anlamak için iyi, kullanmak için gereksiz.
Gerçek Dünya Senaryosu 1: Paylaşımlı Geliştirme Ortamı
Diyelim ki bir ekip proje klasörü var. devteam grubundaki herkes tam yetkiye sahip olmalı, qa grubu sadece okuyabilmeli, deploy_bot kullanıcısı ise her şeyi yapabilmeli. Klasik grup yapısıyla bunu çözmek neredeyse imkansız.
#!/bin/bash
PROJE_DIR="/srv/projects/webapp"
# Önce mevcut ACL'leri temizle
setfacl -b "$PROJE_DIR"
# Kural ekle
setfacl -m u:deploy_bot:rwx "$PROJE_DIR"
setfacl -m g:devteam:rwx "$PROJE_DIR"
setfacl -m g:qa:r-x "$PROJE_DIR"
# Default ACL: yeni oluşturulan dosyalar da aynı kurallara tabi olsun
setfacl -d -m u:deploy_bot:rwx "$PROJE_DIR"
setfacl -d -m g:devteam:rwx "$PROJE_DIR"
setfacl -d -m g:qa:r-x "$PROJE_DIR"
setfacl -d -m o::--- "$PROJE_DIR"
echo "ACL kuralları uygulandı:"
getfacl "$PROJE_DIR"
Burada -d ile tanımlanan default ACL kritik bir rol oynar. Bu dizin içinde touch, mkdir, cp gibi komutlarla oluşturulan her yeni dosya veya alt dizin, otomatik olarak bu default kuralları miras alır. Klasörü oluşturduktan sonra “ya yeni dosyalara izin verilmedi” diye koşturmaktan kurtarır sizi.
Gerçek Dünya Senaryosu 2: Denetim ve Raporlama Klasörü
Muhasebe departmanının raporlar dizini var. muhasebe grubu okuma/yazma/çalıştırma yetkisine sahip. denetci kullanıcısı sadece okuyabilmeli. sistem_yedek servisi ise dosyaları kopyalayabilmeli ama değiştiremez. Bir de hassas alt klasörler var, oraya denetçi hiç girememeli.
RAPOR_DIR="/data/muhasebe/raporlar"
HASSAS_DIR="/data/muhasebe/raporlar/gizli"
# Ana dizin için kurallar
setfacl -R -m g:muhasebe:rwx "$RAPOR_DIR"
setfacl -R -m u:denetci:r-x "$RAPOR_DIR"
setfacl -R -m u:sistem_yedek:r-x "$RAPOR_DIR"
# Default ACL ana dizin
setfacl -d -m g:muhasebe:rwx "$RAPOR_DIR"
setfacl -d -m u:denetci:r-x "$RAPOR_DIR"
setfacl -d -m u:sistem_yedek:r-x "$RAPOR_DIR"
# Hassas dizinden denetçiyi tamamen çıkar
setfacl -m u:denetci:--- "$HASSAS_DIR"
setfacl -d -m u:denetci:--- "$HASSAS_DIR"
# Kontrol edelim
echo "=== Ana Dizin ACL ==="
getfacl "$RAPOR_DIR"
echo "=== Gizli Dizin ACL ==="
getfacl "$HASSAS_DIR"
--- ile bir kullanıcıya açıkça sıfır izin verdiğinizde, o kullanıcı o dizine hiçbir şekilde erişemez. Bu, “zaten groups’ta yok, o yüzden giremez” mantığından farklıdır. Explicit deny mantığıyla çalışır.
ACL Yedeklemek ve Geri Yüklemek
Sunucu taşıma, sistem yedekleme veya aynı konfigürasyonu başka bir sunucuya uygulama senaryolarında ACL’leri yedeklemek şarttır. rsync veya tar bazen ACL’leri taşımaz, buna dikkat edin.
# Tüm /srv/projects altındaki ACL'leri dosyaya yedekle
getfacl -R --absolute-names /srv/projects > /backup/acl_yedek_$(date +%Y%m%d).acl
# Yedekten geri yükle
setfacl --restore=/backup/acl_yedek_20240115.acl
tar ile ACL’leri birlikte yedeklemek için:
# ACL'leri koruyarak arşivle
tar --acls -czf proje_yedek.tar.gz /srv/projects/
# Geri aç
tar --acls -xzf proje_yedek.tar.gz
rsync kullanıyorsanız -A parametresini eklemeyi unutmayın:
rsync -avA --progress /srv/projects/ user@backup-server:/backup/projects/
Kuralları Silmek ve Temizlemek
Kural eklemek kadar silmek de önemli. Özellikle bir kullanıcı işten ayrıldığında veya bir projenin erişim politikası değiştiğinde temizlik yapmanız gerekir.
# Belirli bir kullanıcının kuralını sil
setfacl -x u:eski_calisan /srv/projects/webapp
# Belirli bir grubun kuralını sil
setfacl -x g:eski_ekip /srv/projects/webapp
# Default ACL'den bir kuralı sil
setfacl -d -x u:eski_calisan /srv/projects/webapp
# Özyinelemeli olarak sil (dizin ve içindeki her şeyde)
setfacl -R -x u:eski_calisan /srv/projects/webapp
# Tüm ACL'leri sıfırla (sadece standart izinler kalsın)
setfacl -b /srv/projects/webapp
# Sadece default ACL'leri temizle
setfacl -k /srv/projects/webapp
Bir kullanıcı sistemden silindiğinde, o kullanıcıya ait ACL kuralları dosyalarda sayısal UID olarak kalır. Bu “phantom entry” durumunu tespit etmek için:
# Silinmiş kullanıcılara ait ACL kalıntılarını bul
getfacl -R /srv 2>/dev/null | grep "^user:" | grep -v "^user::" | awk -F: '{print $2}' | sort -u | while read user; do
id "$user" &>/dev/null || echo "Silinmiş kullanıcı ACL bulundu: $user"
done
ACL ve Standart İzinlerin Birlikte Davranışı
Önemli bir nokta: ACL’ler standart Unix izinlerini ezmez, onların yanında çalışır. Bir dosyaya chmod 000 yaparsanız, ACL kuralları da etkisiz kalır çünkü önce standart kernel kontrolü devreye girer.
Fakat ls -l çıktısında ACL’li dosyaları nasıl tanırsınız? İzin bitlerinin sonundaki + işaretiyle:
ls -l /srv/projects/
# drwxrwxr-x+ 3 alice devteam 4096 Oca 15 10:30 webapp
O + işareti “bu dosyanın ACL’i var, tam listeyi görmek için getfacl kullan” demektir.
Bir de şunu bilin: cp komutu varsayılan olarak ACL’leri kopyalamaz. Eğer kopyalarken ACL’leri de taşımak istiyorsanız:
cp --preserve=all kaynak hedef
# veya
cp -a kaynak hedef
Toplu ACL Yönetimi için Pratik Script
Büyük ortamlarda tek tek komut yazmak yerine bir yapılandırma scripti hazırlamak hayat kurtarır:
#!/bin/bash
# acl_uygula.sh - Proje bazlı ACL yönetim scripti
set -euo pipefail
LOG_FILE="/var/log/acl_changes.log"
TARIH=$(date '+%Y-%m-%d %H:%M:%S')
log() {
echo "[$TARIH] $1" | tee -a "$LOG_FILE"
}
acl_uygula() {
local dizin="$1"
local kullanici_okuma="${2:-}"
local grup_yazma="${3:-}"
if [ ! -d "$dizin" ]; then
log "HATA: Dizin bulunamadı: $dizin"
return 1
fi
log "ACL uygulanıyor: $dizin"
# Okuma kullanıcısı tanımlıysa ekle
if [ -n "$kullanici_okuma" ]; then
setfacl -R -m "u:${kullanici_okuma}:r-x" "$dizin"
setfacl -d -m "u:${kullanici_okuma}:r-x" "$dizin"
log "Okuma izni verildi: $kullanici_okuma -> $dizin"
fi
# Yazma grubu tanımlıysa ekle
if [ -n "$grup_yazma" ]; then
setfacl -R -m "g:${grup_yazma}:rwx" "$dizin"
setfacl -d -m "g:${grup_yazma}:rwx" "$dizin"
log "Yazma izni verildi: $grup_yazma -> $dizin"
fi
}
# Kullanım
acl_uygula "/srv/projects/proje-a" "denetci" "devteam"
acl_uygula "/srv/projects/proje-b" "musteri_x" "backend_ekip"
acl_uygula "/data/raporlar" "yonetim" "muhasebe"
log "Tüm ACL işlemleri tamamlandı."
Sık Karşılaşılan Sorunlar
“Operation not supported” hatası alıyorum. Dosya sisteminiz ACL desteklemiyor olabilir. tune2fs -l /dev/sdaX | grep "Default mount" ile kontrol edin. NFS bağlantılarında ise sunucu tarafında da ACL desteği etkin olmalı.
Default ACL tanımladım ama yeni dosyalar almıyor. Bazı editörler (vim, gedit) dosyayı doğrudan değiştirmez, siler ve yeniden oluşturur. Bu durumda yeni dosya default ACL’i alır ama mask sıfırlanmış olabilir. umask değerinizi kontrol edin.
setfacl -R kullanırken dizin ve dosyalar için farklı izin vermek istiyorum. Tek geçişte bunu yapamassınız. İki ayrı komut kullanın: dosyalar için find ile filtreleyin.
# Dizinlere rwx, dosyalara rw- ver
find /srv/projects -type d -exec setfacl -m u:alice:rwx {} ;
find /srv/projects -type f -exec setfacl -m u:alice:rw- {} ;
Sonuç
ACL, geleneksel Unix izin modelinin yetersiz kaldığı durumlarda sistem yöneticisinin elindeki en güçlü araçlardan biridir. Öğrenmesi biraz zaman alıyor, özellikle mask kavramı ve default ACL mantığı başlangıçta kafa karıştırıcı gelebilir. Ama bir kez kavradıktan sonra, daha önce çözemediğiniz izin senaryolarını dakikalar içinde halledebileceğinizi göreceksiniz.
Pratik önerilerim şunlar: Üretime geçmeden önce her zaman bir test dizininde deneyin. ACL kurallarınızı mutlaka yedekleyin ve dökümante edin. Bir kullanıcı sistemi terk ettiğinde ACL temizliğini offboarding sürecine dahil edin, aksi halde zamanla kimsenin bilmediği izin kalıntıları birikir. Ve son olarak, getfacl çıktısını ciddiye alın; o çıktı size dosyanın gerçek erişim durumunu anlatır, ls -l değil.
