SELinux Policy Yönetimi ve İleri Seviye Hata Ayıklama Teknikleri

 · 

SELinux Policy Yönetimi ve İleri Seviye Hata Ayıklama Teknikleri

SELinux Policy Yönetimi ve İleri Seviye Hata Ayıklama Teknikleri

Sunucu güvenliği denince akla gelen ilk katmanlardan biri olan SELinux (Security-Enhanced Linux), işletim sistemi üzerinde zorunlu erişim kontrolü (MAC) uygulayan güçlü bir Linux çekirdek güvenlik modülüdür. Geleneksel isteğe bağlı erişim kontrolü (DAC) mekanizmalarının ötesine geçerek, bir sürecin bir kaynağa (dosya, soket, port vb.) erişimini, kullanıcının veya sürecin yetkilerinden bağımsız olarak, önceden tanımlanmış güvenlik politikalarına göre sınırlar. Bu yazıda, SELinux politikalarının derinlemesine yönetimi ve karmaşık üretim ortamlarında karşılaşılan sorunların nasıl giderileceği üzerine odaklanacağız.

SELinux Mimarisi ve Temel Kavramlar

SELinux'un çalışma prensibi, her dosya, dizin, süreç ve port için güvenlik bağlamları (security contexts) atamasına dayanır. Bu bağlamlar, user:role:type:sensitivity formatında olup, en kritik bileşeni type (tip) veya domain'dir. Tip, bir dosyanın veya dizinin etiketini, domain ise bir sürecin etiketini tanımlar. Politikalar, belirli bir domain'in belirli bir tipe ne tür erişime sahip olabileceğini belirtir. SELinux üç ana modda çalışır:

  • Enforcing: Politikalar aktif olarak uygulanır ve erişim ihlalleri engellenir.
  • Permissive: Politikalar ihlalleri kaydeder ancak engellemez. Hata ayıklama için idealdir.
  • Disabled: SELinux tamamen kapalıdır. Güvenlik açısından tavsiye edilmez.

Geçerli durumu kontrol etmek için:

sestatus

