Bir sistemi yönetirken en çok başınızı ağrıtan şeylerden biri, “kim neye erişebilmeli?” sorusudur. Küçük bir sunucuda iki-üç kullanıcı varken bu soruyu sezgisel olarak çözebilirsiniz. Ama onlarca geliştirici, birden fazla ortam (dev, staging, prod) ve farklı sorumluluk alanları olan bir yapıda sezgi yeterli olmaz. İşte tam bu noktada Rol Tabanlı Erişim Kontrolü (RBAC) devreye giriyor. Linux’un yerleşik araçlarını kullanarak sağlam bir RBAC mimarisi kurmak hem güvenliği artırır hem de operasyonel kaosu önler.
Rol Tabanlı Erişim Kontrolü Nedir?
RBAC’ın özü şudur: kullanıcılara doğrudan izin vermek yerine, önce roller tanımlarsınız, sonra kullanıcıları bu rollere atarsınız. Bir rol, belirli görevleri yerine getirebilmek için gereken minimum izin setidir.
Linux’ta RBAC’ı uygulamak için birkaç katman vardır:
- Unix grupları: Temel ve en yaygın mekanizma
- sudo kuralları: Komut bazlı yetkilendirme
- ACL (Access Control Lists): Standart Unix izinlerinin ötesinde granüler kontrol
- PAM modülleri: Kimlik doğrulama katmanında politika uygulamak
- SELinux / AppArmor: Zorunlu erişim kontrolü (MAC) katmanı
Bu yazıda gerçek dünya senaryoları üzerinden, gruplardan sudo’ya, ACL’den özel yapılandırmalara kadar pratik bir RBAC tasarımı nasıl yapılır onu göreceğiz.
Senaryo: Bir Web Uygulaması Ortamı
Diyelim ki şu ekiplere ve rollere sahipsiniz:
- Geliştirici ekibi: Uygulama kodunu deploy eder, log okur ama sunucu yapılandırmasına dokunamaz
- DBA ekibi: Veritabanı servislerini yönetir, yedek alır
- Ops ekibi: Sistem genelinde tam yetkiye sahiptir
- Monitoring ekibi: Sadece okuma yapar, log ve metrik toplar
- Junior geliştirici: Sadece kendi proje dizininde çalışır, başka hiçbir yere erişemez
Bu tanımlardan yola çıkarak sistemimizi inşa edelim.
Grup Yapısını Kurmak
Her rol için bir Unix grubu oluşturuyoruz. Grup isimlendirme konvansiyonunu standart tutmak önemlidir. Ben role_ öneki kullanmayı seviyorum, böylece sistem gruplarından ayırt etmek kolaylaşır.
# Rol gruplarını oluştur
sudo groupadd role_developer
sudo groupadd role_dba
sudo groupadd role_ops
sudo groupadd role_monitoring
sudo groupadd role_junior_dev
# Mevcut grupları doğrula
getent group | grep role_
Şimdi kullanıcıları bu gruplara ekleyelim. Bir kullanıcının birden fazla rolü olabilir, bu tamamen normaldir:
# ali bir geliştirici
sudo useradd -m -s /bin/bash -G role_developer ali
# ayse hem geliştirici hem junior dev değil, sadece developer
sudo useradd -m -s /bin/bash -G role_developer ayse
# mehmet DBA
sudo useradd -m -s /bin/bash -G role_dba mehmet
# zeynep ops ekibinden
sudo useradd -m -s /bin/bash -G role_ops zeynep
# monitoring için servis hesabı, login kapalı
sudo useradd -r -s /sbin/nologin -G role_monitoring monitor_agent
# Kullanıcının gruplarını kontrol et
id ali
Önemli not: useradd ile kullanıcı oluştururken -G parametresi ek grupları tanımlar. Kullanıcının birincil grubu (private group) ayrı tutulur. Bu, dosya sahipliği konusunda daha temiz bir yapı sağlar.
Dizin Yapısını ve İzinleri Tasarlamak
Uygulama dizin yapısını rollerimize göre şekillendirelim:
# Ana uygulama dizinlerini oluştur
sudo mkdir -p /srv/webapp/{releases,shared,logs,config}
sudo mkdir -p /srv/webapp/shared/{uploads,cache}
sudo mkdir -p /var/log/webapp
sudo mkdir -p /opt/dba/{backups,scripts}
# Sahiplik ve izinleri ayarla
# releases: ops sahip, developer okuyabilir ve yazabilir
sudo chown -R root:role_developer /srv/webapp/releases
sudo chmod -R 2775 /srv/webapp/releases
# config: ops sahip, developer sadece okur
sudo chown -R root:role_developer /srv/webapp/config
sudo chmod -R 2750 /srv/webapp/config
# logs: herkes okuyabilir ama sadece uygulama yazabilir
sudo chown -R www-data:role_monitoring /var/log/webapp
sudo chmod -R 2750 /var/log/webapp
# DBA dizinleri
sudo chown -R root:role_dba /opt/dba
sudo chmod -R 2770 /opt/dba
Buradaki 2775 iznindeki 2, setgid bitini temsil eder. Setgid ayarlandığında, bu dizin içinde oluşturulan her yeni dosya otomatik olarak dizinin grubunu miras alır. Bu, ekip çalışmasında son derece kullanışlıdır çünkü birisi yeni bir dosya oluşturduğunda grubunu elle değiştirmeniz gerekmez.
ACL ile Granüler İzin Yönetimi
Standart Unix izinleri bazen yetmez. Örneğin, config dizinini geliştiricilerin okuması ama monitoring ajanının da okuyabilmesi gerekiyor diyelim. Klasik Unix’te bir dosya için yalnızca bir grup tanımlayabilirsiniz. ACL bu kısıtlamayı aşar.
# ACL paketinin yüklü olduğunu kontrol et
which setfacl || sudo apt install acl # Debian/Ubuntu
# veya
which setfacl || sudo dnf install acl # RHEL/Fedora
# Monitoring grubuna /srv/webapp/logs üzerinde okuma yetkisi ver
sudo setfacl -R -m g:role_monitoring:r-x /var/log/webapp
# Varsayılan ACL: yeni dosyalar da aynı izni miras alsın
sudo setfacl -R -d -m g:role_monitoring:r-x /var/log/webapp
# Junior developer için sadece kendi proje dizinine erişim
sudo mkdir -p /srv/webapp/releases/project_junior
sudo setfacl -m u:ali:rwx /srv/webapp/releases/project_junior
sudo setfacl -d -m u:ali:rwx /srv/webapp/releases/project_junior
# ACL'leri görüntüle
getfacl /var/log/webapp
ACL çıktısı şöyle görünecektir:
# file: var/log/webapp
# owner: www-data
# group: role_monitoring
# flags: -s-
user::rwx
group::r-x
group:role_monitoring:r-x
mask::r-x
other::---
Dikkat edilmesi gereken nokta: ACL kullanırken mask değeri kritiktir. mask, grup ve ek kullanıcı izinlerinin üst sınırını belirler. Eğer mask r-x ise, bir gruba rwx versseniz bile rx ile sınırlı kalır.
Sudo ile Komut Bazlı Yetkilendirme
Grup izinleri dosya sistemi erişimini çözer ama ya bir geliştiricinin nginx’i yeniden başlatması gerekiyorsa? Bunu root yapmak zorunda değil, ama tam root yetkisi de vermek istemiyoruz. sudoers yapılandırması burada devreye girer.
/etc/sudoers dosyasını direkt düzenlemek yerine /etc/sudoers.d/ altında ayrı dosyalar kullanın. Bu hem daha güvenli hem de yönetimi kolaylaştırır.
# Doğrudan düzenleme YAPMAYIN, her zaman visudo kullanın
sudo visudo -f /etc/sudoers.d/role_developer
Geliştirici rolü için sudo kuralları:
# /etc/sudoers.d/role_developer
# Syntax: kim nereden=(hangi_kullanıcı_olarak) komutlar
# Geliştiriciler nginx ve uygulama servisini yönetebilir
%role_developer ALL=(root) NOPASSWD: /bin/systemctl restart webapp
%role_developer ALL=(root) NOPASSWD: /bin/systemctl reload nginx
%role_developer ALL=(root) NOPASSWD: /bin/systemctl status nginx
%role_developer ALL=(root) NOPASSWD: /usr/bin/tail -f /var/log/webapp/*
# Deploy scripti çalıştırabilirler
%role_developer ALL=(root) NOPASSWD: /opt/scripts/deploy.sh
# Ama nginx config'ini DÜZENLEYEMEZLEr
# Bu satır YOK demek ki yasak
DBA rolü için:
# /etc/sudoers.d/role_dba
%role_dba ALL=(root) NOPASSWD: /bin/systemctl restart postgresql
%role_dba ALL=(root) NOPASSWD: /bin/systemctl restart mysql
%role_dba ALL=(root) NOPASSWD: /opt/dba/scripts/backup.sh
%role_dba ALL=(root) PASSWD: /usr/bin/pg_dump
Tehlikeli sudo kullanımları hakkında uyarı: Bazı komutlara asla NOPASSWD ile sudo vermeyin:
/bin/bash,/bin/shveya herhangi bir shell/usr/bin/vim,/usr/bin/nanogibi editörler (shell escape ile root olunabilir)/usr/bin/find(exec argümanı ile komut çalıştırılabilir)/usr/bin/python,/usr/bin/perlgibi yorumlayıcılar
Bu komutlara sudo vermek, dolaylı yoldan tam root erişimi vermek anlamına gelir.
Servis Hesapları ve Minimum Yetki Prensibi
Uygulamaların çalışacağı servis hesapları özel dikkat gerektirir. Bu hesapların login yetkisi olmamalı, home dizinleri kısıtlı olmalı ve sadece ihtiyaç duydukları kaynaklara erişebilmeli.
# Webapp servis hesabı
sudo useradd -r -s /sbin/nologin
-d /nonexistent
-c "Web Application Service Account"
webapp_svc
# Hesabın kilitli olduğunu doğrula
sudo passwd -S webapp_svc
# Çıktı: webapp_svc L (hesap kilitli)
# Servis hesabına sadece gerekli dizinlere erişim ver
sudo chown webapp_svc:role_developer /srv/webapp/releases
sudo chown webapp_svc:www-data /srv/webapp/shared/uploads
sudo chmod 2770 /srv/webapp/shared/uploads
# Servis hesabının gruplarını görüntüle
id webapp_svc
Şifre Politikası ve Hesap Güvenliği
Rol tasarımı sadece izinlerle bitmez. Hesap güvenlik politikaları da RBAC’ın ayrılmaz parçasıdır. chage komutu ile şifre politikalarını yönetebilirsiniz:
# Ops ekibi için sıkı şifre politikası
sudo chage -M 30 -m 7 -W 7 zeynep
# -M 30: Maksimum 30 günde şifre değişmeli
# -m 7: Minimum 7 gün aynı şifreyle kalabilir
# -W 7: 7 gün önce uyarı alır
# Geliştirici için daha esnek
sudo chage -M 90 -m 1 -W 14 ali
# Servis hesabı için şifre asla expire olmasın
sudo chage -M -1 webapp_svc
# Hesap politikasını görüntüle
sudo chage -l ali
/etc/login.defs dosyasında sistem geneli varsayılanları belirleyebilirsiniz:
sudo grep -E "^PASS_|^LOGIN_" /etc/login.defs
# PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_AGE parametrelerini inceleyin
Erişim Denetimi ve Loglama
İyi bir RBAC tasarımı, “kim ne yaptı?” sorusunu yanıtlayabilmelidir. Linux’ta bu için birkaç mekanizma vardır.
PAM ile login logları: /var/log/auth.log (Debian) veya /var/log/secure (RHEL) dosyaları tüm kimlik doğrulama olaylarını kaydeder.
sudo logları: Tüm sudo komutları varsayılan olarak loglanır:
# Son sudo kullanımlarını incele
sudo grep "sudo:" /var/log/auth.log | tail -20
# Belirli bir kullanıcının sudo komutlarını filtrele
sudo grep "sudo:.*ali" /var/log/auth.log
# Başarısız sudo denemelerini bul (yetkisiz erişim girişimi!)
sudo grep "NOT allowed" /var/log/auth.log
auditd ile gelişmiş denetim: Kritik dosyalara erişimi izlemek için auditd kullanın:
# auditd yükle ve başlat
sudo apt install auditd # veya sudo dnf install audit
# Kritik dizine yazma işlemlerini izle
sudo auditctl -w /srv/webapp/config -p wa -k config_changes
# Belirli kullanıcının dosya erişimlerini izle
sudo auditctl -a always,exit -F arch=b64
-F uid=ali -S openat -k ali_file_access
# Audit loglarını sorgula
sudo ausearch -k config_changes --start today
sudo ausearch -k ali_file_access -ts today
Otomatik Yapılandırma: Bir Kurulum Scripti
Tüm bu ayarları manuel yapmak hem zaman alıcı hem de hata yapmaya açık. Tekrarlanabilir bir kurulum için bir script hazırlamak iyi pratiktir:
#!/bin/bash
# /opt/scripts/setup_rbac.sh
# RBAC yapılandırmasını otomatik kur
set -euo pipefail
ROLES=(developer dba ops monitoring junior_dev)
LOG_FILE="/var/log/rbac_setup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Grupları oluştur
log "Rol grupları oluşturuluyor..."
for role in "${ROLES[@]}"; do
if ! getent group "role_${role}" > /dev/null 2>&1; then
groupadd "role_${role}"
log "Grup oluşturuldu: role_${role}"
else
log "Grup zaten mevcut: role_${role}"
fi
done
# Dizin yapısını kur
log "Dizin yapısı oluşturuluyor..."
mkdir -p /srv/webapp/{releases,shared,logs,config}
mkdir -p /opt/dba/{backups,scripts}
mkdir -p /var/log/webapp
# İzinleri ayarla
chown -R root:role_developer /srv/webapp/releases
chmod -R 2775 /srv/webapp/releases
chown -R root:role_developer /srv/webapp/config
chmod -R 2750 /srv/webapp/config
# ACL ayarları
setfacl -R -m g:role_monitoring:r-x /var/log/webapp
setfacl -R -d -m g:role_monitoring:r-x /var/log/webapp
log "RBAC kurulumu tamamlandı."
Bu scripti chmod +x /opt/scripts/setup_rbac.sh ile çalıştırılabilir yapın ve her yeni sunucu kurulumunda kullanın. Ansible veya Puppet gibi araçlarla entegre etmek daha da iyi olur ama bu başlı başına ayrı bir yazı konusu.
Yaygın Hatalar ve Çözümleri
Gerçek dünyada en çok karşılaştığım RBAC hatalarını paylaşayım:
“Çalışsın da nasıl çalışırsa” yaklaşımı: chmod 777 veya chown root:root sonra chmod 755 yapıp geçiştirmek. Bu, RBAC’ı tamamen anlamsız kılar. Her izin değişikliği gerekçeli olmalı ve dokümante edilmelidir.
Kullanıcıları doğrudan wheel/sudo grubuna eklemek: Ops ekibinden biri gelip “bana sudo lazım” dediğinde direkt usermod -aG sudo ali yapmayın. Bunun yerine ne işe ihtiyacı olduğunu sorun ve o komutları sudoers.d altına ekleyin.
Grup üyeliği değişikliklerinin etkili olmaması: Kullanıcıya yeni bir grup ekledikten sonra etkili olması için ya kullanıcı yeniden login olmalı ya da newgrp role_developer komutunu çalıştırmalıdır. Bunu bilmeyen birçok kullanıcı “izin çalışmıyor” diye şikayet eder.
# Mevcut oturumda yeni grup üyeliğini aktif et
newgrp role_developer
# Veya kullanıcının aktif gruplarını kontrol et
id
# Tüm grupları (yeniden login olmadan) listelemek için
groups
setgid ve ACL mask çakışmaları: Setgid bit ile ACL’yi birlikte kullanırken mask hesaplamasına dikkat edin. chmod g+x komutunu setgid bir dizinde çalıştırdığınızda ACL mask’ı etkileyebilirsiniz. Her izin değişikliğinden sonra getfacl ile kontrol edin.
Düzenli Denetim ve Bakım
RBAC bir kez kurup unutulan bir şey değildir. Düzenli denetim şarttır:
# Sudoers yapılandırmasını kontrol et
sudo visudo -c
# Tüm grup üyelerini listele
for group in $(getent group | grep "^role_" | cut -d: -f1); do
echo "=== $group ==="
getent group "$group" | cut -d: -f4 | tr ',' 'n'
done
# Login kapalı servis hesaplarını doğrula
awk -F: '$7 == "/sbin/nologin" || $7 == "/bin/false" {print $1}' /etc/passwd
# Boş parolalı hesapları bul (olmaması lazım!)
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
# 90 günden fazla login olmamış hesapları bul
sudo lastlog | awk 'NR>1 && $0 !~ /Never/ {
cmd="date -d ""$4" "$5" "$6" "$7"" +%s 2>/dev/null"
cmd | getline ts
close(cmd)
if ((systime()-ts) > 7776000) print $1
}'
Düzenli denetim için bir cron job kurmak da mantıklıdır:
# Her hafta grup üyeliklerini raporla
echo "0 8 * * 1 root /opt/scripts/audit_rbac.sh | mail -s 'Haftalık RBAC Raporu' [email protected]"
| sudo tee /etc/cron.d/rbac_audit
Sonuç
Linux’ta etkili bir RBAC tasarımı katmanlı bir yaklaşım gerektirir. Unix grupları temel erişim kontrolünü sağlar, ACL bunu granüler hale getirir, sudo komut bazlı yetkilendirme verir ve auditd tüm bunları denetlenebilir kılar. Hiçbir araç tek başına yeterli değildir; güç bu katmanların bir arada kullanılmasından gelir.
En önemli prensip minimum yetkidir: kullanıcıya ve uygulamaya, işini yapabilmesi için gereken en düşük izni verin. Bugün “kolaylık” için geniş izin vermek, yarın güvenlik olaylarında “nasıl bu kadar büyüdü?” diye sormaya yol açar.
Rollerinizi iş gereksinimlerinden türetin, teknik kısıtlamalardan değil. Önce “bu kullanıcı ne yapabilmeli ve ne yapamamalı?” sorusunu yanıtlayın, sonra teknik implementasyona geçin. Bu sıralamanın tersine gitmek, yönetilmesi imkansız karmaşık yapılara yol açar.
Son olarak, yaptığınız her izin değişikliğini dokümante edin. Altı ay sonra neden o sudo kuralını eklediğinizi hatırlamak isteyeceksiniz, inanın.