su ve sudo Arasındaki Fark ve Doğru Kullanım

Linux sistemlerde yetki yönetimi, güvenli bir ortam oluşturmanın temel taşlarından biridir. Yeni başlayan sistem yöneticilerinin sıklıkla karıştırdığı iki komut vardır: su ve sudo. Her ikisi de yükseltilmiş ayrıcalıklarla işlem yapmanı sağlar, ama çalışma mantıkları, güvenlik modelleri ve kullanım senaryoları birbirinden oldukça farklıdır. Yanlış tercih, hem güvenlik açıklarına hem de gereksiz komplikasyonlara yol açabilir. Bu yazıda her iki komutu derinlemesine inceleyeceğiz, gerçek dünya senaryolarıyla karşılaştıracağız ve hangi durumda hangisini kullanman gerektiğini netleştireceğiz.

su Komutu: Kullanıcı Değiştirmenin Klasik Yolu

su komutu, “substitute user” veya eski kaynaklarda “switch user” olarak geçer. Temelde mevcut oturumda başka bir kullanıcıya geçiş yapmanı sağlar. En yaygın kullanımı tabii ki root’a geçmektir, ama herhangi bir kullanıcıya geçiş için de kullanabilirsin.

su Nasıl Çalışır?

su komutunu çalıştırdığında, sistem senden hedef kullanıcının parolasını ister. Yani root’a geçmek istiyorsan root parolasını bilmen gerekir. Bu, birden fazla sistem yöneticisinin olduğu ortamlarda ciddi bir güvenlik sorununa dönüşebilir: ya herkes root parolasını bilir, ya da sürekli parola paylaşımı yaşanır.

# Basit su kullanımı - sadece root shell'i açar
su

# Eksi işaretiyle tam login shell açma (önerilen)
su -

# Belirli bir kullanıcıya geçiş
su - ahmet

# Kullanıcıyı değiştirmeden komut çalıştırma
su -c "systemctl restart nginx" root

Burada önemli bir ayrıntı var: su ile su - arasındaki fark. Sadece su yazdığında root’un kimliğine bürünürsün ama mevcut ortam değişkenlerin (PATH, HOME gibi) büyük bölümü kendi kullanıcından gelmeye devam eder. su - yazdığında ise root’un tam login ortamına girersin, yani sanki root olarak sisteme yeni giriş yapmış gibi olursun. Prodüksiyonda çalışırken bu fark bazen beklenmedik sorunlara yol açar.

# su ile PATH farkını görmek için
su
echo $PATH
# Çıktı: /usr/local/bin:/usr/bin:/bin:/home/kullanici/bin (eski PATH karışık gelir)

su -
echo $PATH
# Çıktı: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin (temiz root PATH)

su ile Kabuk Seçimi

su komutu varsayılan olarak hedef kullanıcının shell’ini kullanır. Ama bunu değiştirebilirsin:

# Bash ile root shell aç
su -s /bin/bash -

# Belirli bir kullanıcı için zsh ile geçiş
su -s /bin/zsh - ahmet

su’nun Zayıf Noktaları

su komutunun en büyük problemi denetlenebilirlik konusunda. Kim ne zaman root’a geçti, hangi komutları çalıştırdı? /var/log/auth.log dosyasına baktığında sadece su oturumunun açıldığını görürsün, o oturumda yapılan işlemleri değil. Bir ekipte beş kişi root parolasını biliyorsa ve bir gün bir şeyler bozulursa, kim yaptı? Bulmak çok zor.

sudo Komutu: Kontrollü Yetki Devri

sudo, “superuser do” anlamına gelir ve 1980’lerin sonunda geliştirilen, ama modern Linux sistemlerde standart hale gelen bir yetki yönetim aracıdır. Temel farkı şu: su‘da hedef kullanıcının parolasını giriyorsun, sudo‘da kendi parolasını giriyorsun.

sudo’nun Çalışma Prensibi

sudo, /etc/sudoers dosyasındaki kurallara göre hangi kullanıcının hangi komutu hangi kullanıcı olarak çalıştırabileceğini belirler. Bu yapı sayesinde birisi salt nginx servisini yönetebilecek yetkiye sahip olurken, başkası tüm sistemi yönetebilir.

# Tek bir komutu root yetkileriyle çalıştırma
sudo systemctl restart apache2

# Root shell açma (önerilmez ama bazen gereklidir)
sudo -i

# Başka bir kullanıcı olarak komut çalıştırma
sudo -u ahmet ls /home/ahmet/

# Mevcut sudo yetkilerini listeleme
sudo -l

# Parola önbelleğini temizleme
sudo -k

