Linux'ta SELinux Engellerini Güvenle Aşmak: Kendi Politikanızı Yazın!

SELinux (Security-Enhanced Linux), Linux çekirdeği (kernel) için geliştirilmiş, sistem güvenliğini en üst düzeye çıkarmayı hedefleyen bir güvenlik mimarisidir. Geleneksel erişim kontrol mekanizmalarının yetersiz kaldığı durumlarda, sistem süreçleri ve dosyalar üzerinde çok daha hassas bir denetim sağlar.



1. SELinux Nedir ve Neden Gereklidir?

Standart Linux sistemlerinde DAC (Discretionary Access Control - İsteğe Bağlı Erişim Kontrolü) kullanılır. Bu sistemde dosya izinleri (rwxrwxrwx) dosya sahibine bağlıdır. Eğer bir uygulama (örneğin bir web sunucusu) root yetkisiyle çalışıyorsa ve saldırgan bu uygulamayı ele geçirirse, tüm sisteme erişim sağlayabilir.

SELinux ise MAC (Mandatory Access Control - Zorunlu Erişim Kontrolü) modelini uygular. Bu modelde, bir sürecin (process) ne yapabileceği sadece kullanıcı yetkilerine değil, merkezi bir güvenlik politikasına bağlıdır. Bir web sunucusu root yetkisine sahip olsa bile, SELinux politikası izin vermediği sürece /home dizinine erişemez.


2. Temel Kavramlar

SELinux'u anlamak için üç temel kavramı bilmek gerekir:

A. Context (Bağlam)

Her dosya, süreç ve kullanıcı bir "etikete" sahiptir. Bu etikete SELinux Context denir. Formatı şöyledir:

user:role:type:level

  • Type (Tip): En önemli kısımdır. Süreçlerin ve dosyaların birbirleriyle etkileşime girip giremeyeceğini belirler. Örneğin, bir web sunucusu süreci httpd_t tipine, web dosyaları ise httpd_sys_content_t tipine sahiptir.

B. Policy (Politika)

Sistemdeki tüm kurallar kümesidir. "X tipi, Y tipine sahip dosyalara sadece okuma yetkisiyle erişebilir" gibi binlerce kural içerir.

C. Enforcement (Uygulama)

SELinux üç modda çalışabilir:

  1. Enforcing: Güvenlik politikaları sıkı bir şekilde uygulanır ve ihlaller engellenir.

  2. Permissive: İhlaller engellenmez ama "Audit" loglarına kaydedilir. Sorun giderme için kullanılır.

  3. Disabled: SELinux tamamen kapalıdır.


3. SELinux Nasıl Çalışır?

Bir süreç bir dosyaya erişmek istediğinde, Linux çekirdeği önce DAC (standart izinler) kontrolünü yapar. Eğer bu izin verilirse, SELinux devreye girer. SELinux, sürecin context'i ile dosyanın context'ini karşılaştırır ve Access Vector Cache (AVC) adı verilen önbelleğe bakarak erişime izin verip vermeyeceğine karar verir.


4. Temel SELinux Komutları

Sisteminizi yönetirken en sık kullanacağınız komutlar şunlardır:

  • Durum Sorgulama:

    Bash:
    sestatus
    
  • Mod Değiştirme (Anlık):

    Bash:
    setenforce 0  # Permissive mod
    setenforce 1  # Enforcing mod
    
  • Dosya Bağlamlarını Görme:

    Bash:
    ls -Z /var/www/html
    
  • Bağlamı Yeniden Düzenleme (Restore):

    Eğer bir dosyayı başka bir yerden taşıdıysanız ve etiketi yanlış kaldıysa:

    Bash
    restorecon -v /yol/dosya
    

5. Booleans: Politikaları Esnetmek

SELinux politikalarını tamamen kapatmak yerine, "Boolean" adı verilen anahtarlarla belirli izinleri açıp kapatabilirsiniz. Örneğin, web sunucusunun (Apache) ağ üzerinden veritabanına bağlanmasına izin vermek için:

