Geçici Sudo Yetkisi: Belirli Süre ve Komutla Sınırlı Erişim Verme

Bir sistemde geçici sudo yetkisi vermek, sysadmin hayatının en hassas konularından biri. “Şu arkadaşa bir bakayım” diye tam yetki veriyorsunuz, sonra o yetki orada kalıyor, unutuluyor ve bir gün başınıza bela açıyor. Oysa sudoers dosyasını ve birkaç araçı doğru kullanırsanız, hem belirli komutlarla sınırlı hem de belirli süre sonra otomatik olarak sona eren yetkiler tanımlayabilirsiniz. Bu yazıda bu konuyu derinlemesine ele alacağız.

Neden Kalıcı Sudo Değil?

Klasik senaryo şu: Geliştirici ekibinden biri sunucuda bir servis başlatamıyor, sizden yardım istiyor. Siz de hızlıca usermod -aG sudo ahmet yazıyorsunuz. İş çözülüyor, ama Ahmet artık o sunucuda tam root yetkisine sahip. Proje bitti, Ahmet başka ekibe geçti, yetki hâlâ orada.

Bu tür birikmiş yetkiler, güvenlik denetimlerinde en sık karşılaşılan sorunların başında geliyor. Principle of Least Privilege (En Az Yetki İlkesi) tam da bunu söylüyor: Kullanıcıya sadece ihtiyacı olan yetkiyi, sadece ihtiyacı olan süre için ver.

Geçici ve sınırlı sudo erişimi şu durumlarda kritik hale geliyor:

  • Dış danışmanların sisteme bakması gerektiğinde
  • Stajyerlerin belirli servisleri yönetmesi gerektiğinde
  • Nöbet/vardiya sistemi olan ekiplerde
  • Acil müdahale senaryolarında belirli bir kişiye geçici yetki verilmesi gerektiğinde
  • CI/CD pipeline’larının yalnızca belirli komutları çalıştırması gerektiğinde

sudoers Dosyasının Anatomisi

Her şey /etc/sudoers dosyasında başlıyor. Bu dosyayı doğrudan vi veya nano ile açmayın, her zaman visudo kullanın. visudo sözdizimini kaydederken kontrol eder ve hatalı bir konfigürasyonun sizi sistemden kilitlemesini önler.

sudo visudo

Temel sudoers satır yapısı şu şekilde:

kullanici SUNUCU=(OLARAK_KIM) KOMUTLAR

Örneğin:

# Ahmet, bu sunucuda root olarak yalnızca nginx'i yönetebilir
ahmet ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

Grup bazlı tanımlama için % işareti kullanıyoruz:

# ops-team grubu belirli komutları çalıştırabilir
%ops-team ALL=(root) /usr/bin/systemctl restart apache2, /usr/bin/tail -f /var/log/apache2/error.log

Komut Bazlı Kısıtlama: Detaylar

Komut kısıtlaması yaparken dikkat etmeniz gereken bazı incelikler var. Yalnızca binary’nin yolunu yazmak yetmez, argümanları da kontrol etmeniz gerekebilir.

# Sadece belirli bir servis için restart yetkisi
ahmet ALL=(root) /usr/bin/systemctl restart myapp.service

# Tüm systemctl komutlarına izin vermek (DİKKATLİ OLUN - tehlikeli)
ahmet ALL=(root) /usr/bin/systemctl

