Skip to content
Bloga dön
Teknoloji Linux Sunucu Güvenliği SELinux Sistem Yönetimi DevOps

Linux Sunucu Güvenliğinde Mandatory Access Control (MAC) ve SELinux Pratikleri

Geleneksel DAC (Discretionary Access Control) modellerinin ötesine geçerek Linux sunucu güvenliğini SELinux ile nasıl sıkılaştırabileceğinizi, gerçek dünya senaryoları ve pratik konfigürasyon adımlarıyla inceleyin.

Caner Serbest

Sistem ve Altyapı

5 dk okuma

Linux Sunucu Güvenliğinde Mandatory Access Control (MAC) ve SELinux Pratikleri

Linux tabanlı sistemlerde güvenlik denildiğinde ilk akla gelen mekanizmalar genellikle dosya izinleri (chmod, chown) ve yetki yönetim araçlarıdır (sudo). Geleneksel olarak Unix benzeri işletim sistemleri, Discretionary Access Control (DAC - İsteğe Bağlı Erişim Kontrolü) modelini kullanır. Bu modelde bir dosyanın veya kaynağın sahibi, kimin erişebileceğini belirleme yetkisine sahiptir. Ancak günümüzün karmaşık ağ altyapılarında ve bulut ortamlarında, sadece DAC kullanmak kurumsal düzeydeki güvenlik ihtiyaçlarını karşılamakta yetersiz kalabilir.

Bir web sunucusunun (örneğin Nginx veya Apache) güvenlik açığı barındıran bir eklenti nedeniyle ele geçirildiğini hayal edin. Saldırgan, web sunucusunu çalıştıran kullanıcının (örneğin www-data veya nginx) yetkilerine sahip olur. Eğer bu kullanıcı /etc/passwd gibi kritik sistem dosyalarını okuyabiliyorsa veya sistemin diğer bölümlerine yanal hareket (lateral movement) yapabiliyorsa, potansiyel zarar katlanarak artar. İşte bu noktada Mandatory Access Control (MAC - Zorunlu Erişim Kontrolü) devreye girer. Bu yazıda, Linux ekosistemindeki en güçlü MAC implementasyonlarından biri olan SELinux’ün (Security-Enhanced Linux) temellerini, pratik yönetim komutlarını ve gerçek hayatta karşılaşabileceğiniz senaryolardaki kullanım biçimlerini ele alacağız.


DAC ve MAC Arasındaki Temel Farklar

DAC mekanizmasında erişim yetkileri tamamen nesnenin sahibine bağlıdır. Bir dosya oluşturduğunuzda, o dosyanın izinlerini değiştirebilir ve başka kullanıcıların erişimine açabilirsiniz. Süreç tamamen kullanıcı odaklıdır.

MAC ise merkezi bir politika (policy) tarafından yönetilir. Sistemdeki her kullanıcıya, sürece ve dosyaya birer güvenlik etiketi (context) atanır. Hiçbir kullanıcı veya süreç, sistem yöneticisi tarafından belirlenen merkezi politikanın dışına çıkamaz. Web sunucusu kök dizinine tam yetkili bir dosya koysanız dahi, SELinux politikası web sunucusunun o dosyayı okumasına izin vermiyorsa, işlem engellenir.

SELinux üç temel modda çalışır:

  1. Enforcing (Uygulama): Politikalar eksiksiz uygulanır ve ihlaller engellenir, ayrıca loglanır.
  2. Permissive (İzin Verici): İhlaller engellenmez, ancak loglanır. Genellikle hata ayıklama (troubleshooting) aşamasında kullanılır.
  3. Disabled (Devre Dışı): SELinux tamamen devre dışıdır.

Sunucunuzun mevcut SELinux durumunu kontrol etmek için aşağıdaki komutu kullanabilirsiniz:

sestatus

Çıktı genellikle şu şekildedir:

SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 33
Policy name: targeted

SELinux Bağlamlarını (Context) Anlamak

SELinux, her dosya, süreç ve porta etiketler (labels) atar. Bu etiketler üç ana bileşenden oluşur: Kullanıcı (User), Rol (Role) ve Tür (Type). Çoğu sistem yönetim senaryosunda odaklanacağımız temel kısım tür (type) etiketidir.

Sistemdeki dosyaların SELinux bağlamlarını görmek için -Z parametresini kullanabilirsiniz:

ls -lZ /var/www/html/

Örnek bir çıktı:

-rw-r--r--. root root httpd_sys_content_t:s0 index.html

Buradaki httpd_sys_content_t, bu dosyanın web sunucusu tarafından okunabilir olduğunu belirten SELinux türüdür. Eğer bu dosyayı /tmp dizininden taşıdıysanız ve etiketi güncellemediyseniz, web sunucunuz siteye giren kullanıcılara 403 Forbidden hatası verecektir. DAC izinleri (chmod 777) kusursuz görünse bile SELinux erişimi engeller.

Süreçlerin SELinux bağlamlarını görmek için ise ps komutuna -Z parametresi eklenir:

ps auxZ | grep nginx

Pratik Senaryo: Özel Bir Port Üzerinde Nginx Çalıştırmak

Varsayılan olarak Nginx veya Apache gibi web sunucuları standart portlarda (80, 443) çalışacak şekilde yapılandırılmıştır. Ancak güvenlik veya mimari gereksinimler nedeniyle web sunucusunu özel bir porta (örneğin 8080 yerine 8888) taşımak isteyebilirsiniz.

Eğer Nginx yapılandırma dosyasını değiştirip dinleme portunu 8888 yaparsanız ve SELinux etkin durumdaysa, Nginx servisi başlatılamayacaktır. Loglarda şu hatayı görürsünüz:

[emerg] 12345#0: bind() to 0.0.0.0:8888 failed (13: Permission denied)