Bash:
setsebool -P httpd_can_network_connect_db on

6. Log Analizi ve Sorun Giderme

SELinux bir erişimi engellediğinde bu durum /var/log/audit/audit.log (veya Debian/Ubuntu tabanlı sistemlerde /var/log/syslog) dosyasına kaydedilir. Bu loglar karmaşık olabilir, bu yüzden sealert aracı kullanılır:

Bash:
sealert -a /var/log/audit/audit.log

Bu komut, hatanın nedenini açıklar ve çözüm için size bir komut önerir.


Sonuç

SELinux, sistem yöneticileri için başlangıçta zorlayıcı bir öğrenme eğrisi sunsa da, modern siber güvenlik dünyasında vazgeçilmez bir kalkandır. Özellikle kamu kurumlarında ve yüksek güvenlik gerektiren sunucu altyapılarında (Pardus Server gibi yapılandırmalarda) aktif olarak kullanılması tavsiye edilir.


SELinux’un en güçlü ve esnek yanlarından biri olan "Politika Yazımı ve Booleans Yapılandırması" konusunu biraz daha teknik bir derinlikle ele alalım. Bir sistem yöneticisi veya geliştirici olarak, hazır kuralların dışına çıkmanız gerektiğinde bu adımlar hayat kurtarıcıdır.

SELinux Politika Yönetimi ve İnce Ayarlar