Çıktı, SELinux durumunu, politikasını ve modunu gösterir. Modu değiştirmek için (geçici olarak Permissive'e almak genelde hata ayıklama adımının ilkidir):

sudo setenforce 0  # Permissive moda alırsudo setenforce 1  # Enforcing moda alır

Kalıcı değişiklikler için /etc/selinux/config dosyası düzenlenmelidir.

SELinux Politikalarını Yönetmek

Politika yönetimi, doğru güvenlik bağlamlarını atamak ve bu bağlamlar arasındaki izinleri ayarlamakla ilgilidir. Anahtar komutlar şunlardır:

1. Dosya Bağlamları (File Contexts)

Dosyaların ve dizinlerin güvenlik bağlamları, SELinux'un hangi uygulamaların hangi kaynaklara erişebileceğini belirlemesinde esastır. Varsayılan bağlamlar, politika içinde file_contexts dosyalarıyla tanımlanır.

a. Bağlamı Görüntüleme: ls -Z

Bir dosyanın veya dizinin mevcut SELinux bağlamını görmek için:

ls -Z /var/www/html/index.html# system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

b. Bağlamı Değiştirme: chcon (Geçici)

chcon komutu, bir dosyanın veya dizinin SELinux bağlamını geçici olarak değiştirir. Yeniden etiketleme (relabel) veya sistem yeniden başlatıldığında bu değişiklikler kaybolur.

sudo chcon -t httpd_sys_content_t /opt/mywebapp/index.html

Bu, /opt/mywebapp/index.html dosyasının tipini httpd_sys_content_t olarak ayarlar ve Apache'nin bu dosyaya erişimini sağlar.

c. Bağlamı Geri Yükleme: restorecon

Yanlışlıkla değiştirilen veya yeni oluşturulan dosyaların doğru varsayılan bağlamlarına geri döndürülmesi için kullanılır. Özellikle Recursive (-R) parametresi ile dizinler için sıkça kullanılır.

sudo restorecon -Rv /opt/mywebapp/

d. Varsayılan Bağlamları Tanımlama: semanage fcontext (Kalıcı)

Sistem genelinde kalıcı dosya bağlamları tanımlamak için semanage fcontext kullanılır. Bu, bir dizinin veya dosya yolunun her zaman belirli bir bağlama sahip olmasını sağlar.

sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"sudo restorecon -Rv /srv/www/

Bu örnek, /srv/www altındaki tüm dosyaları ve dizinleri httpd_sys_content_t tipiyle etiketler.

2. Port Bağlamları (Port Contexts)

Ağ portlarının SELinux bağlamları, süreçlerin hangi portları dinleyebileceğini veya onlara bağlanabileceğini kontrol eder.

sudo semanage port -l | grep http# http_port_t tcp 80, 443, 8008, 8009, 8443, 9000sudo semanage port -a -t http_port_t -p tcp 8080

Yukarıdaki komut, 8080 TCP portunu http_port_t olarak etiketler, böylece httpd domain'indeki bir süreç bu portu dinleyebilir.

3. Boole'lar (Booleans)

SELinux boole'ları, politika içindeki önceden tanımlanmış belirli davranışları etkinleştirmek veya devre dışı bırakmak için kullanılan anahtarlardır. Uygulamaların belirli senaryolarda nasıl davranacağını esnek bir şekilde kontrol etmeye olanak tanır.

getsebool -a | grep httpd_can_network# httpd_can_network_connect --> offsudo setsebool -P httpd_can_network_connect on

Bu komut, Apache'nin ağ bağlantıları yapmasına izin veren boolean'ı kalıcı olarak etkinleştirir.

Gerçek Dünya Senaryoları ve İleri Seviye Hata Ayıklama

SELinux, genellikle "her şeyi kırıyor" algısıyla karşılaşsa da, doğru hata ayıklama yöntemleriyle son derece yönetilebilir ve kritik bir güvenlik katmanı sağlar. Sorun giderme sürecinin kalbi, audit.log dosyası ve bu logları yorumlama araçlarıdır.

Senaryo 1: Web Sunucusu Özel Bir Dizin veya Porta Erişemiyor

Bir web uygulaması, varsayılan web kök dizini yerine /data/web_app dizininde barındırılıyor ve 8080 portunu kullanmaya çalışıyor. Uygulama başlatıldığında veya dizine erişildiğinde "Permission Denied" hataları alınıyor.

Hata Ayıklama Adımları:

  1. Modu Kontrol Et ve Geçici Olarak Değiştir:

    Eğer SELinux enforcing moddaysa, sorunun SELinux'tan kaynaklandığını doğrulamak için permissive moda alın.

    sudo setenforce 0

    Uygulamayı tekrar test edin. Eğer sorun ortadan kalkıyorsa, SELinux bir erişimi engelliyordur.

  2. audit.log Dosyasını İncele:

    Tüm SELinux erişim ihlalleri /var/log/audit/audit.log dosyasında kaydedilir. ausearch ve sealert araçları bu logları anlamayı kolaylaştırır.

    sudo tail -f /var/log/audit/audit.log | grep AVC

    veya spesifik bir hata için:

    sudo ausearch -c httpd -ts today -m AVC -i

    -c httpd: httpd süreciyle ilgili olayları filtreler.
    -ts today: Bugünkü olayları gösterir.
    -m AVC: SELinux erişim vektörü denetimlerini filtreler.
    -i: Sayıları okunabilir metne dönüştürür.

    Genellikle çıktıda scontext (kaynak bağlam), tcontext (hedef bağlam), tclass (hedef sınıfı) ve perm (izin) gibi bilgiler bulunur. Örneğin:

    type=AVC msg=audit(1678886400.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="index.html" dev="dm-0" ino=5678 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0

    Bu çıktı, httpd_t domain'indeki bir sürecin, default_t bağlamına sahip index.html dosyasını read yapma girişiminin engellendiğini gösterir.

    Daha kullanıcı dostu bir rapor için sealert kullanın:

    sudo sealert -a /var/log/audit/audit.log

    Bu, loglardaki SELinux ihlallerini analiz eder ve genellikle sorunu çözmek için önerilen audit2allow veya semanage komutlarını sunar.

  3. Sorunu Çözme:

    Yukarıdaki senaryo için iki temel sorun olabilir:

    • Dizin Bağlamı: /data/web_app dizininin ve içeriğinin httpd_sys_content_t bağlamına sahip olması gerekir.
    • sudo semanage fcontext -a -t httpd_sys_content_t "/data/web_app(/.*)?"sudo restorecon -Rv /data/web_app/
    • Port Bağlamı: 8080 portunun http_port_t olarak etiketlenmesi gerekir.
    • sudo semanage port -a -t http_port_t -p tcp 8080

    Bu değişikliklerden sonra SELinux'u tekrar enforcing moda alın ve uygulamayı test edin.

    sudo setenforce 1

Senaryo 2: Özel Bir Uygulama veya Script'in Çalıştırılması

Şirket içi geliştirilen bir Python uygulaması, /usr/local/bin/my_app.py konumunda çalışıyor ve belirli bir log dizinine /var/log/my_app/ yazmaya çalışıyor. SELinux enforcing moddayken uygulama, log dizinine yazma izni alamıyor.

Hata Ayıklama ve Özel Politika Oluşturma:

  1. audit.log ile İhlalleri Tespit Et:

    Uygulamayı çalıştırın ve audit.log'u kontrol edin:

    sudo ausearch -c my_app.py -ts today -m AVC -i

    Muhtemelen my_app_t domain'inin (eğer tanımlıysa) veya unconfined_t domain'inin var_log_t veya benzeri bir bağlama yazma girişimlerinin engellendiğini göreceksiniz.

  2. audit2allow ile Özel Politika Modülü Oluşturma:

    audit2allow aracı, audit.log'daki ihlalleri analiz ederek gerekli SELinux politika kurallarını otomatik olarak oluşturur. Bu, karmaşık senaryolarda hayat kurtarıcıdır.

    # İhlalleri bir dosyaya yönlendirsudo grep "my_app.py" /var/log/audit/audit.log | audit2allow -M myapp_custom_policy

    Bu komut, myapp_custom_policy.te (tip tanımlaması) ve myapp_custom_policy.if (arayüz) dosyalarını oluşturur. .te dosyasını inceleyerek nelerin izin verildiğini görebilirsiniz. Örneğin:

    # myapp_custom_policymodule myapp_custom_policy 1.0;require {    type var_log_t;    type unconfined_t;    class file { write create append };    # ... diğer izinler ...}# Allow unconfined_t to write, create, append files in var_log_tallow unconfined_t var_log_t:file { write create append };# ...

    Eğer uygulamanızın kendi domain'i yoksa, unconfined_t yerine uygulamanız için özel bir domain oluşturmanız gerekebilir. Ancak hızlı bir çözüm için unconfined_t domain'inin var_log_t'ye yazmasına izin vermek geçici bir çözüm olabilir. Daha iyi bir yaklaşım, uygulamanız için kendi tipini tanımlamaktır.

    Öncelikle uygulamanızın çalıştırılabilir dosyasına özel bir bağlam atayın:

    sudo semanage fcontext -a -t my_app_exec_t "/usr/local/bin/my_app.py"sudo restorecon -v /usr/local/bin/my_app.py

    Şimdi log dizinine de bir bağlam atayın:

    sudo semanage fcontext -a -t my_app_log_t "/var/log/my_app(/.*)?"sudo restorecon -Rv /var/log/my_app/

    Uygulamayı tekrar çalıştırın ve audit.log'u tekrar audit2allow ile analiz edin. Bu kez, my_app_exec_t domain'inin my_app_log_t tipine erişim ihlallerini göreceksiniz. audit2allow -M myapp_policy komutu bu yeni bağlamlara göre bir politika oluşturacaktır.

  3. Politika Modülünü Derle ve Yükle:
    sudo semodule -i myapp_custom_policy.pp

    .pp dosyası (policy package), derlenmiş SELinux modülüdür. Bu komut, yeni politikayı sisteme yükler ve hemen etkili olmasını sağlar.

  4. Test Et: Uygulamayı tekrar çalıştırın ve SELinux'u enforcing moda alın. Sorun çözülmüş olmalıdır.

Senaryo 3: Konteynerize Uygulamalar ve SELinux

Docker veya Kubernetes ortamlarında SELinux, konteynerler arasındaki izolasyonu artırmak için kullanılır. Varsayılan olarak, konteynerler container_t veya svirt_t bağlamları altında çalışır. Ancak özel bir konteyner imajı, ana sistemdeki bir dizine yazma veya özel bir port açma girişiminde bulunduğunda SELinux engelleriyle karşılaşabilir.

Hata Ayıklama Adımları:

Konteyner senaryolarında, ana sistemdeki audit.log yine kritik öneme sahiptir. Konteynerden gelen bir erişim ihlali, ana sistemdeki SELinux politikaları tarafından yakalanır. Hata ayıklama süreci Senaryo 1 ve 2'ye benzerdir: audit.log'u incele, ihlal eden bağlamları ve izinleri belirle, ardından semanage komutlarıyla (fcontext, port) veya audit2allow ile özel bir politika modülü oluşturarak çözüm üret.

Özellikle dikkat edilmesi gerekenler:

  • Konteynerin bağlandığı host dizinlerine doğru SELinux etiketlerinin verildiğinden emin olun (örneğin, container_file_t veya özel bir etiket).
  • Konteyner tarafından açılan portların ana sistemde doğru port_t etiketine sahip olduğundan emin olun.
  • Docker'da volume bağlarken :z veya :Z seçenekleri ile bağlam yönetimine dikkat edin. :z, paylaşılan volumeler için özel bir etiket ayarlar (çoklu konteyner erişimi), :Z ise özel bir etiket ayarlar (tek konteyner erişimi).
  • docker run -v /host/path:/container/path:z myimage

Sonuç

SELinux, karmaşık ancak doğru anlaşıldığında ve yönetildiğinde Linux sistemlerinin güvenlik postürünü önemli ölçüde artıran vazgeçilmez bir araçtır. Politikaları yönetmek ve sorunları gidermek başlangıçta zorlayıcı görünse de, sestatus, semanage, restorecon, audit.log, ausearch ve audit2allow gibi araçlarla donanmış bir sistem yöneticisi, karşılaşılan hemen her SELinux kaynaklı sorunu çözebilir. Üretim ortamlarında bu derinlemesine anlayış, sadece sorun gidermeyi hızlandırmakla kalmaz, aynı zamanda güvenlik mimarilerini daha sağlam hale getirir.

← Blog Listesine Dön