DAC kurallarına göre portlar root yetkisi gerektirdiğinden bu hata mantıksız gelebilir. Ancak SELinux, Nginx sürecinin 8888 portunu dinlemesine izin vermemektedir.

Çözüm Adımları

Öncelikle sistemde hangi portların hangi SELinux etiketlerine sahip olduğunu listeleyelim:

semanage port -l | grep http_port_t

Bu komut, HTTP servislerinin kullanmasına izin verilen portları listeler. Yeni bir port eklemek veya mevcut olmayan bir portu web sunucusuna tanıtmak için semanage aracını kullanırız. (Eğer sisteminizde semanage komutu bulunmuyorsa, ilgili politika yönetim paketini yüklemeniz gerekir; örneğin Debian/Ubuntu tabanlı sistemlerde policycoreutils, RHEL/AlmaLinux tabanlı sistemlerde policycoreutils-python-utils).

Nginx’in 8888 portunu kullanabilmesi için SELinux port listesine ekleme yapalım:

semanage port -a -t http_port_t -p tcp 8888

Bu komuttan sonra Nginx servisini yeniden başlattığınızda, hata ortadan kalkacak ve servisin sorunsuz çalıştığını göreceksiniz. Eklediğiniz kuralı kaldırmak isterseniz -d parametresini kullanabilirsiniz:

semanage port -d -t http_port_t -p tcp 8888

Dosya ve Dizin Etiketlerini Yönetmek (restorecon ve chcon)

Web sitenizin dosya dizinini /var/www/html yerine özel bir dizine (örneğin /srv/www) taşımak istediğinizde SELinux engelleriyle karşılaşabilirsiniz. Dosyaları taşıdığınızda, kaynak dizindeki etiketler yeni dizine taşınmayabilir veya varsayılan sistem politikasıyla uyuşmayabilir.

Doğru etiketi kalıcı olarak uygulamak için semanage fcontext ve ardından restorecon komutları kullanılır. Örneğin, /srv/www/ altındaki tüm dosyaların web içeriği olarak etiketlenmesini sağlayalım:

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

Bu kuralı sisteme kaydettikten sonra, dosyalara gerçek etiketi uygulamak için restorecon komutunu çalıştırmalıyız:

restorecon -Rv /srv/www/

-R parametresi özyinelemeli (recursive) çalışmayı, -v parametresi ise yapılan değişiklikleri ekrana yazdırmayı sağlar. Bu yöntem, dosya izinlerinin ve SELinux bağlamlarının kalıcı ve doğru olmasını garanti eder.

Geçici veya hızlı testler için ise chcon komutu kullanılabilir:

chcon -t httpd_sys_content_t /srv/www/index.html

Ancak unutmayın ki chcon ile yapılan değişiklikler, dosya sistemi etiketleri yeniden oluşturulduğunda (restorecon çalıştırıldığında veya sistem yeniden etiketlendiğinde) kaybolabilir. Üretim ortamlarında her zaman semanage fcontext tercih edilmelidir.


SELinux Sorun Giderme (Troubleshooting) Süreci

Bir sistem yöneticisinin hayatında en sık karşılaşılan durumlardan biri, bir uygulamanın beklenmedik şekilde hata vermesi ve bunun SELinux kaynaklı olup olmadığını anlamaktır. Doğru hata ayıklama adımlarını izlemek, sorunu dakikalar içinde çözmenizi sağlar.

1. Audit Loglarını İnceleme

SELinux ihlalleri doğrudan kernel loglarına düşer. Bu logları incelemek için ausearch veya grep komutlarını kullanabilirsiniz:

grep AVC /var/log/audit/audit.log

Eğer sisteminizde setroubleshoot paketi kuruluysa, bu hatalar daha okunabilir insan dostu mesajlar halinde /var/log/messages dosyasına yazılır:

journalctl -t setroubleshoot

2. audit2why Kullanımı

Bir hata kodunun (AVC denial) neden kaynaklandığını anlamak için audit2why aracı oldukça faydalıdır:

ausearch -m avc -c "nginx" --ts recent | audit2why

Bu komut size hatanın nedenini ve olası çözüm yolunu açıkça söyler.

3. Geçici Çözüm ve Politika Üretimi

Eğer özel bir uygulama çalıştırıyorsanız ve standart politikalar bu uygulamayı engelliyorsa, kendi özel SELinux politikanızı üretebilirsiniz. Bunun için önce sistemi Permissive moda alıp uygulamanın tüm loglarını toplamasını sağlayabilirsiniz:

setenforce 0

Uygulama çalıştırıldıktan ve tüm işlemler test edildikten sonra toplanan loglardan özel bir politika dosyası oluşturulabilir:

grep myapp /var/log/audit/audit.log | audit2allow -M myapp_policy

Bu komut bir .pp (policy package) dosyası üretir. Bu politikayı sisteme yüklemek için:

semodule -i myapp_policy.pp

İşlem tamamlandıktan sonra SELinux modunu tekrar Enforcing moda almayı unutmayın:

setenforce 1

Sonuç

Mandatory Access Control (MAC) mekanizmaları ve özelinde SELinux, ilk bakışta karmaşık ve yönetilmesi zor yapı gibi görünebilir. Ancak sağladığı derinlemesine savunma (defense-in-depth) katmanı sayesinde, geleneksel DAC yetki aşımı açıklarının sistemin tamamına zarar vermesini engeller. Bir sunucu yöneticisi olarak SELinux’ü devre dışı bırakmak (“disable etmek”) yerine, onu Permissive modda test ederek doğru politikaları uygulamak, sisteminizin güvenlik duruşunu (security posture) üst seviyeye taşıyacaktır.


Bu yazı Gemini ile otomatik oluşturulmuştur.