sudo varsayılan olarak 15 dakika boyunca parola önbelleğe alır. Yani bir kez parolayı girdikten sonra 15 dakika içinde tekrar sorulmaz. Bu süreyi /etc/sudoers dosyasından ayarlayabilirsin.

sudoers Dosyasını Yönetmek

/etc/sudoers dosyasını her zaman visudo komutuyla düzenlemelisin. Bu komut dosyayı kaydetmeden önce sözdizimi kontrolü yapar ve hatalı bir konfigürasyonun sistemi kilitlemesini engeller.

# sudoers dosyasını güvenli şekilde düzenleme
sudo visudo

# Farklı bir editörle açmak istersen
sudo EDITOR=nano visudo

Sudoers dosyasının temel sözdizimi şöyledir:

# Temel format: kullanici KAYNAK=(HEDEF_KULLANICI) KOMUTLAR

# Ahmet'e tüm root yetkilerini ver
ahmet ALL=(ALL:ALL) ALL

# Mehmet'e sadece servis yönetimi yetkisi ver
mehmet ALL=(root) /usr/bin/systemctl

# webteam grubuna nginx ve apache yönetimi ver (parola sormadan)
%webteam ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart apache2

# Belirli kullanıcıya parola sormadan belirli komutları çalıştırma izni
deploy_user ALL=(root) NOPASSWD: /usr/bin/rsync, /usr/bin/systemctl reload nginx

/etc/sudoers.d Dizini

Büyük ortamlarda her şeyi tek bir dosyaya yazmak yönetimi zorlaştırır. /etc/sudoers.d/ dizinini kullanarak modüler bir yapı kurabilirsin:

# Yeni bir kural dosyası oluşturma
sudo visudo -f /etc/sudoers.d/webteam

# Dosya içeriği örneği
# webteam grubunun web servis yönetimi
%webteam ALL=(root) /usr/bin/systemctl start nginx
%webteam ALL=(root) /usr/bin/systemctl stop nginx
%webteam ALL=(root) /usr/bin/systemctl restart nginx
%webteam ALL=(root) /usr/bin/systemctl status nginx

Bu dosyaların izinleri mutlaka 440 olmalıdır, aksi halde sudo bu dosyaları okumayı reddeder:

sudo chmod 440 /etc/sudoers.d/webteam

Günlük Loglama: sudo vs su

İşte en kritik farklardan biri burada ortaya çıkıyor. sudo her çalıştırılan komutu loglar. Kimin, ne zaman, hangi komutu, hangi host üzerinde çalıştırdığını /var/log/auth.log (Debian/Ubuntu) veya /var/log/secure (RHEL/CentOS) dosyasına yazar.

# sudo loglarını inceleme (Ubuntu/Debian)
sudo grep "sudo" /var/log/auth.log | tail -20

# Örnek log çıktısı:
# Dec 15 14:23:01 server01 sudo: ahmet : TTY=pts/1 ; PWD=/home/ahmet ;
# USER=root ; COMMAND=/usr/bin/systemctl restart nginx

# RHEL/CentOS için
sudo grep "sudo" /var/log/secure | tail -20

su için ise log çıktısı çok daha kısıtlıdır:

# su loglarını inceleme
grep "su[" /var/log/auth.log | tail -10

# Örnek çıktı - sadece oturum başlangıcı ve bitişi görünür:
# Dec 15 14:25:10 server01 su[12345]: Successful su for root by ahmet
# Oturumda yapılanlar kayıt altına alınmaz!

Gerçek Dünya Senaryoları

Senaryo 1: Web Sunucu Ekibi

Diyelim ki 5 kişilik bir web geliştirme ekibinin sunucularını yönetiyorsun. Ekip üyelerinin Apache ve Nginx servislerini yönetmesine, log dosyalarını okumasına, ama başka hiçbir şeye dokunmamasına izin vermek istiyorsun.

# /etc/sudoers.d/webteam dosyası
# Web ekibi için kısıtlı yetki tanımı

# Komut takma adları tanımla
Cmnd_Alias WEB_SERVICES = /usr/bin/systemctl start nginx, 
                          /usr/bin/systemctl stop nginx, 
                          /usr/bin/systemctl restart nginx, 
                          /usr/bin/systemctl reload nginx, 
                          /usr/bin/systemctl status nginx, 
                          /usr/bin/systemctl start apache2, 
                          /usr/bin/systemctl stop apache2, 
                          /usr/bin/systemctl restart apache2

