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ırKalı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.htmlb. 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.htmlBu, /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 8080Yukarı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 onBu 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ı:
- 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 0Uygulamayı tekrar test edin. Eğer sorun ortadan kalkıyorsa, SELinux bir erişimi engelliyordur.
audit.logDosyasını İncele:Tüm SELinux erişim ihlalleri
/var/log/audit/audit.logdosyasında kaydedilir.ausearchvesealertaraçları bu logları anlamayı kolaylaştırır.sudo tail -f /var/log/audit/audit.log | grep AVCveya 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ı) veperm(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=0Bu çıktı,
httpd_tdomain'indeki bir sürecin,default_tbağlamına sahipindex.htmldosyasınıreadyapma girişiminin engellendiğini gösterir.Daha kullanıcı dostu bir rapor için
sealertkullanın:sudo sealert -a /var/log/audit/audit.logBu, loglardaki SELinux ihlallerini analiz eder ve genellikle sorunu çözmek için önerilen
audit2allowveyasemanagekomutlarını sunar.- Sorunu Çözme:
Yukarıdaki senaryo için iki temel sorun olabilir:
- Dizin Bağlamı:
/data/web_appdizininin ve içeriğininhttpd_sys_content_tbağlamına sahip olması gerekir.
sudo semanage fcontext -a -t httpd_sys_content_t "/data/web_app(/.*)?"sudo restorecon -Rv /data/web_app/ - Dizin Bağlamı:
- Port Bağlamı: 8080 portunun
http_port_tolarak etiketlenmesi gerekir.
sudo semanage port -a -t http_port_t -p tcp 8080Bu değişikliklerden sonra SELinux'u tekrar enforcing moda alın ve uygulamayı test edin.
sudo setenforce 1Senaryo 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:
audit.logile İhlalleri Tespit Et:Uygulamayı çalıştırın ve
audit.log'u kontrol edin:sudo ausearch -c my_app.py -ts today -m AVC -iMuhtemelen
my_app_tdomain'inin (eğer tanımlıysa) veyaunconfined_tdomain'ininvar_log_tveya benzeri bir bağlama yazma girişimlerinin engellendiğini göreceksiniz.audit2allowile Özel Politika Modülü Oluşturma:audit2allowaracı,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_policyBu komut,
myapp_custom_policy.te(tip tanımlaması) vemyapp_custom_policy.if(arayüz) dosyalarını oluşturur..tedosyası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_tyerine uygulamanız için özel bir domain oluşturmanız gerekebilir. Ancak hızlı bir çözüm içinunconfined_tdomain'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 tekraraudit2allowile analiz edin. Bu kez,my_app_exec_tdomain'ininmy_app_log_ttipine erişim ihlallerini göreceksiniz.audit2allow -M myapp_policykomutu bu yeni bağlamlara göre bir politika oluşturacaktır.- Politika Modülünü Derle ve Yükle:
sudo semodule -i myapp_custom_policy.pp.ppdosyası (policy package), derlenmiş SELinux modülüdür. Bu komut, yeni politikayı sisteme yükler ve hemen etkili olmasını sağlar. - 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_tveya özel bir etiket). - Konteyner tarafından açılan portların ana sistemde doğru
port_tetiketine sahip olduğundan emin olun. - Docker'da volume bağlarken
:zveya:Zseçenekleri ile bağlam yönetimine dikkat edin.:z, paylaşılan volumeler için özel bir etiket ayarlar (çoklu konteyner erişimi),:Zise özel bir etiket ayarlar (tek konteyner erişimi).
docker run -v /host/path:/container/path:z myimageSonuç
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.