5 puan yazan GN⁺ 2025-08-20 | 1 yorum | WhatsApp'ta paylaş
  • systemd güçlü hizmet yönetimi özellikleri sunar, ancak varsayılan yapılandırma güvenlikten çok kullanılabilirliğe optimize edilmiştir; bu yüzden ayrıca hardening seçeneklerinin uygulanması gerekir
  • systemd-analyze security komutuyla tüm hizmetlerin veya belirli bir hizmetin güvenlik maruziyeti göstergeleri analiz edilip önceliklendirilebilir
  • Hizmet birimi düzeyinde uygulanabilecek çeşitli güvenlik seçenekleri vardır ve bunlar /etc/systemd/system/ServiceName.service.d/override.conf gibi dosyalar üzerinden ayrı ayrı değiştirilebilir
  • Başlıca seçenekler arasında ProtectSystem, PrivateTmp, NoNewPrivileges, SystemCallFilter, MemoryDenyWriteExecute gibi süreç yetkilerini ve kaynak erişimini sınırlayan öğeler bulunur
  • Kusursuz güvenliği hedeflemektense dışa açık hizmetleri öncelikli olarak güçlendirerek riski azaltmak mümkündür; self-hosting ortamlarında da bunun büyük etkisi görülebilir

systemd'ye genel bakış

  • systemd, hizmet yönetiminde çok olgun ve sağlam bir yaklaşım sunar
  • Ancak güvenlikten çok anında kullanılabilirliği öncelediği için varsayılan ayarları gevşektir
  • Bu belge, systemd hizmet birimlerine ve podman quadlet'e uygulanabilecek çeşitli güvenlik güçlendirme seçeneklerini tanıtarak ihlal olasılığını azaltmayı ve ihlal gerçekleştiğinde etki alanını en aza indirmeyi amaçlar
  • Bu, tüm hizmetlere topluca uygulanacak bir kılavuz değildir; her hizmetin özelliklerine ve gereken işlevlere göre ayrı ayrı deneme, günlük inceleme ve ayarlama gerekir
  • Altyapı güvenliğinin sorumluluğu tamamen işletmeciye aittir; bu belge yalnızca bir başvuru aracıdır

systemd güvenlik analizi

  • systemd-analyze security komutuyla tüm hizmetlerin güvenlik durumunu kontrol edebilir veya belirli bir hizmetin (ör. sshd.service) ayrıntılı ayarlarını analiz edebilirsiniz
    • Çıktıda kontrol durumu, özellik adı, açıklama ve Exposure puanı yer alır; Exposure ne kadar yüksekse risk de o kadar büyüktür
  • Güvenlik seçenekleri [Service] bölümüne (systemd) veya [Container] bölümüne (podman quadlet) ek ayar olarak eklenebilir
  • Override dosyası oluşturmak için systemctl edit ServiceName.service kullanılması önerilir; başarısız olursa gerekli izinler kontrol edilip ayarlanmalıdır

Hizmet güvenlik seçenekleri

  • systemd çeşitli güvenlik seçeneği anahtar sözcükleri sunar; bunlar man systemd.exec 5, man capabilities 7 gibi sayfalardan incelenebilir
  • Öne çıkan güvenlikle ilgili seçenekler
    • ProtectSystem → dosya sistemini salt okunur olarak sınırlayan seçenektir
    • ProtectHome/home, /root, /run/user erişimini engelleyen seçenektir
    • PrivateDevices → fiziksel aygıt erişimini engeller, yalnızca /dev/null gibi sanal aygıtlara izin verir
    • ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs → çekirdek kaynaklarına erişimi engelleyen seçeneklerdir
    • NoNewPrivileges → setuid/setgid vb. yoluyla yeni yetki kazanılmasını önleyen seçenektir
    • MemoryDenyWriteExecute → yazılabilir ve çalıştırılabilir belleğin aynı anda kullanılmasını engeller; bazı JIT dillerinde sorun çıkarabilir
    • SystemCallFilter → izin verilecek sistem çağrılarını sınırlayan seçenektir; ihlal durumunda süreç sonlandırılabilir veya EPERM döndürülebilir

