sudo Yapılandırması: /etc/sudoers Dosyası ve visudo Kullanımı

Sistem yönetiminde en kritik konulardan biri, kullanıcılara root yetkisi vermeden belirli komutları çalıştırma iznini nasıl düzgün ayarlayacağınızdır. sudo mekanizması tam da bu iş için tasarlanmış olsa da yanlış yapılandırılmış bir /etc/sudoers dosyası sisteminizi ciddi güvenlik açıklarına karşı savunmasız bırakabilir. Bu yazıda sudo yapılandırmasını derinlemesine inceleyeceğiz, gerçek dünya senaryolarıyla pekiştireceğiz.

sudo Nedir ve Neden Önemlidir?

sudo (superuser do), normal kullanıcıların belirli komutları root veya başka bir kullanıcı yetkisiyle çalıştırmasına olanak tanır. Temel mantık şudur: kullanıcıya root parolasını vermek yerine, kendi parolasıyla kimliğini doğrulayarak önceden tanımlanmış komutları çalıştırmasına izin verirsiniz.

Neden önemli olduğuna birkaç somut örnekle bakalım:

  • Bir web geliştirici Apache servisini yeniden başlatmak zorunda ama sunucuya tam root erişimi vermek istemiyorsunuz.
  • DBA ekibinizin PostgreSQL servisini yönetmesi gerekiyor ama sisteme başka müdahale etmesini istemiyorsunuz.
  • Junior sysadmin systemctl komutlarını çalıştırabilmeli ama userdel veya fdisk gibi tehlikeli komutlara erişimi olmamalı.

Tüm bu senaryoları sudo yapılandırmasıyla zarif bir şekilde çözebilirsiniz.

/etc/sudoers Dosyasını Anlama

/etc/sudoers dosyası sudo‘nun kalbidir. Bu dosya okunabilir ama doğrudan bir metin editörüyle düzenlenmemelidir. Neden? Çünkü sözdizimi hatası içeren bir sudoers dosyası tüm sudo erişimini kilitleyebilir. Böyle bir durumda single-user mode’a geçmek zorunda kalırsınız, bu da üretim sunucusunda ciddi bir sorundur.

Dosyanın temel yapısını inceleyelim:

# /etc/sudoers dosyasının varsayılan içeriğini görüntüleme
sudo cat /etc/sudoers

Tipik bir sudoers dosyası şu bölümlerden oluşur:

# Defaults tanımları
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults        logfile="/var/log/sudo.log"

# Kullanıcı yetkileri bölümü
root    ALL=(ALL:ALL) ALL

# Grup yetkileri
%sudo   ALL=(ALL:ALL) ALL
%wheel  ALL=(ALL:ALL) ALL

# Dosya dahil etme
@includedir /etc/sudoers.d

Temel Sözdizimi

sudoers dosyasındaki kural formatı şu şekildedir:

kullanici  HOST=(RUNAS:GROUP) KOMUTLAR

Bu dört bileşeni açalım:

  • kullanici: Kuralın uygulanacağı kullanıcı adı. % ile başlıyorsa grup kuralıdır.
  • HOST: Kuralın hangi makinede geçerli olduğu. ALL her yerde geçerli anlamına gelir.
  • RUNAS: Komutun hangi kullanıcı adına çalıştırılacağı. (ALL) her kullanıcı adına çalıştırılabilir demektir.
  • KOMUTLAR: İzin verilen komutların tam yolları. ALL tüm komutlara izin verir.

visudo: Güvenli Düzenleme Aracı

visudo komutu, sudoers dosyasını düzenlemek için tasarlanmış özel bir araçtır. Normal bir metin editörüyle sudoers dosyasını açmak yerine her zaman visudo kullanmalısınız.

# sudoers dosyasını düzenlemek için
sudo visudo

# Farklı bir editörle kullanmak istiyorsanız
sudo EDITOR=nano visudo

# Belirli bir sudoers.d dosyasını düzenlemek için
sudo visudo -f /etc/sudoers.d/webteam

visudo‘nun avantajları şunlardır:

  • Kaydederken sözdizimini kontrol eder.
  • Sözdizimi hatası varsa kaydetmeden önce sizi uyarır.
  • Dosyayı kilitleyerek eş zamanlı düzenlemeleri engeller.
  • Hatalı düzenleme durumunda mevcut çalışan konfigürasyonu korur.

Eğer sözdizimi hatası yaparsanız visudo şuna benzer bir uyarı verir:

