namei Komutu ile Dosya Yolu İzinlerini ve Sembolik Linkleri Adım Adım Analiz Etme
Bir dosyaya erişemiyorsunuz, izinler doğru görünüyor ama yine de “Permission denied” alıyorsunuz. Klasik senaryo. Çoğu sysadmin bu noktada ls -la ile tek tek dizinleri kontrol etmeye başlar, belki stat komutuyla biraz daha derine iner. Oysa namei komutu bu işi çok daha zarif bir şekilde hallediyor ve bence yeterince tanınmıyor.
namei, bir dosya yolundaki her bileşenin izinlerini ve sembolik linkleri adım adım gösteriyor. Tek komutla tüm yolu analiz ediyorsunuz, her dizin için ayrı ayrı ls çalıştırmak yerine. Özellikle iç içe sembolik linkler söz konusu olduğunda bu araç hayat kurtarıcı.
namei Nedir ve Ne İşe Yarar?
namei, util-linux paketinin bir parçası olarak geliyor. Neredeyse tüm Linux dağıtımlarında hazır bulunuyor, ekstra kurulum gerektirmiyor. Komutun temel mantığı şu: verdiğiniz bir dosya yolunu parçalara ayırıyor ve her parça için türünü, izinlerini ve sahibini gösteriyor.
namei /var/log/nginx/access.log
Bu komutu çalıştırdığınızda şuna benzer bir çıktı görürsünüz:
f: /var/log/nginx/access.log
d /
d var
d log
d nginx
- access.log
Soldaki harfler ne anlama geliyor?
- f: Analiz edilen tam yol (başlık satırı)
- d: Dizin (directory)
- –: Normal dosya
- l: Sembolik link
- s: Socket
- p: Named pipe
- b: Block device
- c: Character device
Sade haliyle bile kullanışlı ama asıl güç parametrelerle ortaya çıkıyor.
Temel Parametreler
-l veya --long: Uzun format, izinleri ve sahiplik bilgilerini gösterir. En sık kullandığım parametre bu.
-m veya --modes: Sadece izinleri gösterir, sahiplik bilgisi olmadan.
-o veya --owners: Sahiplik bilgisini de dahil eder.
-n veya --nosymlinks: Sembolik linkleri takip etmez, linkin kendisini gösterir.
-x veya --mountpoints: Mount noktalarını işaretler.
-v veya --vertical: Dikey hizalama yapar.
Pratikte en çok kullandığım kombinasyon şu:
namei -l /var/log/nginx/access.log
Çıktı şuna benziyor:
f: /var/log/nginx/access.log
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxrwxr-x root syslog log
drwxr-xr-x root root nginx
-rw-r--r-- www-data adm access.log
Artık tek bakışta her şeyi görüyorsunuz. Root dizini herkes tarafından okunabilir, log dizini syslog grubuna yazma izni veriyor, nginx dizinini sadece root yönetiyor, dosya ise www-data’ya ait. Herhangi bir yerde “diğerleri” için execute biti yoksa oraya erişemezsiniz, hemen fark ediyorsunuz.
Gerçek Dünya Senaryoları
Senaryo 1: Web Sunucusu İzin Sorunları
Nginx veya Apache ile çalışırken en sık karşılaşılan sorunların başında izin hataları geliyor. Bir müşterinin sitesi “403 Forbidden” veriyordu. Apache hata loguna baktım, gayet net bir şekilde Permission denied yazıyordu. Ama dosya izinleri doğruydu, yemin ederim 755 yapılmıştı.
namei -l /var/www/html/musteri-sitesi/public/index.php
Çıktıya bakınca sorun hemen göründü:
f: /var/www/html/musteri-sitesi/public/index.php
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x root root html
drwx------ deploy deploy musteri-sitesi
drwxr-xr-x deploy deploy public
-rw-r--r-- deploy deploy index.php
musteri-sitesi dizininin izni 700 idi. Deployment scripti dizini oluştururken varsayılan umask nedeniyle sadece owner için erişilebilir hale getirmişti. Apache kullanıcısı www-data o dizine giremiyordu dolayısıyla. Dosyanın kendisi doğru ayarlanmış olsa bile, üst dizinde execute biti olmayan bir yer varsa oraya kimse ulaşamıyor.
chmod 755 /var/www/html/musteri-sitesi
Sorun çözüldü. namei olmasaydı her dizini tek tek ls -la ile kontrol edecektim.
Senaryo 2: Sembolik Link Labirenti
Sembolik linkler çok kullanışlı ama birden fazla link iç içe girince ne nereye işaret ediyor takip etmek zorlaşıyor. Özellikle /etc/alternatives veya büyük projelerde konfigürasyon dosyaları için kullanılan link zincirlerinde kaybolmak çok kolay.
namei -l /etc/alternatives/python3
f: /etc/alternatives/python3
drwxr-xr-x root root /
drwxr-xr-x root root etc
drwxr-xr-x root root alternatives
lrwxrwxrwx root root python3 -> /usr/bin/python3.10
drwxr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root bin
lrwxrwxrwx root root python3.10 -> python3.10
-rwxr-xr-x root root python3.10
namei sembolik linkleri otomatik olarak takip ediyor ve hiyerarşiyi girintili şekilde gösteriyor. Hangi linkin nereye işaret ettiği, zincirin sonunda gerçek dosyanın nerede olduğu ve her adımın izinleri tek ekranda görünüyor. -n parametresiyle bu takibi devre dışı bırakabiliyorsunuz:
namei -ln /etc/alternatives/python3
Bu seçenekle sadece linkin kendisini görürsünüz, hedefini takip etmez.
Senaryo 3: NFS ve Mount Noktası Sorunları
Uzak mount noktaları üzerindeki dosyalara erişim sorunlarında -x parametresi işe yarıyor. Mount noktalarını özellikle işaretliyor:
namei -lx /mnt/nfs/shared/data/rapor.csv
f: /mnt/nfs/shared/data/rapor.csv
drwxr-xr-x root root /
drwxr-xr-x root root mnt
drwxr-xr-x root root nfs
D rwxr-xr-x nfsuser nfsgroup shared
drwxr-xr-x nfsuser nfsgroup data
-rw-r--r-- nfsuser nfsgroup rapor.csv
D harfi mount noktasını işaret ediyor. NFS üzerinden gelen bir dizin söz konusu olduğunda, uid/gid eşlemesi yanlışsa erişim sorunu yaşıyorsunuz. Burada nfsuser ve nfsgroup yerel sistemde kim olarak eşlendiğini kontrol etmeniz gerekiyor.
Senaryo 4: Cron Job’ları Neden Çalışmıyor?
Cron ile ilgili şikayetlerin büyük çoğunluğu şu cümleyle geliyor: “Script terminalde çalışıyor ama cron’da çalışmıyor.” Bunun birçok sebebi olabilir ama izin sorunları en başta geliyor.
Cron, script’i farklı bir kullanıcı olarak çalıştırıyor olabilir. Özellikle /etc/cron.d/ altındaki job tanımlarında kullanıcı belirtildiğinde, o kullanıcının tüm yol boyunca execute iznine sahip olması gerekiyor.
namei -lo /home/deploy/scripts/backup.sh
-o parametresi sahiplik bilgisini de gösteriyor:
f: /home/deploy/scripts/backup.sh
drwxr-xr-x root root /
drwxr-xr-x root root home
drwx------ deploy deploy /home/deploy
drwxr-xr-x deploy deploy scripts
-rwxr-xr-x deploy deploy backup.sh
/home/deploy dizini 700. Cron job’u www-data olarak çalışıyorsa /home/deploy dizinine giremez, dolayısıyla scripts/backup.sh‘a da ulaşamaz. Bunu bulmak için normalde birkaç dakika harcıyorsunuz, namei ile saniyeler içinde görüyorsunuz.
Senaryo 5: Docker Volume ve Bind Mount İzinleri
Container ortamlarında volume ve bind mount izinleri sık sorun çıkarıyor. Host üzerinde bir dizini container’a mount ediyorsunuz ama container içinden yazamıyorsunuz.
Host üzerinde kontrol:
namei -l /opt/app/data
f: /opt/app/data
drwxr-xr-x root root /
drwxr-xr-x root root opt
drwxr-xr-x root root app
drwxr-x--- root 1000 data
data dizini 750 izinleriyle ayarlanmış ve grup olarak GID 1000 var. Container içindeki uygulama kullanıcısının UID/GID’si farklıysa buraya yazamıyor. Container’ın hangi kullanıcıyla çalıştığına bakıp buna göre ya host dizin iznini düzenliyorsunuz ya da container kullanıcısını ayarlıyorsunuz.
Birden Fazla Yolu Aynı Anda Analiz Etmek
namei birden fazla argümanı kabul ediyor. Aynı anda birkaç yolu karşılaştırmanız gerektiğinde pratik:
namei -l /etc/nginx/nginx.conf /etc/nginx/sites-enabled/default /var/log/nginx/error.log
Her yol için ayrı ayrı analiz yapıyor ve aralarına boş satır koyarak çıktıyı ayırıyor. Nginx konfigürasyonunu debug ederken tüm ilgili dosyaları tek seferde kontrol edebiliyorsunuz.
Shell Scripti ile Toplu Analiz
Birden fazla kritik yolu düzenli olarak kontrol etmeniz gerekiyorsa bunu bir script’e dökmek mantıklı. Örneğin web sunucusu kurulumunu doğrulayan bir kontrol scripti:
#!/bin/bash
PATHS=(
"/var/www/html"
"/etc/nginx/nginx.conf"
"/etc/nginx/sites-enabled"
"/var/log/nginx"
"/run/nginx.pid"
)
echo "=== Web Sunucusu Yol İzin Raporu ==="
echo "Tarih: $(date)"
echo ""
for path in "${PATHS[@]}"; do
echo "--- $path ---"
if [ -e "$path" ] || [ -L "$path" ]; then
namei -l "$path"
else
echo "UYARI: $path mevcut degil!"
fi
echo ""
done
Bu script’i cron’a ekleyip çıktısını bir log dosyasına yönlendirirseniz, izin değişikliklerini tarihsel olarak takip edebiliyorsunuz. Özellikle birden fazla kişinin sunucuya erişebildiği ortamlarda kim ne zaman neyi değiştirdi sorusuna kısmen cevap veriyor.
namei Çıktısını Filtrelemek
Uzun bir yol analiz ediyorsanız ve sadece belirli bilgilere odaklanmak istiyorsanız grep ile birleştirmek işe yarıyor:
# Sadece sembolik link olan satırları göster
namei -l /usr/bin/python3 | grep "^l"
# İzin sorunlarını bulmak için: execute biti olmayan dizinleri filtrele
namei -l /var/www/html/uygulama/index.html | grep "^d" | grep -v "x"
İkinci komut biraz açıklama istiyor: d ile başlayan (dizin olan) satırları alıp, içinde x geçmeyenleri filtreliyor. Bu ham bir filtreleme, chmod çıktısındaki konumsal x karakterini tam olarak yakalamıyor ama hızlı bir bakış için yeterli. Daha hassas bir kontrol için awk kullanmak daha doğru:
namei -l /var/www/html/uygulama/index.html | awk '/^d/{if($1 !~ /x/){print "SORUNLU:", $0}}'
Relative Path Kullanımı
namei mutlak yollarla çalışmak zorunda değil. Göreli yollarla da kullanabilirsiniz:
cd /var/www
namei -l html/musteri-sitesi/public/index.php
Ama dikkat: Göreli yol verdiğinizde namei mevcut dizinden başlıyor ama tam yolu göstermiyor, bu yüzden kafa karışıklığına yol açabiliyor. Production ortamında her zaman mutlak yol kullanmak daha güvenli.
Önemli Bir Nokta: namei ve ACL’ler
namei‘nin bir sınırlamasından söz etmem gerekiyor: POSIX ACL’leri göstermiyor. Eğer bir dosyada setfacl ile ekstra izinler tanımlanmışsa, namei bunları raporlamıyor. Standart Unix izinleri tamam görünüyor olsa bile ACL nedeniyle erişim sorunları yaşanabilir.
Bu durumu kontrol etmek için:
# Önce namei ile standart izinlere bak
namei -l /dosya/yolu
# ACL kontrolü için getfacl kullan
getfacl /dosya/yolu
İkisini birlikte kullanmak izin sorunlarını %99 oranında açıklıyor benim deneyimimde. Geri kalan %1 genellikle SELinux veya AppArmor ile ilgili, onlar için de ls -Z komutu devreye giriyor.
SELinux Bağlamı ile Birlikte Kullanım
SELinux aktifse ve “Permission denied” alıyorsanız, namei‘nin gösterdiği izinler tamamen doğru olabilir ama SELinux bağlamı yanlış olabilir. İki komutu ardışık kullanmak iyi bir alışkanlık:
# Standart izinler
namei -l /var/www/html/uygulama
# SELinux bağlamı
ls -laZ /var/www/html/uygulama
Eğer SELinux bağlamı httpd_sys_content_t yerine user_home_t veya başka bir şeyse, Apache o dosyalara erişemiyor. restorecon veya chcon ile düzeltmek gerekiyor. Ama önce hangi katmanda sorun olduğunu anlamak lazım, namei bu triage sürecini hızlandırıyor.
namei’yi Sistematik Troubleshooting İş Akışına Dahil Etmek
Şöyle bir sıra oluşturdum kendim için. Herhangi bir dosya erişim sorunu geldiğinde şu adımları takip ediyorum:
# Adım 1: Temel yol analizi
namei -l /sorunlu/dosya/yolu
# Adım 2: Sembolik link varsa takip et
namei -lx /sorunlu/dosya/yolu
# Adım 3: ACL kontrolü
getfacl /sorunlu/dosya/yolu
# Adım 4: SELinux aktifse bağlam kontrolü
ls -laZ /sorunlu/dosya/yolu
# Adım 5: Dosyayı açmaya çalışan process'in hangi kullanıcıyla çalıştığını bul
ps aux | grep [p]rocess-adi
Bu beş adımın ilki namei, ve %70 oranında burada sorun çözülüyor. Gerisi kenar durumlar.
Sonuç
namei küçük ama özlü bir araç. Yaptığı iş çok basit görünüyor ama bunu el yordamıyla yapmak, yani uzun bir yoldaki her dizin için ayrı ayrı ls -la çalıştırmak, hem zaman kaybı hem de gözden kaçırma riski demek. Özellikle derinlemesine iç içe geçmiş dizin yapılarında veya sembolik link zincirleri söz konusu olduğunda namei‘nin sağladığı bütünsel görünüm gerçekten fark yaratıyor.
Benim için en büyük değeri şu: bir sorunu çözmekten çok o sorunu hızla teşhis etmek. İzin sorunlarının kaynağını bulmak bazen çözmekten daha uzun sürer. namei -l ile bu teşhis sürecini dramatik biçimde kısaltabiliyorsunuz.
Eğer henüz araç setinize dahil etmediyseniz, bir dahaki “Permission denied” hatanızda deneyin. Büyük ihtimalle bir daha onsuz troubleshooting yapmak istemeyeceksiniz.