# Belirli bir dizindeki logları okuma yetkisi
ahmet ALL=(root) /usr/bin/tail -f /var/log/myapp/*.log

# Şifresiz sudo için NOPASSWD direktifi
ahmet ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp.service

NOPASSWD direktifini otomatik sistemler için, yani CI/CD pipeline’ları veya monitoring scriptleri için kullanabilirsiniz. İnsan kullanıcılar için mümkünse şifre sorulsun.

Bir de NOEXEC direktifi var, bunu genellikle atlarlar ama çok önemli:

# Bu kullanıcı less veya vim üzerinden shell escape yapamaz
ahmet ALL=(root) NOEXEC: /usr/bin/less /var/log/syslog

NOEXEC olmadan, less veya vim gibi programlar içinden !bash yaparak shell açılabilir. Bu ciddi bir güvenlik açığıdır.

Zaman Bazlı Erişim: sudoers ile Yaklaşımlar

Pure sudoers dosyası zaman sınırlaması için doğal bir mekanizma sunmuyor. Ama birkaç farklı yöntemle bunu başarabiliyoruz.

Yöntem 1: at ve cron ile Yetki Kaldırma

En basit yöntem: yetkiyi ver, belirli süre sonra kaldıracak bir iş zamanla.

# Ahmet'e yetki ver
sudo usermod -aG wheel ahmet  # RHEL/CentOS için
# veya
sudo usermod -aG sudo ahmet   # Debian/Ubuntu için

# 4 saat sonra yetkiyi kaldır
echo "sudo gpasswd -d ahmet sudo" | at now + 4 hours

# at komutunun kurulu olduğundan emin olun
sudo apt install at -y  # Debian/Ubuntu
sudo yum install at -y  # RHEL/CentOS

Bu yaklaşım basit ama kaba. Daha ince kontrole ihtiyacınız varsa devam edin.

Yöntem 2: sudoers.d ile Geçici Dosya ve Cron

/etc/sudoers.d/ dizinini kullanarak modüler bir yapı kurabilirsiniz. Her kullanıcı veya proje için ayrı dosya, yönetimi kolaylaştırır.

# Geçici yetki dosyası oluştur
cat > /etc/sudoers.d/temp-ahmet << 'EOF'
# Geçici yetki - 2024-01-15 tarihine kadar
ahmet ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp.service, /usr/bin/journalctl -u myapp.service
EOF

# Dosya izinlerini doğru ayarla (bu çok önemli!)
chmod 440 /etc/sudoers.d/temp-ahmet

# Sözdizimini kontrol et
visudo -c -f /etc/sudoers.d/temp-ahmet

Şimdi bu dosyayı belirli tarihte kaldıracak bir cron işi ekleyelim:

# root crontab'ına ekle
sudo crontab -e

# 15 Ocak 2024 gece yarısı yetkiyi kaldır
0 0 15 1 * rm -f /etc/sudoers.d/temp-ahmet && logger "Geçici sudo yetkisi kaldırıldı: ahmet"

Yöntem 3: sudo_logsrvd ve Timestamp Manipülasyonu

sudo komutunun -r (reset) ve timestamp mekanizmasını kullanarak daha dinamik bir kontrol sağlayabilirsiniz.

# Kullanıcının mevcut sudo timestamp'ini sil (yetkiyi hemen iptal et)
sudo -K -u ahmet

# Ya da sudoers'da timestamp_timeout ile oturum süresini sınırla
# /etc/sudoers içine ekleyin:
Defaults:ahmet timestamp_timeout=30

timestamp_timeout=30 ifadesi, Ahmet’in sudo şifresini girdikten sonra 30 dakika boyunca tekrar şifre sorulmayacağı anlamına gelir. 0 yaparsanız her seferinde şifre ister, -1 yaparsanız hiç sormaz.

Pratik Senaryo: Danışman Erişimi

Diyelim ki bir dış güvenlik danışmanı sisteminize bakacak. 48 saat için, sadece log okuma ve bazı tanı komutlarına erişim vermek istiyorsunuz.

#!/bin/bash
# grant-temp-access.sh

USERNAME=$1
HOURS=$2
EXPIRY=$(date -d "+${HOURS} hours" "+%Y-%m-%d %H:%M")

if [ -z "$USERNAME" ] || [ -z "$HOURS" ]; then
    echo "Kullanim: $0 <kullanici> <saat>"
    exit 1
fi

# Sudoers dosyası oluştur
SUDOERS_FILE="/etc/sudoers.d/temp-${USERNAME}"

cat > "$SUDOERS_FILE" << EOF
# Geçici erişim: $USERNAME
# Oluşturulma: $(date)
# Son geçerlilik: $EXPIRY
# Yetkili: $(whoami)

$USERNAME ALL=(root) NOPASSWD: /usr/bin/journalctl, \
    /usr/bin/tail, \
    /usr/bin/cat /var/log/*, \
    /usr/bin/systemctl status *, \
    /usr/bin/ss -tlnp, \
    /usr/bin/netstat -tlnp, \
    /usr/bin/df -h, \
    /usr/bin/free -m, \
    /usr/bin/top, \
    /usr/bin/htop
EOF

chmod 440 "$SUDOERS_FILE"

# Sözdizimi kontrolü
if ! visudo -c -f "$SUDOERS_FILE" 2>/dev/null; then
    rm -f "$SUDOERS_FILE"
    echo "HATA: Sudoers dosyasında sözdizim hatası!"
    exit 1
fi

# Yetkiyi kaldıracak cron işi ekle
(crontab -l 2>/dev/null; echo "0 */${HOURS} * * * rm -f ${SUDOERS_FILE} && logger 'Geçici sudo yetkisi sona erdi: ${USERNAME}'") | crontab -