>>> /etc/sudoers: syntax error near line 28 <<<
What now?
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save anyway (DANGER!)

Asla Q seçeneğini seçmeyin. Bu seçenek hatalı dosyayı kaydeder ve sisteminizi kilitleyebilir.

Gerçek Dünya Senaryoları

Senaryo 1: Web Sunucusu Ekibi

Bir web geliştirme ekibiniz var. Bu ekip Apache/Nginx servislerini yönetebilmeli, log dosyalarını okuyabilmeli ama sisteme başka müdahale etmemeli.

sudo visudo -f /etc/sudoers.d/webteam
# Web ekibi için grup tanımı
%webteam    ALL=(root) /usr/bin/systemctl restart apache2, 
                       /usr/bin/systemctl reload apache2, 
                       /usr/bin/systemctl status apache2, 
                       /usr/bin/systemctl restart nginx, 
                       /usr/bin/systemctl reload nginx, 
                       /bin/cat /var/log/apache2/*.log, 
                       /bin/tail /var/log/apache2/*.log

Şimdi web ekibindeki bir kullanıcı şu komutları çalıştırabilir:

sudo systemctl restart apache2
sudo tail /var/log/apache2/error.log

Senaryo 2: Veritabanı Ekibi

DBA ekibinizin PostgreSQL’i yönetmesi gerekiyor:

# /etc/sudoers.d/dba dosyasına eklenecek
%dba    ALL=(postgres) /usr/bin/psql, 
                       /usr/bin/pg_dump, 
                       /usr/bin/pg_restore
%dba    ALL=(root) /usr/bin/systemctl restart postgresql, 
                   /usr/bin/systemctl status postgresql

DBA kullanıcısı şu şekilde PostgreSQL kullanıcısı olarak psql çalıştırabilir:

sudo -u postgres psql
sudo -u postgres pg_dump mydb > backup.sql

Senaryo 3: Sudo Olmadan Parola İsteme (NOPASSWD)

Monitoring scriptlerinin veya otomatik görevlerin sudo parola istemeden çalışması gerektiğinde kullanılır. Dikkatli kullanın!

# /etc/sudoers.d/monitoring
monitoring_user    ALL=(root) NOPASSWD: /usr/bin/systemctl status *, 
                                        /bin/df, 
                                        /usr/bin/free, 
                                        /bin/netstat

Ansible veya benzeri otomasyon araçları için servis hesabı yapılandırması:

# /etc/sudoers.d/ansible
ansible_svc    ALL=(ALL) NOPASSWD: ALL

Bu son kural oldukça geniş bir yetki veriyor. Üretim ortamında daha kısıtlayıcı olmayı tercih edin.

Senaryo 4: Belirli Komutları Yasaklama

! operatörü ile belirli komutları açıkça yasaklayabilirsiniz:

# Junior sysadmin'e geniş yetki ver ama tehlikeli komutları yasakla
junior_admin    ALL=(ALL) ALL, 
                !SHELLS, 
                !/bin/su, 
                !/usr/bin/passwd root, 
                !/bin/bash, 
                !/bin/sh

# Shell alias tanımı
Cmnd_Alias SHELLS = /bin/bash, /bin/sh, /bin/zsh, /usr/bin/fish

Önemli uyarı: ! operatörüne çok güvenmeyin. Bir kullanıcı sudo bash -c "komut" gibi dolaylı yollarla kısıtlamaları aşabilir. Gerçek güvenlik için whitelist (izin verilenler listesi) yaklaşımı daha güvenlidir.

Alias Kullanımı

Alias’lar sudoers dosyasını okunabilir ve yönetilebilir hale getirir. Dört tip alias vardır:

# Komut alias'ları
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, 
                      /usr/bin/systemctl stop *, 
                      /usr/bin/systemctl restart *, 
                      /usr/bin/systemctl status *

Cmnd_Alias NETWORKING = /sbin/ifconfig, 
                        /sbin/ip, 
                        /bin/netstat, 
                        /sbin/ss

Cmnd_Alias PACKAGE_MGMT = /usr/bin/apt, 
                           /usr/bin/apt-get, 
                           /usr/bin/dpkg

# Kullanıcı alias'ları
User_Alias WEBADMINS = ahmet, mehmet, ayse
User_Alias DBADMINS = ali, veli

# Host alias'ları (çok sunuculu ortamlarda kullanışlı)
Host_Alias WEBSERVERS = web01, web02, web03
Host_Alias DBSERVERS = db01, db02

# RunAs alias'ları
Runas_Alias DB_USERS = postgres, mysql

# Alias'ları kullanarak kural oluşturma
WEBADMINS    WEBSERVERS=(root) SERVICES, NETWORKING
DBADMINS     DBSERVERS=(DB_USERS) ALL
WEBADMINS    ALL=(root) PACKAGE_MGMT

Bu yapı hem okunması kolay hem de bakımı basit bir konfigürasyon sağlar.

Defaults Direktifleri

Defaults direktifleri sudo‘nun davranışını özelleştirmenizi sağlar. En önemli olanları:

# Güvenli PATH ayarı - hijacking saldırılarına karşı
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Sudo log dosyası
Defaults    logfile="/var/log/sudo.log"

# Hatalı parola girişlerinde mail gönder
Defaults    mail_badpass
Defaults    mailto="[email protected]"

# Çevre değişkenlerini sıfırla (güvenlik için önemli)
Defaults    env_reset

# Belirli çevre değişkenlerini koru
Defaults    env_keep += "HOME MAIL"

# Terminal olmadan sudo kullanımını engelle (güvenlik)
Defaults    requiretty

# Oturum zaman aşımı (dakika cinsinden, 0 = her seferinde parola sor)
Defaults    timestamp_timeout=15

# Belirli kullanıcı için farklı timeout
Defaults:ahmet    timestamp_timeout=5

# Parola denemesi sayısı
Defaults    passwd_tries=3

# sudo -l çalıştırıldığında kısa format
Defaults    listpw=always

/etc/sudoers.d Dizinini Kullanma

Ana sudoers dosyasını şişirmek yerine modüler yapı için /etc/sudoers.d/ dizinini kullanın. Bu yaklaşım şu avantajları sağlar:

  • Her ekip veya servis için ayrı dosya yönetimi
  • Konfigürasyon yönetim araçlarıyla (Ansible, Puppet, Chef) kolay entegrasyon
  • Bir dosyadaki hata diğerlerini etkilemez
  • git ile versiyonlama kolaylığı
# Yeni bir sudoers.d dosyası oluşturma
sudo visudo -f /etc/sudoers.d/devops_team

# Dosya içeriği örneği
# Açıklayıcı yorum ekleyin
# DevOps ekibi yetkileri - Son güncelleme: 2024-01
# Sorumlu: Ahmet Yilmaz

User_Alias DEVOPS = ahmet, mehmet, fatma

Cmnd_Alias DOCKER_CMDS = /usr/bin/docker, /usr/bin/docker-compose
Cmnd_Alias K8S_CMDS = /usr/bin/kubectl, /usr/local/bin/helm

DEVOPS    ALL=(root) DOCKER_CMDS, K8S_CMDS
DEVOPS    ALL=(root) NOPASSWD: /usr/bin/systemctl status *

Dosya izinlerine dikkat edin. sudoers.d altındaki dosyalar 0440 izninde ve root’a ait olmalıdır:

# Dosya izinlerini kontrol et
ls -la /etc/sudoers.d/

# Yanlış izinleri düzelt
sudo chmod 0440 /etc/sudoers.d/devops_team
sudo chown root:root /etc/sudoers.d/devops_team

sudo Loglarını İzleme

sudo kullanımını izlemek güvenlik açısından kritiktir. Kim ne zaman hangi komutu çalıştırdığını takip etmelisiniz.

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

# CentOS/RHEL sistemlerde
sudo grep sudo /var/log/secure | tail -20

# Özel sudo log dosyası yapılandırıldıysa
sudo tail -f /var/log/sudo.log

# Belirli kullanıcının sudo kullanımını filtrele
sudo grep "ahmet" /var/log/auth.log | grep sudo

Tipik bir sudo log girişi şöyle görünür:

Jan 15 14:23:01 webserver01 sudo: ahmet : TTY=pts/0 ; PWD=/home/ahmet ; USER=root ; COMMAND=/usr/bin/systemctl restart apache2

Bu satır size şunları söyler: Tarih/saat, hangi sunucu, hangi kullanıcı, hangi terminalden, hangi dizinden, hangi kullanıcı adına, hangi komutu çalıştırdı.

Yapılandırmayı Test Etme

sudoers değişikliklerinden sonra test etmek iyi bir alışkanlıktır:

# Bir kullanıcının sudo yetkilerini listele
sudo -l -U ahmet

# Kendi yetkilerinizi listeleyin
sudo -l

# Belirli bir komutu simüle et (çalıştırmadan test)
sudo -l -U ahmet | grep systemctl

# Syntax kontrolü
sudo visudo -c

# Belirli bir dosyanın syntax kontrolü
sudo visudo -c -f /etc/sudoers.d/webteam

sudo -l -U ahmet çıktısı şuna benzer:

Matching Defaults entries for ahmet on webserver01:
    env_reset, mail_badpass, secure_path=...

User ahmet may run the following commands on webserver01:
    (root) /usr/bin/systemctl restart apache2
    (root) /usr/bin/systemctl reload apache2
    (root) NOPASSWD: /usr/bin/systemctl status *

Güvenlik En İyi Uygulamaları

Gerçek ortamda uygulamanız gereken bazı temel kurallar:

  • En az yetki prensibi: Kullanıcılara sadece ihtiyaç duydukları komutlar için izin verin. ALL yetkisini minimize edin.
  • NOPASSWD dikkatli kullanın: Sadece gerçekten parola girmesi mümkün olmayan otomatik süreçler için kullanın.
  • Komut yollarını tam belirtin: systemctl yerine /usr/bin/systemctl yazın. Bu PATH manipülasyonunu engeller.
  • Wildcard kullanımında dikkatli olun: systemctl restart * gibi wildcard’lar beklenmedik komutlara yol açabilir.
  • Düzenli denetim yapın: sudoers dosyasını düzenli gözden geçirin, gereksiz yetkileri temizleyin.
  • Değişiklikleri versiyonlayın: /etc/sudoers.d/ dizinini git ile takip edin.
# Tehlikeli wildcard örneği - bunu yapMAYIN
ahmet    ALL=(root) /usr/bin/vi *
# Çünkü: sudo vi /etc/sudoers ile her şeyi değiştirebilir!

# Doğru yaklaşım - belirli dosyaları belirtin
ahmet    ALL=(root) /usr/bin/vi /var/www/html/config.php

Yaygın Hatalar ve Çözümleri

Hata 1: “ahmet is not in the sudoers file”

# Kullanıcıyı sudo grubuna ekle (Ubuntu/Debian)
sudo usermod -aG sudo ahmet

# CentOS/RHEL için wheel grubu
sudo usermod -aG wheel ahmet

# Değişikliği hemen uygula (kullanıcı yeniden login olmalı)
# veya:
newgrp sudo

Hata 2: Syntax hatası nedeniyle sudo çalışmıyor

Bu durumda pkexec aracını kullanabilirsiniz:

# pkexec ile sudoers dosyasını düzelt
pkexec visudo

# Veya single-user mode'a geçip düzelt
# GRUB'dan 'recovery mode' veya 'single user mode' seçin

Hata 3: “sorry, you must have a tty to run sudo”

# Bu hata requiretty Defaults ayarından gelir
# Belirli kullanıcı için devre dışı bırak
Defaults:ansible_svc    !requiretty

# Veya tüm sistem için (güvenlik riski!)
# Defaults    !requiretty

Sonuç

sudo yapılandırması, Linux sistem yönetiminin hem en kritik hem de en sık ihmal edilen konularından biridir. Pek çok ortamda ya herkese ALL=(ALL) ALL veriliyor ya da hiç yapılandırılmadan bırakılıyor. Bu yaklaşımların ikisi de güvenlik sorunlarına davetiye çıkarır.

İyi bir sudo yapılandırması için şu prensipleri benimseyin: En az yetki prensibini uygulayın, her zaman visudo kullanın, /etc/sudoers.d/ ile modüler yapı kurun, logları düzenli izleyin ve yapılandırmanızı düzenli olarak audit edin. Alias’ları kullanarak dosyanızı okunabilir tutun.

Ekibiniz büyüdükçe ve sisteminiz karmaşıklaştıkça bu yapılandırmaları Ansible veya Puppet gibi konfigürasyon yönetim araçlarıyla yönetmeyi düşünün. Böylece hem tutarlılık sağlarsınız hem de her değişikliği versiyonlayabilirsiniz.

Unutmayın: Bir sysadmin’in en önemli görevi, sistemi çalışır tutmakla birlikte güvenliğini de sağlamaktır. sudo bu dengeyi kurmanın en zarif yollarından biridir.

Yorum yapın