Her seçeneğin açıklaması

  • ProtectSystem: strict ayarında tüm dosya sistemini salt okunur bağlar; /dev, /proc, /sys için ayrıca koruma seçenekleri gerekir
  • ReadWritePaths: yalnızca bazı yolları yeniden yazılabilir yapar
  • ProtectHome: /home, /root, /run/user erişimini engeller
  • PrivateDevices: fiziksel aygıt erişimini devre dışı bırakır, yalnızca /dev/null gibi pseudo aygıtlara izin verir
  • ProtectKernelTunables: /proc, /sys alanlarını salt okunur yapar
  • ProtectControlGroups: yalnızca cgroup'a salt okunur erişime izin verir
  • ProtectKernelModules: çekirdek modüllerinin açıkça yüklenmesini yasaklar
  • ProtectKernelLogs: çekirdek günlük tamponuna erişimi sınırlar
  • ProtectProc: invisible ayarında başka kullanıcıya ait süreçleri /proc/ altında gizler
  • ProcSubset: belirli PID ile ilgili öğeler dışındaki içerikleri /proc altında engeller
  • NoNewPrivileges: setuid, setgid, dosya sistemi capability'leri üzerinden yeni yetki yükseltmesini engeller
  • ProtectClock: sistem/donanım saatine yazmayı engeller
  • SystemCallArchitectures: native ayarında yalnızca x86-64 gibi yerel syscall'lara izin verir
  • RestrictNamespaces: konteynere özgü namespace'leri sınırlar
  • RestrictSUIDSGID: dosya setuid, setgid bitlerinin ayarlanmasını engeller
  • LockPersonality: yürütme alanının değiştirilmesini önler (yalnızca eski uygulamalarda gerekebilir)
  • RestrictRealtime: gerçek zamanlı zamanlamayı sınırlar (yalnızca bazı özel amaçlı hizmetlerde gerekir)
  • RestrictAddressFamilies: izin verilen soket adres ailelerini sınırlar (ör. AF_INET, AF_INET6, AF_UNIX vb.)
  • MemoryDenyWriteExecute: yazılabilir+çalıştırılabilir bellek alanlarının ek olarak oluşturulmasını engeller (JIT kullanan hizmetlerde dikkatli olunmalıdır)
  • ProtectHostname: sethostname, setdomainname syscall kullanımını yasaklar
  • SystemCallFilter: hizmet bazında syscall izin/verme ve engelleme ayarı yapar; ayrıntılı filtreleme mümkündür
    • Gruplar, tekil syscall'lar, izin/verme veya engelleme yöntemi gibi ayrıntılar ayarlanabilir
    • İhlal durumunda sonlandırmak yerine EPERM gibi hata kodu döndürme ayarı da desteklenir
    • Tüm liste systemd-analyze syscall-filter veya man systemd.exec(5) ile görülebilir
    • ~ önekiyle tüm liste tersine çevrilebilir (ör. CapabilityBoundingSet=~CAP_SETUID vb.)

SystemCallFilter kısıtlamalarını ayarlama süreci

  • auditd kullanılarak hizmet başarısız olduğunda hangi syscall'ın engellendiği günlüklerden görülebilir
    • sudo ausearch -i -m SECCOMP -ts recent çalıştırdıktan sonra syscall değerini kontrol edin
    • İlgili syscall veya ilişkili grubu SystemCallFilter'a ekleyerek sorun adım adım çözülebilir

Güçlendirme uygulama önceliği ve operasyon ipuçları

  • Her şeyi tüm hizmetlere uygulamak gerekli değildir
  • Tehdit modeli ve risk yönetimi esastır; özellikle dışa açık hizmetler (httpd, nginx, ssh vb.) mutlaka değerlendirilmelidir
  • Özel komutlar, timer unit'ler (eski cron yerine) gibi bileşenlerde de önleyici uygulama etkilidir
  • Hizmet ne kadar az karmaşıksa ince ayar yapma olasılığı da o kadar yüksektir