Cmnd_Alias WEB_LOGS = /usr/bin/tail -f /var/log/nginx/*, 
                      /usr/bin/tail -f /var/log/apache2/*

# webteam grubuna bu yetkileri ver
%webteam ALL=(root) WEB_SERVICES
%webteam ALL=(root) NOPASSWD: WEB_LOGS

Bu yapıda ekip üyeleri kendi parolalarıyla servis yönetimi yapabilir, log okuyabilir ama başka hiçbir root işlemi yapamaz. Kim ne yaptı tüm detayıyla kayıt altında.

Senaryo 2: Otomatik Deployment Scripti

CI/CD pipeline’ında deployment scriptinin bazı root yetkisi gerektiren işlemleri otomatik yapması gerekiyor. Root parolasını scripte gömmek ise kabul edilemez bir güvenlik riski.

# /etc/sudoers.d/deploy kullanıcısı için
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl reload nginx
deploy ALL=(root) NOPASSWD: /usr/bin/rsync -av --delete /tmp/deploy/* /var/www/html/
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart php8.1-fpm

# Deployment scripti içinde kullanım örneği
#!/bin/bash
set -e

echo "Deployment başlatılıyor..."
sudo rsync -av --delete /tmp/deploy/* /var/www/html/
sudo systemctl reload nginx
sudo systemctl restart php8.1-fpm
echo "Deployment tamamlandı!"

Bu senaryoda su kullanmak neredeyse imkansızdır, çünkü interaktif parola girişi yoktur. sudo NOPASSWD kombinasyonu bu tür otomasyon senaryoları için biçilmiş kaftandır.

Senaryo 3: Paylaşımlı Geliştirme Sunucusu

Bir şirkette 20 geliştirici aynı sunucuyu kullanıyor ve herkesin zaman zaman bazı servisleri yeniden başlatması gerekiyor. Ama biri yanlışlıkla kritik bir servis olan sshd‘yi durdurursa sunucuya erişim kesilir.

# Tehlikeli komutları açıkça yasaklama
# /etc/sudoers.d/developers

# Yasaklanan komutları tanımla
Cmnd_Alias DANGEROUS = /usr/bin/systemctl stop sshd, 
                       /usr/bin/systemctl disable sshd, 
                       /usr/bin/systemctl mask sshd, 
                       /usr/sbin/reboot, 
                       /usr/sbin/shutdown, 
                       /usr/sbin/halt

# Genel servis yönetimi yetkisi
Cmnd_Alias SERVICES = /usr/bin/systemctl

# Önce yasağı koy, sonra izni ver (sıra önemli!)
%developers ALL=(root) !DANGEROUS
%developers ALL=(root) SERVICES

Bu örnekte ! operatörü belirli komutları açıkça yasaklar. Ancak bu yöntemin bazı bypass riskleri olduğunu belirtmek gerekir; daha güvenli yaklaşım sadece izin verilen komutları listelemektir.

Ubuntu ve Debian’da sudo Varsayılan Yapısı

Ubuntu ve türevlerinde root hesabı varsayılan olarak kilitlidir. Bu yüzden su - çalıştırmak istesen parola istenir ama root parolası yoktur. Bu sistemlerde sudo -i veya sudo su - kullanman gerekir.

# Ubuntu'da root shell açmanın yolları
sudo -i          # root'un login shell'ini açar (önerilen)
sudo su -        # su aracılığıyla root'a geçiş
sudo bash        # root bash shell'i açar (tam login değil)

# Ubuntu'da root parolası ayarlama (genellikle önerilmez)
sudo passwd root

# Root parolasını tekrar kilitlemek için
sudo passwd -l root

RHEL, CentOS ve Fedora Ekosistemi

Red Hat tabanlı sistemlerde wheel grubu özel bir öneme sahiptir. Bu gruba üye olan kullanıcılar varsayılan olarak sudo yetkisine sahip olur.

# Kullanıcıyı wheel grubuna ekleme (RHEL/CentOS)
sudo usermod -aG wheel ahmet

# Fedora'da aynı işlem
sudo usermod -aG wheel ahmet

# Wheel grubunun sudoers'daki tanımını kontrol et
sudo grep wheel /etc/sudoers
# %wheel  ALL=(ALL)       ALL

sudo ile Ortam Değişkenleri

Bir uygulama dağıtımı sırasında ortam değişkenlerinin sudo ile nasıl çalıştığını bilmemek sinir bozucu sorunlara yol açabilir. sudo varsayılan olarak birçok ortam değişkenini temizler.

# Ortam değişkenlerini koruyarak sudo çalıştırma
sudo -E env_degiskeni_gerektirenkomut

# Belirli değişkenleri geçirme
sudo MY_VAR=deger komut

# sudoers'da ortam değişkeni geçirme izni
# Defaults env_keep += "MY_VAR APPLICATION_ENV"
sudo visudo
# Şu satırı ekle:
# Defaults env_keep += "MY_VAR APPLICATION_ENV DEBUG_MODE"

Güvenlik İpuçları ve Yaygın Hatalar

Yıllar içinde gördüğüm en yaygın hataları paylaşayım:

  • sudo su - kullanmak: Bu iki komutun birlikte kullanılması loglama açısından sorunludur. Su oturumu açıldıktan sonra yapılanlar sudo tarafından loglanmaz. sudo -i kullan.
  • NOPASSWD: ALL vermek: Bir kullanıcıya parola sorulmadan tüm komutları çalıştırma yetkisi vermek, pratik olarak root parolasını vermekle eşdeğerdir.
  • Sudoers dosyasını direkt editörle açmak: visudo yerine nano /etc/sudoers kullanmak, sözdizimi hatası yapıldığında sistemi tamamen kilitleyebilir.
  • Wildcard kullanırken dikkatli olmamak: sudo ALL=(root) /usr/bin/vim * gibi bir kural, vim /etc/sudoers yazmaya da izin verir ve kullanıcı oradan her şeyi değiştirebilir.
# Kötü örnek - vim üzerinden yetki yükseltme açığı
# %developers ALL=(root) /usr/bin/vim /var/www/html/*
# Kullanıcı şunu yapabilir: sudo vim /var/www/html/dosya
# Vim içinden :!/bin/bash ile root shell alabilir!

# İyi örnek - sadece belirli bir dizini düzenleme
# Bu bile tehlikeli olabilir, editörler yerine özel scriptler kullan
%developers ALL=(root) /usr/local/bin/edit-config.sh
# sudo yetkilerini test etmek için
sudo -l -U ahmet   # Ahmet kullanıcısının yetkilerini listele

# Komut çıktısı örneği:
# User ahmet may run the following commands on server01:
#     (root) /usr/bin/systemctl restart nginx
#     (root) NOPASSWD: /usr/bin/tail -f /var/log/nginx/*

PAM ile sudo Entegrasyonu

Kurumsal ortamlarda LDAP veya Active Directory entegrasyonu sık yapılır. sudo PAM altyapısını kullandığı için bu entegrasyonlara kolayca dahil edilebilir:

# LDAP ile sudo entegrasyonu için gerekli paket
sudo apt install libpam-ldap sudo-ldap    # Debian/Ubuntu
sudo dnf install nss-pam-ldapd sudo      # RHEL/Fedora

# /etc/nsswitch.conf'a sudoers satırı ekle
# sudoers: files ldap

# LDAP'tan gelen grup üyeliğiyle sudo yetkisi verme
# /etc/sudoers.d/ldap-groups dosyasına:
# %linux-admins ALL=(ALL:ALL) ALL
# %web-operators ALL=(root) /usr/bin/systemctl restart nginx

Sonuç

su ve sudo arasındaki tercih, aslında sadece teknik bir karar değil, bir güvenlik felsefesi tercihidir. su, “güven ve tam yetki ver” anlayışını temsil ederken; sudo, “en az yetki ilkesi” (principle of least privilege) anlayışını hayata geçirir.

Günümüz prodüksiyon ortamları için tavsiyem net: Varsayılan tercih sudo olmalı. Root parolasını paylaşmak yerine, ihtiyaç duyulan komutlara özel yetkiler ver. Loglama sayesinde kimin ne yaptığını her zaman izleyebilirsin. Bir şeyler ters gittiğinde de hesap verebilirlik mümkün olur.

su komutunun hala geçerli olduğu durumlar tabii ki var. Özellikle root parolasının bilindiği, tek yöneticinin çalıştığı ortamlarda ya da başka bir kullanıcı olarak interaktif çalışman gerektiğinde su gayet mantıklıdır. Ama çok kullanıcılı, kurumsal veya paylaşımlı ortamlarda sudo altyapısı kurmak için harcadığın zaman, ilerleyen dönemde seni pek çok baş ağrısından kurtarır.

Son olarak şunu hatırlatmak isterim: En iyi güvenlik yapılandırması bile yanlış alışkanlıklarla delik deşik olabilir. sudo visudo yerine nano /etc/sudoers kullanma alışkanlığını değiştiremeyen bir ekip, ne kadar güzel bir sudoers konfigürasyonu yazarsa yazsın, bir gün bu hatanın bedelini öder. Araçları doğru öğrenmek kadar, doğru alışkanlıkları yerleştirmek de sistem yöneticiliğinin temel sorumluluklarından biridir.

Yorum yapın