echo "Yetki verildi: $USERNAME, $HOURS saat, bitiş: $EXPIRY"
logger "Geçici sudo yetkisi verildi: $USERNAME, $HOURS saat, admin: $(whoami)"

Bu scripti kullanmak için:

sudo bash grant-temp-access.sh consultant 48

sudo_logsrvd ile Merkezi Log ve Denetim

Geçici yetkiler verirken denetim kaydı tutmak zorunlu. Kim hangi komutu ne zaman çalıştırdı? Bunu sudo kendi başına zaten loglayabiliyor.

# /etc/sudoers içine ekleyin
Defaults logfile=/var/log/sudo.log
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io/%{user}

# Log dosyasını izlemek için
sudo tail -f /var/log/sudo.log

# Ya da journald üzerinden
sudo journalctl -f | grep sudo

log_input ve log_output direktifleri, kullanıcının sudo oturumunda hem girdiği komutları hem de çıktıları kaydeder. Bu biraz disk kaplar ama güvenlik denetimi için altın değerinde.

# Sudo I/O loglarını görüntülemek için sudoreplay kullanın
sudo sudoreplay -d /var/log/sudo-io /var/log/sudo-io/ahmet/00/00/01

sudo_timestamp ile Fine-Grained Kontrol

Ubuntu 20.04+ ve modern RHEL/CentOS sistemlerde sudo‘nun timestamp mekanizması çok daha gelişmiş. Her terminal oturumu için ayrı timestamp tutabiliyorsunuz.

# /etc/sudoers içine per-tty timestamp ekleyin
Defaults timestamp_type=tty
Defaults:ahmet timestamp_timeout=0  # Her seferinde şifre sor

# Global olarak tüm kullanıcılara kısa timeout
Defaults timestamp_timeout=5  # 5 dakika

Gerçek Dünya Senaryosu: Nöbet Sistemi

Birçok ekipte nöbet sistemi var. Nöbetçi kişinin belirli acil müdahale komutlarına erişmesi gerekiyor ama mesai saatleri dışında tam yetkiye gerek yok.

#!/bin/bash
# nobet-yonetim.sh

NOBET_GRUBU="on-call-ops"
SUDOERS_NOBET="/etc/sudoers.d/nobet-yetki"

# Nöbet yetkilerini tanımla
cat > "$SUDOERS_NOBET" << 'EOF'
# Nöbet ekibi acil müdahale yetkileri
%on-call-ops ALL=(root) NOPASSWD: 
    /usr/bin/systemctl restart *, 
    /usr/bin/systemctl stop *, 
    /usr/bin/systemctl start *, 
    /usr/bin/journalctl -u * -n *, 
    /usr/bin/kill, 
    /usr/sbin/nginx -t, 
    /usr/bin/mysql -e "SHOW PROCESSLIST", 
    /usr/bin/redis-cli FLUSHDB