Varsayılan politikalar bazen özel yazdığınız bir betiği veya standart dışı bir dizini engelleyebilir. Bu durumda sistemi tamamen korumasız bırakmak yerine (yani SELinux'u kapatmak yerine) "iğne deliği" kadar bir izin açmak en güvenli yoldur.

1. SELinux Booleans (Mantıksal Anahtarlar)

Booleans, karmaşık politika kodları yazmadan, sistemdeki mevcut kuralları anında değiştirmenizi sağlar.

  • Tüm Boolean listesini görmek için:

    getsebool -a

  • Belirli bir servisle ilgili ayarları filtrelemek için:

    getsebool -a | grep httpd

  • Bir izni kalıcı olarak aktif etmek için:

    setsebool -P httpd_enable_homedirs on (Bu komut, Apache'nin kullanıcı ana dizinlerine erişmesine izin verir).


2. Özel Politika Modülü Oluşturma (Denial to Policy)

Eğer bir uygulama engelleniyorsa ve bunun için hazır bir Boolean yoksa, kendi politika modülünüzü oluşturabilirsiniz. Bu süreç genellikle 4 adımdan oluşur:

Adım 1: Engellemeyi Yakalayın

Sistemi geçici olarak Permissive moda alın ki uygulama çalışsın ve tüm engelleme logları oluşsun:

Bash:
setenforce 0

Adım 2: Logları Analiz Edin

audit.log içindeki karmaşık veriyi anlamlı bir politika taslağına dönüştüren audit2allow aracını kullanın:

Bash:
grep "denied" /var/log/audit/audit.log | audit2allow -m ozel_iznim > ozel_iznim.te

.te (Type Enforcement) dosyası, insan tarafından okunabilir kuralları içerir.

Adım 3: Politika Paketini Derleyin

Bu taslağı sistemin anlayacağı bir modül haline getirin:

Bash:
checkmodule -M -m -o ozel_iznim.mod ozel_iznim.te
semodule_package -o ozel_iznim.pp -m ozel_iznim.mod

Adım 4: Modülü Sisteme Yükleyin

Bash:
semodule -i ozel_iznim.pp
setenforce 1  # Sistemi tekrar koruma moduna alın

3. Dosya ve Port Etiketleme (Labeling)

SELinux bazen sadece dosyanın yanlış "etiketlenmiş" olması nedeniyle erişimi engeller.

  • Standart dışı bir portu (örneğin 8080) Web servisine tanıtmak:

    Normalde Apache sadece belirli portlarda çalışabilir. 8080'i eklemek için:

    Bash:
    semanage port -a -t http_port_t -p tcp 8080
    
  • Bir dizini kalıcı olarak etiketlemek:

    /data/web diye bir dizin açtınız ve Apache'nin burayı okumasını istiyorsunuz:

    Bash:
    semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
    restorecon -R -v /data/web
    

Pratik Bir Senaryo: Pardus Server ve Dosya Paylaşımı

Örneğin, Linux üzerinde bir Samba sunucusu kurdunuz. Kullanıcılar dosya yükleyemiyorsa, önce loglara bakılır:

type=AVC msg=audit(...): avc: denied { write } for pid=... comm="smbd" name="paylasim"

Burada yapılacak en doğru hareket, ilgili klasöre Samba'nın yazabileceği etiketi vermektir:

chcon -t samba_share_t /srv/samba/paylasim


Özet: Hangi Durumda Ne Yapılmalı?

SorunÇözüm Yolu
Standart bir servis özelliği çalışmıyorBoolean kontrol et.
Dosya/Dizin erişimi engelleniyorContext (Label) kontrol et veya restorecon kullan.
Servis standart dışı bir portta çalışacaksemanage port ile izin ekle.
Çok özel bir hata var ve hiçbir yere uymuyoraudit2allow ile özel modül yaz.

Diyelim ki; bir Python betiği yazdınız ve bu betik okul ağındaki bir sunucuya veri gönderiyor ya da özel bir dizine log yazıyor. Ancak SELinux bunu "şüpheli bir hareket" olarak görüp engelliyor.

İşte adım adım Debug ve Çözüm süreci:

1. Adım: Sorunun SELinux Kaynaklı Olduğunu Doğrulamak

Önce suçlunun gerçekten SELinux olup olmadığını anlamalıyız. Uygulamanız hata verdiğinde şu komutu çalıştırın:

Bash:
setenforce 0

Bu komutla SELinux'u Permissive (İzleme) moduna aldınız. Eğer uygulamanız şu an sorunsuz çalışıyorsa, sorun %100 SELinux politikalarıdır.

Not: Testten sonra setenforce 1 ile tekrar aktif etmeyi unutmayın.


2. Adım: Logları İzlemek (Canlı Takip)

Hatanın nedenini anlık olarak görmek için terminalde şu komutu açık bırakın ve uygulamanızı tekrar çalıştırın:

Bash:
tail -f /var/log/audit/audit.log | audit2why

audit2why, karmaşık log satırlarını okur ve size şunu söyler:

"Sizin Python betiğiniz (python_t), şu dosyaya (user_home_t) yazmaya çalıştı ama izin verilmedi. Şunu yaparsanız düzelebilir: ..."


3. Adım: Senaryo Üzerinden Çözüm (Python Backend Örneği)

Diyelim ki Python uygulamanız /var/www/html/data klasörüne bir SQLite veritabanı yazmak istiyor.

Hata Mesajı (AVC Denial):

type=AVC msg=audit(...): avc: denied { write } for pid=1234 comm="python3" name="data" dev="sda1" ino=5678 scontext=system_u:system_r:httpd_sys_script_t tcontext=unconfined_u:object_r:httpd_sys_content_t tclass=dir

Analiz:

  • scontext (Kaynak): httpd_sys_script_t (Betik modu)

  • tcontext (Hedef): httpd_sys_content_t (Sadece okunabilir içerik modu)

  • İşlem: write (Yazma engellendi)

Çözüm:

Hedef dizinin etiketini "yazılabilir" bir etiketle değiştirmeliyiz:

Bash:
semanage fcontext -a -t httpd_sys_script_rw_content_t "/var/www/html/data(/.*)?"
restorecon -R -v /var/www/html/data

4. Adım: Otomatik Politika Üretimi (Zor Durumlar İçin)

Eğer etiketleme veya Boolean ayarları sorunu çözmüyorsa (örneğin uygulamanız çok spesifik bir sistem çağrısı yapıyorsa), SELinux'a bu hareketi "öğretmemiz" gerekir.

  1. Hataları toplayın:

    ausearch -m avc -ts recent > hatalar.txt

  2. Çözüm önerisine bakın:

    audit2allow -a < hatalar.txt

  3. Politikayı uygulayın:

    audit2allow -a -M benim_ozel_modulum

    semodule -i benim_ozel_modulum.pp


Özet İpucu

Geliştirme aşamasında Pardus üzerinde SELinux ile boğuşmamak için en iyi pratik şudur:

  • Dosyalarınızı /home yerine sistemin beklediği standart dizinlerde tutun (/var/www, /opt vb.).

  • Dosya taşırken mv (move) yerine cp (copy) kullanmaya özen gösterin. mv komutu eski SELinux etiketini korur ve yeni yerinde hataya sebep olur; cp ise hedef dizinin etiketini otomatik alır.

Bu debug süreci, özellikle geliştirdiğiniz "Pardus Sınıf Asistanı" gibi sistem araçlarında, uygulamanızın güvenliğini zayıflatmadan çalışmasını sağlayacaktır.


"Pardus Sınıf Asistanı" veya benzeri bir Python/Tauri uygulamasının, sistem üzerinde kısıtlı bir kaynağa (örneğin USB aygıtlarını dinleme veya belirli bir sistem dosyasına erişme) ulaşmaya çalışırken engellendiğini varsayalım.

İşte bu durumu çözmek için özel bir SELinux politika modülü oluşturmanın en pratik yolu:

Senaryo: Uygulamanın Engellenmesi

Uygulamanız çalışıyor ancak log dosyasına baktığınızda Permission Denied alıyorsunuz ve sestatus komutu sistemin Enforcing modda olduğunu gösteriyor.

1. Adım: Hata Kaydını İzole Edin

Sistemdeki tüm karmaşık loglar arasından sadece uygulamanızla ilgili olanları çekmemiz gerekir. Uygulamanızın adının sinif-asistani olduğunu varsayalım:

Bash:
# Son 10 dakika içindeki SELinux engellemelerini çek
ausearch -m avc -ts recent | grep "sinif-asistani" > uygulama_hatalari.txt

2. Adım: Politika Taslağını İnceleyin

audit2allow aracı, bu hataları okuyarak "Eğer şu izni verirsen sorun çözülür" diyerek bize bir kural dosyası (.te - Type Enforcement) hazırlar.

Bash:
audit2allow -i uygulama_hatalari.txt -m sinif_asistani_politikasi > sinif_asistani_politikasi.te

Şimdi bu .te dosyasının içine cat ile bir bakalım. Şuna benzer bir içerik göreceksiniz:

Plaintext:
module sinif_asistani_politikasi 1.0;

require {
    type unconfined_t;
    type sysfs_t;
    class dir read;
}

#============= unconfined_t ==============
allow unconfined_t sysfs_t:dir read;

Bu çıktı şunu söyler: "unconfined_t" tipindeki uygulama, "sysfs_t" tipindeki klasörleri okuyabilsin.


3. Adım: Politikayı Derleyin ve Yükleyin

Bu metin dosyasını çekirdeğin (kernel) anlayacağı ikili (binary) formata dönüştürmemiz gerekiyor. Modern sistemlerde bunu tek komutla yapabiliriz:

Bash:
# Politika paketini oluştur ve sisteme yükle
audit2allow -d -M sinif_asistani_politikasi
semodule -i sinif_asistani_politikasi.pp

4. Adım: Kontrol

Modülün başarıyla yüklendiğini doğrulamak için:

Bash:
semodule -l | grep sinif_asistani

Artık uygulamanız, sadece sizin belirlediğiniz o özel izne sahip olacak ve sistemin geri kalanı hâlâ SELinux tarafından korunmaya devam edecektir.


Dikkat Edilmesi Gereken Önemli Nokta

Bu yöntem çok güçlüdür ancak **"en az yetki prensibi"**ne dikkat etmelisiniz. audit2allow bazen çok geniş izinler önerebilir. Eğer oluşturulan .te dosyasında capability dac_override (tüm dosya izinlerini bypass et) gibi çok kritik bir izin görüyorsanız, bu izni vermek yerine dosya etiketlerini (chcon veya semanage fcontext) değiştirmeyi tercih etmelisiniz.


SELinux engellemelerini analiz eden, kullanıcıya neyin engellendiğini gösteren ve onay verilirse otomatik olarak çözüm politikasını üreten bir Bash Script hazırlayalım.

SELinux Sorun Giderici (selinux_fixer.sh)

Bash:
#!/bin/bash

# Renk tanımlamaları
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # Renk yok

echo -e "${GREEN}=== Pardus SELinux Sorun Giderici ===${NC}"

# Root kontrolü
if [ "$EUID" -ne 0 ]; then 
  echo -e "${RED}Lütfen bu betiği sudo ile çalıştırın.${NC}"
  exit
fi

# Gerekli paketlerin kontrolü
for pkg in policycoreutils-python-utils audit; do
    if ! command -v $pkg &> /dev/null; then
        echo -e "${RED}$pkg paketi eksik. Kuruluyor...${NC}"
        apt update && apt install -y $pkg
    fi
done

echo "1) Son 10 dakika içindeki engellemeleri analiz et"
echo "2) Tüm audit loglarını tara"
echo "3) Çıkış"
read -p "Seçiminiz: " choice

case $choice in
    1) TIMESPAN="recent" ;;
    2) TIMESPAN="all" ;;
    *) exit ;;
