Dosya izinleri konusu, Linux dünyasına yeni adım atan birinin “eh, nasılsa sonra öğrenirim” deyip geçiştirdiği, deneyimli bir sysadmin’in ise “keşke daha erken öğrenseydim” dediği o ender konulardan biri. Bir üretim sunucusunda yanlış yapılandırılmış bir izin, hem güvenlik açığı hem de uygulama çöküşü anlamına gelebilir. Bu yüzden chmod komutunu yüzeysel değil, gerçekten derinlemesine anlamak gerekiyor.
Linux Dosya İzin Sistemi Nasıl Çalışır?
Linux’ta her dosya ve dizin üç farklı kimlik grubuna ait izinler taşır. Bunlar owner (sahip), group (grup) ve others (diğerleri) olarak ayrılır. Her grup için üç temel izin vardır: okuma (read), yazma (write) ve çalıştırma (execute).
Bir dosyaya ls -la komutu çektiğinizde şöyle bir çıktı görürsünüz:
ls -la /var/www/html/index.php
-rwxr-xr-- 1 www-data developers 4096 Jan 15 10:30 index.php
Bu çıktıdaki -rwxr-xr-- kısmını parçalara ayıralım:
- –: Dosya türü (- dosya, d dizin, l sembolik link)
- rwx: Owner izinleri (okuma, yazma, çalıştırma)
- r-x: Group izinleri (okuma, çalıştırma, yazma yok)
- r–: Others izinleri (sadece okuma)
Bu yapıyı kavramadan chmod kullanmak, körün fil tarif etmesine benziyor. Temeli oturtmadan devam etmeyelim.
Sayısal (Octal) Mod ile chmod
chmod‘un en yaygın kullanım biçimi sayısal moddur. Okuma 4, yazma 2, çalıştırma 1 değerlerini alır ve bunların toplamı ilgili grubun iznini belirler.
# Klasik web dosyası izni: owner rwx, group r-x, others r--
chmod 754 /var/www/html/index.php
# Sadece owner okuyabilir ve yazabilir, kimse başkası dokunamaz
chmod 600 /home/ahmet/.ssh/id_rsa
# Herkes okuyabilir, owner yazabilir
chmod 644 /etc/nginx/nginx.conf
# Dizinlere execute vermek önemli: dizine girebilmek için gerekli
chmod 755 /var/www/html
Sayısal modda sık yapılan hata, dizinlere execute vermeyip sonra “dizine giremiyorum” diye şikayet etmek. Dizinde execute izni olmadan cd komutu çalışmaz, bu temel bir kural.
Bir örnek senaryo düşünelim: Şirkette bir PHP uygulaması deploy ediyorsunuz. Web sunucusu www-data kullanıcısı olarak çalışıyor, geliştirici ekibi developers grubunda. Dosyaların okunabilir ama yalnızca authorized kişilerce yazılabilir olmasını istiyorsunuz.
# Uygulama dizinini doğru izinlerle ayarla
find /var/www/myapp -type f -exec chmod 644 {} ;
find /var/www/myapp -type d -exec chmod 755 {} ;
# Upload klasörü www-data tarafından yazılabilmeli
chmod 775 /var/www/myapp/uploads
chown -R www-data:developers /var/www/myapp
find ile chmod kombinasyonu gerçek hayatta en çok kullandığınız yapılardan biri olacak. Tek tek dosyalara izin vermek yerine toplu işlem yapmanızı sağlar.
Sembolik Mod ile chmod
Sayısal mod güçlüdür ama mevcut izinleri değiştirmek yerine sıfırdan set eder. Sembolik mod ise sadece belirli bir iznin üzerine yazmanıza izin verir. Bu kritik bir fark.
Sembolik modda kullandığınız karakterler şunlardır:
- u: User (owner)
- g: Group
- o: Others
- a: All (hepsi)
- +: İzin ekle
- –: İzin kaldır
- =: Tam olarak bu iznleri set et
# Owner'a execute izni ekle, mevcut izinleri koru
chmod u+x /usr/local/bin/myscript.sh
# Gruptan yazma iznini kaldır
chmod g-w /etc/passwd
# Herkesten execute iznini kaldır (güvenlik için)
chmod a-x /tmp/suspicious_file
# Owner için okuma ve yazma, diğerleri için sadece okuma
chmod u=rw,go=r /etc/cron.d/myapp
Sembolik modun gerçek gücü şurada ortaya çıkıyor: Diyelim ki bir script dosyasının izinleri 644 ve siz sadece çalıştırma iznini eklemek istiyorsunuz. Eğer sayısal mod kullansaydınız, önce mevcut izni okuyup sonra hesap yapmanız gerekirdi. Sembolik modda tek satır yeterli:
# Önce izni kontrol et
ls -la deploy.sh
# -rw-r--r-- 1 deploy deploygroup 1234 Jan 15 10:00 deploy.sh
# Sadece execute ekle, geri kalanı bozmadan
chmod +x deploy.sh
# Sonuç: -rwxr-xr-x
ls -la deploy.sh
Bu yaklaşım özellikle script’lerin otomatik deployment’ında, CI/CD pipeline’larında çok değerlidir. Mevcut izin yapısını bozmadan üstüne ekleme yaparsınız.
Recursive chmod ve Dikkat Edilmesi Gerekenler
-R bayrağıyla recursive izin değişikliği yapabilirsiniz. Ama bu bayrak körce kullanılırsa büyük sorunlara yol açar.
# Tüm dizin ağacına aynı izni verme - YANLIŞ yaklaşım
chmod -R 755 /var/www/myapp
# Neden yanlış? Çünkü dosyalar ve dizinler farklı izne ihtiyaç duyar.
# Dosyalar için 755 = herkes çalıştırabilir, bu genellikle istemediğiniz bir durum
# DOĞRU yaklaşım: find ile ayrı ayrı uygula
find /var/www/myapp -type d -exec chmod 755 {} ;
find /var/www/myapp -type f -exec chmod 644 {} ;
Bir üretim ortamında yanlış chmod -R kullanımının nasıl felakete yol açabileceğini anlatan bir senaryo paylaşayım. Bir ekip arkadaşım bir gün /etc altındaki bir uygulama konfigürasyonunu düzelteceğim derken yanlışlıkla şunu çalıştırdı:
# BU KOMUTU ÇALIŞTIRMAYIN - örnek amaçlıdır
chmod -R 777 /etc/myapp/../../
# Yukarıdaki /etc/myapp/../../ = / anlamına gelir
# Yani tüm sistem dosyalarına 777 verilir, felaket
Sistem tamamen çöktü. SSH private key izinleri bozuldu, sudo çalışmaz oldu. Bu yüzden recursive işlemlerde her zaman hedef dizini iki kez kontrol edin.
SUID, SGID ve Sticky Bit
İşte burada çoğu sysadmin bilgisi yetersiz kalır. Standart üç izin grubunun ötesinde, özel amaçlı üç bit daha var.
SUID (Set User ID)
SUID biti set edilmiş bir binary, çalıştıran kişinin değil, dosyanın sahibinin yetkileriyle çalışır. passwd komutu buna en güzel örnektir:
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Jan 15 09:00 /usr/bin/passwd
# 's' harfine dikkat: execute + SUID
Normal bir kullanıcı /etc/shadow dosyasını yazamaz, ama passwd komutu root sahipliğinde ve SUID ile çalıştığı için shadow dosyasını güncelleyebilir. SUID vermek için:
# Sayısal modda: 4 prefix olarak eklenir
chmod 4755 /usr/local/bin/myspecialapp
# Sembolik modda
chmod u+s /usr/local/bin/myspecialapp
Güvenlik uyarısı: SUID biti yanlış kullanıldığında ciddi privilege escalation açıklarına neden olur. Sisteminizde gereksiz SUID binary’leri periyodik olarak kontrol edin:
# Sistemdeki tüm SUID dosyalarını bul
find / -perm -4000 -type f 2>/dev/null
# SGID dosyalarını bul
find / -perm -2000 -type f 2>/dev/null
SGID (Set Group ID)
SGID dosyalar üzerinde SUID gibi çalışır, ama group için. Dizinler üzerinde ise çok farklı ve kullanışlı bir davranış sergiler: Dizin içinde oluşturulan her yeni dosya, oluşturanın grubu değil, dizinin grubu ile oluşturulur.
# Paylaşılan proje dizini oluştur
mkdir /opt/project-data
chown root:devteam /opt/project-data
chmod 2775 /opt/project-data
# Artık devteam grubundaki herkes bu dizinde dosya oluşturabilir
# Ve oluşturulan dosyalar otomatik olarak devteam grubuna ait olur
ls -la /opt/project-data/
# drwxrwsr-x 2 root devteam 4096 Jan 15 11:00 .
# 's' harfi group execute konumunda: SGID aktif
Bu yapı, birden fazla geliştirici veya operasyon ekibinin aynı dizin üzerinde çalıştığı paylaşımlı ortamlarda son derece değerlidir. Her dosyanın sahibi farklı kullanıcı olsa bile tüm dosyalar aynı grupla oluşturulur, erişim sorunu yaşanmaz.
Sticky Bit
Sticky bit genellikle /tmp gibi herkesin yazabildiği dizinlerde kullanılır. Bu bit set edildiğinde, bir kullanıcı dizin içindeki sadece kendi oluşturduğu dosyaları silebilir.
ls -la /
# drwxrwxrwt 15 root root 4096 Jan 15 12:00 tmp
# 't' harfine dikkat: sticky bit
# Sticky bit set etmek
chmod +t /shared/uploads
chmod 1777 /tmp/myapptemp
Gerçek dünya senaryosu: Bir multi-tenant uygulama geliştiriyorsunuz. Her kullanıcının dosya yüklediği paylaşımlı bir upload dizini var. Sticky bit olmadan, kullanıcı A, kullanıcı B’nin dosyalarını silebilir. Sticky bit ile herkes sadece kendi dosyasına dokunabilir.
umask: Varsayılan İzinleri Yönetmek
chmod yeni dosyaların iznini belirlemez, sadece mevcut dosyaları değiştirir. Yeni dosyaların varsayılan izinleri umask değeriyle belirlenir.
# Mevcut umask değerini görüntüle
umask
# 0022
# umask nasıl çalışır?
# Dosyalar için maksimum: 666
# Dizinler için maksimum: 777
# umask 022 ise:
# Dosyalar: 666 - 022 = 644
# Dizinler: 777 - 022 = 755
Güvenlik odaklı bir ortamda daha kısıtlayıcı umask kullanabilirsiniz:
# Kullanıcının .bashrc veya .profile dosyasına ekle
umask 027
# Dosyalar: 666 - 027 = 640 (group okuyabilir, others hiçbir şey yapamaz)
# Dizinler: 777 - 027 = 750
# Sistem genelinde /etc/profile veya /etc/login.defs üzerinden de ayarlanabilir
grep UMASK /etc/login.defs
Bir finans şirketinde çalışırken, hassas raporlama dosyaları için tüm raporlama kullanıcılarına umask 027 uygulanmasını zorunlu kıldık. Böylece yeni oluşturulan raporlar otomatik olarak grup dışı kullanıcılara kapalı geliyordu.
ACL ile Gelişmiş İzin Yönetimi
Standart Unix izinleri bazen yeterli olmaz. Örneğin bir dosyaya üç farklı kullanıcıya üç farklı izin vermek istediğinizde, sadece chmod yetersiz kalır. İşte bu noktada ACL (Access Control List) devreye girer.
# ACL desteğini kontrol et
getfacl /var/www/html/config.php
# Belirli bir kullanıcıya özel izin ver
setfacl -m u:jenkins:r-- /var/www/html/config.php
# Belirli bir gruba izin ver
setfacl -m g:monitoring:r-x /var/log/nginx
# Recursive ACL uygulama
setfacl -R -m u:backup:r-x /var/www/html
# ACL'leri görüntüle
getfacl /var/www/html/config.php
# # file: var/www/html/config.php
# # owner: www-data
# # group: www-data
# user::rw-
# user:jenkins:r--
# group::r--
# mask::r--
# other::---
# ACL kaldırma
setfacl -x u:jenkins /var/www/html/config.php
setfacl -b /var/www/html/config.php # Tüm ACL'leri kaldır
ACL, özellikle DevOps ortamlarında CI/CD araçlarına (Jenkins, GitLab Runner) belirli dosyalara okuma erişimi verirken diğer izin yapısını bozmadan çok işe yarar.
Pratik Senaryolar ve Hata Ayıklama
Web Sunucusu İzin Sorunlarını Çözmek
En sık karşılaşılan senaryo: Apache ya da Nginx “Permission denied” hatası veriyor.
# Önce hangi kullanıcıyla çalıştığını öğren
ps aux | grep nginx
# www-data
# Dosya sahipliği ve izinleri kontrol et
ls -la /var/www/html/
namei -l /var/www/html/index.php
# namei tüm yol üzerindeki izinleri gösterir, çok kullanışlı
# Sorunlu dizini düzelt
chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 755 {} ;
find /var/www/html -type f -exec chmod 644 {} ;
# Yazılabilir olması gereken dizinler
chmod 775 /var/www/html/storage
chmod 775 /var/www/html/cache
SSH Anahtar Dosyalarının İzinleri
SSH, izin konusunda çok katıdır. Yanlış izin varsa bağlantı reddedilir.
# .ssh dizini ve içindeki dosyalar için doğru izinler
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts
chmod 600 ~/.ssh/config
# Tüm bunları tek scriptle ayarla
#!/bin/bash
SSH_DIR="$HOME/.ssh"
chmod 700 "$SSH_DIR"
find "$SSH_DIR" -name "id_*" ! -name "*.pub" -exec chmod 600 {} ;
find "$SSH_DIR" -name "*.pub" -exec chmod 644 {} ;
chmod 600 "$SSH_DIR/authorized_keys" 2>/dev/null
chmod 600 "$SSH_DIR/config" 2>/dev/null
echo "SSH izinleri düzenlendi."
Cron Job İzin Sorunları
Cron job çalışmıyor mu? İzin sorunu olabilir.
# Script çalıştırılabilir mi?
ls -la /etc/cron.d/myapp
chmod +x /usr/local/bin/myapp-cron.sh
# /etc/cron.d/ dosyaları 644 olmalı, çalıştırılabilir OLMAMALI
chmod 644 /etc/cron.d/myapp
# Cron log'larını kontrol et
tail -f /var/log/cron
# veya
journalctl -u cron -f
İzin Sorunlarını Proaktif İzleme
Üretim ortamında izin değişikliklerini izlemek güvenlik açısından kritik.
# inotifywait ile anlık izleme (inotify-tools paketi gerekli)
inotifywait -m -r --format '%T %w %f %e' --timefmt '%Y-%m-%d %H:%M:%S'
-e attrib /etc /var/www 2>/dev/null |
while read line; do
echo "$line" >> /var/log/permission-changes.log
done
# Audit sistemiyle izin değişikliklerini kayıt altına alma
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -w /var/www/html -p wa -k webroot_changes
# Audit loglarını sorgula
ausearch -k webroot_changes --start today
chmod Hakkında Bilinmesi Gereken Ek İpuçları
- –reference: Bir dosyanın iznini başka bir dosyadan kopyalamak için kullanılır
# reference.txt'nin iznini target.txt'ye kopyala
chmod --reference=/etc/nginx/nginx.conf /etc/nginx/sites-available/mysite.conf
- Verbose mod: Ne yapıldığını görmek için
-vbayrağını kullanın
chmod -v 644 /etc/myapp/*.conf
# mode of '/etc/myapp/app.conf' changed from 0664 (rw-rw-r--) to 0644 (rw-r--r--)
- Değişiklik bildirimi: Yalnızca değişen dosyaları görmek için
-ckullanın
chmod -c 755 /usr/local/bin/*
Sonuç
chmod ilk bakışta basit bir komut gibi görünse de arkasında Unix güvenlik modelinin tüm katmanları yatıyor. Sayısal ve sembolik modlar, SUID/SGID/Sticky bit, umask, ACL ve bunların birbirleriyle olan etkileşimi, gerçekten sağlam bir sistem güvenliği için vazgeçilmez.
Bir sysadmin olarak şunu söyleyebilirim: İzin sorunlarının %80’i üç temel hatadan kaynaklanır. Birincisi, dosya ve dizinlere aynı izni körce uygulamak. İkincisi, ownership ile permission arasındaki farkı göz ardı etmek. Üçüncüsü ise SUID gibi özel bitleri güvenlik açısından değerlendirmemek.
Bu bilgileri pratikte pekiştirmenin en iyi yolu bir test ortamı kurup farklı senaryolar denemek. Vagrant ya da Docker ile hızlıca bir sandbox hazırlayabilir, izin yapılarını bozmaktan korkmadan deneyebilirsiniz. Gerçek üretim ortamında “bir bakalım ne olacak” demek, gece yarısı nöbeti anlamına gelebilir.