Kontrol listesi: önerilen güvenlik seçeneği kombinasyonu (ilk uygulama önceliği)

  • ProtectSystem=strict
  • PrivateTmp=yes
  • ProtectHome=yes veya ProtectHome=tmpfs
  • ProtectClock=yes, ProtectKernelLogs=yes, ProtectKernelModules=yes
  • RestrictSUIDGUID=yes
  • UMask=0077
  • LockPersonality=yes
  • RestrictRealtime=yes
  • MemoryDenyWriteExecute=yes
  • DynamicUser=yes veya User değerini root dışındaki belirli bir kullanıcı olarak ayarlama
  • Bu öğeler, genel olarak hizmetleri neredeyse hiç etkilemeden kullanılabilecek bir kombinasyondur
  • Ek olarak syscall filtreleme (SystemCallFilter) uygulamak istenirse ayrıntılı test gerekir

Traefik örnek yapılandırması

  • Konteyner tabanlı Traefik hizmetinin systemd quadlet ile çalıştırıldığı ve çok sayıda güvenlik seçeneğinin uygulandığı bir örnektir
    • ProtectSystem=full, ProtectHome=yes, SystemCallFilter=@system-service @mount @privileged vb. uygulanmıştır
    • CapabilityBoundingSet=~CAP_SETUID CAP_SETPCAP ile belirli yetkiler kaldırılmıştır
    • RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK vb. ile ağ erişim kısıtlamaları uygulanmıştır

Sonuç

  • systemd güvenlik güçlendirme seçenekleri, Unix benzeri sistem yöneticilerinin araç kutusunda bulunması gereken pratik araçlardan biridir
  • Bu seçenekler kusursuz bir güvenlik çözümü değil, riski azaltma aracı olarak kullanılmalıdır; tüm hizmetlere gelişigüzel güvenlik ayarı uygulamak gerekmez
  • Özellikle self-hosting ortamı yöneticileri için kullanıldığında güvenlik seviyesini artırmada büyük fayda sağlar
  • "Mükemmellikten çok pratiklik" yaklaşımıyla, işinize ve ortamınıza uygun ölçüde kısmen de olsa uygulanması önerilir

