SystemD Hizmet Güçlendirmesi (Hardening)
(roguesecurity.dev)- 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 securitykomutuyla 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.confgibi dosyalar üzerinden ayrı ayrı değiştirilebilir - Başlıca seçenekler arasında
ProtectSystem,PrivateTmp,NoNewPrivileges,SystemCallFilter,MemoryDenyWriteExecutegibi 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 securitykomutuyla 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.servicekullanı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 7gibi sayfalardan incelenebilir - Öne çıkan güvenlikle ilgili seçenekler
ProtectSystem→ dosya sistemini salt okunur olarak sınırlayan seçenektirProtectHome→/home,/root,/run/usererişimini engelleyen seçenektirPrivateDevices→ fiziksel aygıt erişimini engeller, yalnızca/dev/nullgibi sanal aygıtlara izin verirProtectKernelTunables,ProtectKernelModules,ProtectKernelLogs→ çekirdek kaynaklarına erişimi engelleyen seçeneklerdirNoNewPrivileges→ setuid/setgid vb. yoluyla yeni yetki kazanılmasını önleyen seçenektirMemoryDenyWriteExecute→ yazılabilir ve çalıştırılabilir belleğin aynı anda kullanılmasını engeller; bazı JIT dillerinde sorun çıkarabilirSystemCallFilter→ 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:
strictayarında tüm dosya sistemini salt okunur bağlar;/dev,/proc,/sysiçin ayrıca koruma seçenekleri gerekir - ReadWritePaths: yalnızca bazı yolları yeniden yazılabilir yapar
- ProtectHome:
/home,/root,/run/usererişimini engeller - PrivateDevices: fiziksel aygıt erişimini devre dışı bırakır, yalnızca
/dev/nullgibi pseudo aygıtlara izin verir - ProtectKernelTunables:
/proc,/sysalanları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:
invisibleayarında başka kullanıcıya ait süreçleri/proc/altında gizler - ProcSubset: belirli PID ile ilgili öğeler dışındaki içerikleri
/procaltında engeller - NoNewPrivileges: setuid, setgid, dosya sistemi capability'leri üzerinden yeni yetki yükseltmesini engeller
- ProtectClock: sistem/donanım saatine yazmayı engeller
- SystemCallArchitectures:
nativeayarı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,setdomainnamesyscall 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-filterveyaman systemd.exec(5)ile görülebilir ~önekiyle tüm liste tersine çevrilebilir (ör.CapabilityBoundingSet=~CAP_SETUIDvb.)
SystemCallFilter kısıtlamalarını ayarlama süreci
auditdkullanılarak hizmet başarısız olduğunda hangi syscall'ın engellendiği günlüklerden görülebilirsudo 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=strictPrivateTmp=yesProtectHome=yesveyaProtectHome=tmpfsProtectClock=yes,ProtectKernelLogs=yes,ProtectKernelModules=yesRestrictSUIDGUID=yesUMask=0077LockPersonality=yesRestrictRealtime=yesMemoryDenyWriteExecute=yesDynamicUser=yesveyaUserdeğ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 @privilegedvb. uygulanmıştırCapabilityBoundingSet=~CAP_SETUID CAP_SETPCAPile belirli yetkiler kaldırılmıştırRestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINKvb. 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
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ış amaTemporaryFileSystem=/:ro, BindReadOnly=/usr/bin/binary /lib /lib64 /usr/lib usr/lib64gibi bir yapı ilesadece istenen binary’yi ve okunması istenen yolları dahil edebilirsiniz
ProtectSystem=şu anda bu davranışla uyumlu değilDaha 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
Bazı tarayıcılarda sertifika hatası nedeniyle siteye hiç erişilemiyor
Paylaştığın için teşekkürler
systemd-analyzearacını--userbayrağı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
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
unshareadlı aracı keşfettim; bununla/nixağacının tamamını RW olarak yeniden mount etmek gibi deneyleri başka süreçleri etkilemeden yapabildimsystemd’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-resolvedvedns=defaultmodları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 gerekirAyrı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
sshdgibi şeyleri de daha kısıtlı yapmak iyi olurdu amagibi 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 securitysonuçları dağıtıma göre değişiyordesbma/shh, strace ile toplanan içeriktenSyscallFiltergibi unit bazlı kuralları otomatik üretiyor; bu yönüyle SELinux’unaudit2allowaracına benziyorAma 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
nixpkgsgibi 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ı yolBu 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:
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şeklindedirSystemD,system D,system ddeğil, doğrususystemdSebebi de “system daemon” olması; Unix/Linux geleneğine uygun olarak adı küçük
dile bitiyorBen genelde
systemDyazıldığını görüyordum; bunun neden bu kadar yaygınlaştığını merak ediyorumsystemd’de syscall sorunlarını debug etmeye dair ipucu gerçekten çok faydalı