esac

# Hataları geçici dosyaya yaz
echo -e "\n${GREEN}Hatalar analiz ediliyor...${NC}"
if [ "$TIMESPAN" == "recent" ]; then
    ausearch -m avc -ts recent > /tmp/selinux_errors.txt 2>/dev/null
else
    ausearch -m avc > /tmp/selinux_errors.txt 2>/dev/null
fi

if [ ! -s /tmp/selinux_errors.txt ]; then
    echo -e "${GREEN}Tebrikler! Herhangi bir SELinux engellemesi bulunamadı.${NC}"
    exit
fi

# Önerilen politikayı göster
echo -e "${RED}Engellenen işlemler bulundu:${NC}"
audit2allow -i /tmp/selinux_errors.txt

echo -e "\n---"
read -p "Bu izinler için özel bir politika modülü oluşturulsun mu? (y/n): " confirm

if [ "$confirm" == "y" ]; then
    read -p "Modül adı ne olsun? (ör: pardus_asistan): " modname
    
    # Modülü oluştur ve yükle
    audit2allow -a -M $modname < /tmp/selinux_errors.txt
    semodule -i ${modname}.pp
    
    echo -e "${GREEN}Başarılı! ${modname}.pp modülü sisteme yüklendi.${NC}"
    echo "Artık uygulamanızın bu işlemleri yapmasına izin veriliyor."
    
    # Temizlik
    rm ${modname}.te ${modname}.pp
else
    echo "İşlem iptal edildi."
fi

Bu Script Nasıl Kullanılır?

  1. Dosyayı oluşturun: nano selinux_fixer.sh komutuyla içeriği yapıştırın.

  2. Çalıştırma izni verin: chmod +x selinux_fixer.sh

  3. Çalıştırın: sudo ./selinux_fixer.sh

Scriptin Avantajları

  • Otomasyon: Karmaşık checkmodule ve semodule_package komutlarını senin yerine arka planda yapar.

  • Analiz: Önce hatayı gösterir, onayını almadan sisteme kural eklemez.

  • Uyumu: apt paket yöneticisi kontrolü ile bağımlılıkları otomatik çözer.

Yorumlar

Bu blogdaki popüler yayınlar

Android Telefon/Tablet Ekranını Pardus ETAP 23 Yüklü Akıllı Tahtaya Yansıtma

Pardus Etap 23’de Unutulmuş Etap Yetkili Parolasını Sıfırlama

Pardus Etap 23 Yazıcı Kurulumu