1 yorum

 
GN⁺ 2025-08-20
Hacker News görüşleri
  • strace profillemesiyle otomatikleştirilmiş systemd servis hardening uygulanabilmesi bana ilginç geldi
    https://github.com/desbma/shh

    • Benim bulduğum iyi bir yöntem var; örnekte ProtectSystem= kullanılmamış ama
      TemporaryFileSystem=/:ro, BindReadOnly=/usr/bin/binary /lib /lib64 /usr/lib usr/lib64 gibi bir yapı ile
      sadece istenen binary’yi ve okunması istenen yolları dahil edebilirsiniz
      ProtectSystem= şu anda bu davranışla uyumlu değil
      Daha fazla ayrıntı için buraya bakın

    • Bu yaklaşımın, hata oluştuğunda e-posta göndermek gibi ek davranışlara ihtiyaç duyan servislerde sorun yaratabileceğini düşünüyorum

  • Dün paylaşılan systemd hardening yazısına kıyasla bu çok daha gerçekçi ve hemen uygulanabilir iyi ipuçları içeriyor
    Dün o yazının yorumlarında daha pratik örnekler vermeye çalışmıştım; bugünkü yazı ise somut noktaları çok iyi toparlayıp systemd ile izolasyon ve güvenliği hızlı ve kolay biçimde güçlendirmenin yollarını anlatıyor
    Bence harika bir yazı
    Referans olması için dünkü yazıyı da bırakıyorum
    https://us.jlcarveth.dev/post/hardening-systemd.md
    https://news.ycombinator.com/item?id=44928504

    • Site sertifikası sorununu düzeltmeleri iyi olurdu
      Bazı tarayıcılarda sertifika hatası nedeniyle siteye hiç erişilemiyor
  • Paylaştığın için teşekkürler
    systemd-analyze aracını --user bayrağıyla kullanırsanız systemd kullanıcı unit’lerinin güvenliğini kontrol edebilirsiniz (systemd-analyze --user security)
    Container’ları Podman’a taşırken systemd’yi daha fazla kullanmaya başladım ve bu araç systemd unit/container servislerinin güvenliğini artırmada çok yardımcı olacak

  • Eski init script’lerinin hepsi birbirinden farklıydı; bu yüzden böyle tutarlı bir hardening çalışması mümkün değildi

    • Elbette eski init script’leriyle de böyle bir hardening yapmak mümkün, ama systemd çekirdeğin iyi özelliklerini standart ve tutarlı bir şekilde kolayca kullanmayı sağlıyor
      Ben Linux’a nispeten geç başladım; systemd’siz bir sistemi hayal etmek zor ve systemd olmayan sistemlerle uğraşmak çok rahatsız ediciydi
      Yakın zamanda unshare adlı aracı keşfettim; bununla /nix ağacının tamamını RW olarak yeniden mount etmek gibi deneyleri başka süreçleri etkilemeden yapabildim
      systemd’nin kullanılabilirliği biraz kaba olabilir ama dürüst olmak gerekirse benim için alternatif yalnızca Windows gibi geliyor
  • Linux dağıtımlarının neden bu tür güvenlik anahtarlarını varsayılan olarak daha fazla etkinleştirmediğini merak ediyorum
    Muhafazakâr biçimde hardening yapmanın dezavantajları mı var diye düşünüyorum
    Birçok kullanıcı için ayar sayısı fazla ve karmaşık olabilir

    • Ayarlar fazla agresif değiştirilirse mevcut yapılandırmalar istemeden bozulabilir
      Örneğin NetworkManager’ı harden ettiyseniz IPv4 ve IPv6 bağlantısının ikisinin de çalıştığını, dns=systemd-resolved ve dns=default modlarının düzgün işlediğini, ModemManager ve hücresel entegrasyonunu, openvpn veya cisco anyconnect eklentilerini, NetworkManager-dispatcher hook’larını tek tek doğrulamanız gerekir
      Ayrıca kaç dağıtım paketleyicisinin yönettiği paketteki anahtarları ne ölçüye kadar değiştirirse kullanıcı ortamlarının %0,01’inden fazlasını bozmayacağından emin olabileceği de ayrı bir sorun
      Dağıtım bu bayrakları yönetirse her upstream sürümünde ek uyumluluk sorunları gelir; tersine upstream ayarlarsa bu kez geriye dönük uyumluluk yüzünden daha da temkinli kullanmak zorunda kalır

    • Bu soru, “dağıtımlar neden varsayılan olarak MAC’i (SELinux vb.) daha sıkı kullanmıyor?” sorusuna benziyor
      sshd gibi şeyleri de daha kısıtlı yapmak iyi olurdu ama

      1. uygulama için başlangıç geliştirme maliyeti
      2. çeşitli kullanıcı ortamlarında ortaya çıkan bug report’ları ele alma maliyeti
      3. dağıtım/upstream değişikliklerine uyumlu sürekli bakım maliyeti
        gibi nedenlerle büyük dağıtımlar için bu ciddi bir yük
        SELinux ve AppArmor’da da bakımcılar çoğu zaman yatırım/getiri oranını düşük görüyor
    • Temel sistem servislerinin her parametre altındaki normal çalışmasını tek tek entegrasyon testine tabi tutacak kapasite veya kaynak olmaması da büyük bir neden
      İlgili tartışma
      https://news.ycombinator.com/item?id=29995566
      systemd-analyze security sonuçları dağıtıma göre değişiyor
      desbma/shh, strace ile toplanan içerikten SyscallFilter gibi unit bazlı kuralları otomatik üretiyor; bu yönüyle SELinux’un audit2allow aracına benziyor
      Ama production ortama strace kurmanın tartışmalı olabileceği de söylenebilir
      https://github.com/desbma/shh

    • Ben de tam bilmiyorum ama bazı ayarlar yeni eklenmiş olabilir ve pek çok kullanıcı bunlardan habersiz olabilir
      Herkes systemd uzmanı değil; ayrıca bir ayarı açmak eski systemd sürümlerinde düzgün çalışmama riski de taşıyabilir
      SELinux, AppArmor gibi çeşitli özellikler var ama birçok dağıtım, geliştirici ve kullanıcı bunları özellikle gerekli görmediği için otomatik uygulamak zor olabiliyor

  • Güvenliği güçlendirmeye yönelik seçenekler o kadar fazla ki, yaygın servisler için genel hardening örneklerini toplayan bir depo olsa iyi olurdu diye düşünüyorum
    Kullanıcılar ortak kullanılan hardening script’lerinden yararlansa da, pratikte istisna durumlarla karşılaşmamak için bazen yetkileri daha geniş vermek gerektiği ortaya çıkıyor

    • nixpkgs gibi upstream desteğinin zayıf olduğu dağıtımlarda paketleme yaparken, ana akım dağıtımların nasıl paketleyip hardening uyguladığına bakmak en faydalı yol
      Bu hardening yöntemleri genelde yeterince test edilmiş oluyor; postgresql gibi örnekleri merak ediyorsanız Debian, Ubuntu ve RHEL paketlerinden başlamak iyi bir fikir
  • systemd’nin sunduğu harika güvenlik özelliklerinden biri de credential yönetimi
    Bununla kimlik bilgilerini uygulamaya, ortam değişkenlerinde ya da dosya sisteminde tutmaktan daha güvenli şekilde aktarabilirsiniz
    Vault vb. olmayan ortamlarda, örneğin kişisel projelerde, ben her zaman bu yöntemi tercih ediyorum
    Hatta bu özellikle entegre olan bir Go paketi de kendim yaptım
    systemd’de credentials
    credential-go paketi

    • Bu, nodejs veya npm’de iki satırlık kodu bile paket yapma kültürüne benziyor diye düşünüyorum
      Aslında olan şey şu:

      dir, err := os.Getenv("CREDENTIALS_DIRECTORY")
      cred, err := os.ReadFile(filepath.Join(dir, "name"))
      

      left-pad’den bile daha karmaşık değil
      Bildiğim kadarıyla Go topluluğunda erdem sayılan şey bağımlılıkları azaltmak ve gereksiz soyutlamalardan (ör. fonksiyon çağrıları) kaçınmaktı
      Eskiden bu kadar basit işler genelde herkes tarafından o anda elle yazılırdı

    • Bu credential iletim yönteminin, fork edilmiş child process’lere kimlik bilgilerinin miras kalmasını nasıl engellediğini merak ediyorum

  • Gerçekten çok faydalı bir yazı
    systemd’nin her seçeneğini listelemesi ve “man sayfasına bakın, bol şans” tarzı tavsiyeler vermesi de hoşuma gitti
    systemd gerçekten çok iyi; bunu sunucularımda daha yaygın kullanmak istiyorum

  • Küçük bir not ama başlıkta systemd’nin doğru yazımı systemd şeklindedir
    SystemD, system D, system d değil, doğrusu systemd
    Sebebi de “system daemon” olması; Unix/Linux geleneğine uygun olarak adı küçük d ile bitiyor

    • İlginç bir bilgi
      Ben genelde systemD yazıldığını görüyordum; bunun neden bu kadar yaygınlaştığını merak ediyorum
  • systemd’de syscall sorunlarını debug etmeye dair ipucu gerçekten çok faydalı