# Log okuma her zaman açık
%on-call-ops ALL=(root) NOPASSWD: /usr/bin/tail -f /var/log/*
EOF

chmod 440 "$SUDOERS_NOBET"

# Nöbetçiyi gruba ekle
if [ "$1" = "baslat" ]; then
    sudo gpasswd -a "$2" "$NOBET_GRUBU"
    logger "Nöbet başladı: $2"
    echo "$2 nöbet grubuna eklendi"
elif [ "$1" = "bitir" ]; then
    sudo gpasswd -d "$2" "$NOBET_GRUBU"
    logger "Nöbet bitti: $2"
    echo "$2 nöbet grubundan çıkarıldı"
fi

Yaygın Hatalar ve Kaçınma Yolları

Wildcard kullanımında dikkat: systemctl yazmak her şeye izin verir demek. Mümkün olduğunca spesifik olun.

# YANLIŞ - Çok geniş
ahmet ALL=(root) /usr/bin/systemctl *

# DOĞRU - Spesifik servis ve komut
ahmet ALL=(root) /usr/bin/systemctl restart myapp.service, /usr/bin/systemctl status myapp.service

Dosya izinlerini unutmayın: /etc/sudoers.d/ altındaki dosyalar mutlaka 440 veya 0440 olmalı, aksi takdirde sudo bu dosyaları görmezden gelir.

# İzin kontrolü
ls -la /etc/sudoers.d/
# Beklenen çıktı: -r--r----- 1 root root

# Toplu izin düzeltme
chmod 440 /etc/sudoers.d/*

Shell escape’e karşı önlem: vim, less, awk, perl gibi programlar shell escape yapabilir. Bu programlara sudo yetkisi veriyorsanız NOEXEC kullanın.

# Güvenli log okuma yetkisi
ahmet ALL=(root) NOEXEC: NOPASSWD: /usr/bin/less /var/log/nginx/error.log

Yetki temizliğini otomatize edin: Manuel verilen yetkileri unutmak çok kolay. Bir yetki envanteri tutun.

# Mevcut geçici yetkileri listele
ls -la /etc/sudoers.d/ | grep temp-

# Tüm sudoers kurallarını derle ve kontrol et
sudo visudo -c
sudo grep -r "NOPASSWD|ALL.*ALL" /etc/sudoers /etc/sudoers.d/

PAM ile Zaman Tabanlı Erişim

/etc/security/time.conf ve PAM modülleri ile belirli saatler dışında sisteme girişi tamamen engelleyebilirsiniz. Bu sudo ile birleşince çok güçlü bir kombinasyon oluyor.

# /etc/security/time.conf dosyasını düzenle
# Format: servis;tty;kullanici;zaman
sudo nano /etc/security/time.conf

# Ahmet sadece mesai saatlerinde (09:00-18:00, Haftaiçi) sudo kullanabilsin
# Ama bu PAM seviyesinde SSH girişini kısıtlar, doğrudan sudo'yu değil

# /etc/pam.d/sshd veya /etc/pam.d/sudo içine ekleyin
account required pam_time.so

/etc/security/time.conf içine şunu ekleyin:

# sudo;*;ahmet;Wk0900-1800
# Anlamı: sudo servisi, tüm tty, ahmet kullanıcısı, Haftaiçi 09:00-18:00
sudo;*;ahmet;Wk0900-1800

Sonuç

Geçici ve sınırlı sudo yetkisi vermek, tek seferlik bir iş değil, bir süreç. Doğru araçları kullandığınızda hem güvenliği sağlıyorsunuz hem de ekibe yardım etmeyi geciktirmiyorsunuz.

Özetlemek gerekirse:

  • Her zaman visudo kullanın, asla doğrudan sudoers’ı düzenlemeyin
  • Yetkileri /etc/sudoers.d/ altında modüler tutun
  • Komutları olabildiğince spesifik tanımlayın, wildcard kullanırken dikkatli olun
  • NOEXEC direktifini, shell açabilecek programlar için ihmal etmeyin
  • Zaman sınırlaması için at veya cron ile otomatik temizlik yapın
  • Loglama mutlaka açık olsun, sudo I/O logları denetim için kritik
  • Yetki verme işlemini otomatize eden scriptler yazın, insan hatası kaçınılmaz

En güvenli sistem, gerektiğinde kolayca yetki verebildiğiniz ama bu yetkilerin otomatik olarak sona erdiği sistemdir. Bunu alışkanlık haline getirdiğinizde, yıllar sonra yapılan bir güvenlik denetiminde “Bu kişinin neden hâlâ sudo yetkisi var?” sorusunu duymak yerine, temiz ve denetlenebilir bir yetki geçmişi sunabilirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir