Skip to content
Siber Vatan

Modern Servis Yönetimi ve systemd Mimarisi ​

Saide Beyza Bozyiğit @0beyz64

Umut Açıkgöz @umutackgoz

Bu yazıda Linux sistemlerde arka plan süreçlerinin nasıl yönetildiği, modern init mimarisi olan systemd'nin bileşenleri, birim (unit) dosyalarının hazırlanması, timer mekanizmaları ve üretim ortamında servis sıkılaştırma (hardening) pratikleri ele alınmaktadır.


Modern Servis Yönetimi Nedir? ​

Modern servis yönetimi; bir işletim sisteminde arka planda çalışan süreçlerin yaşam döngülerini merkezi, güvenli, izlenebilir ve yapılandırılabilir kurallarla kontrol etme yaklaşımıdır.

Temel kabiliyetleri şunlardır:

  • Bağımlılık ve Sıralama Yönetimi: Servisler arasındaki öncelik ve bağımlılık ilişkilerinin net biçimde tanımlanması.
  • Paralel Başlatma: Birbirine bağımlı olmayan servislerin eşzamanlı çalıştırılmasıyla sistem açılış süresinin kısaltılması.
  • Hata Kurtarma (Self-healing): Restart= direktifleri ile beklenmedik biçimde çöken süreçlerin otomatik olarak yeniden başlatılması.
  • Merkezi Süreç ve Kaynak Denetimi: Süreçlerin PID takibinden ziyade cgroups (Control Groups) üzerinden izlenmesi ve kaynak tüketimlerinin sınırlandırılması.
  • Tümleşik Loglama: Dağınık log dosyaları yerine journald ile yapılandırılmış ve merkezi log yönetimi.
  • Zamanlanmış Görevler: Harici araçlara (cron) ihtiyaç duymaksızın servislerle doğrudan entegre zamanlayıcılar (.timer).
  • Süreç İzolasyonu ve Sıkılaştırma: Çekirdek düzeyinde dosya sistemi kısıtlamaları, Linux yetenekleri (capabilities) ve namespace tabanlı güvenlik izolasyonu.

Neden Modern Yaklaşım? ​

Geleneksel SysVinit mekanizmaları ile systemd arasındaki farklar:

Özellik / KriterGeleneksel Sistem (SysVinit)Modern Sistem (systemd)
Başlatma YöntemiSıralı (Sequential) başlatmaParalel başlatma
Bağımlılık ÇözümüBetik düzeyinde manuel kontrolBildirimsel (Declarative) bağımlılık grafiği
Süreç TakibiPID dosyaları (kırılgan takip)cgroups tabanlı hiyerarşik süreç takibi
Log YönetimiDağınık metin dosyaları (/var/log/)Merkezi ve ikili formatlı systemd-journald
Sıkılaştırma / İzolasyonEkstra harici araçlar gerekirYerleşik çekirdek izolasyon direktifleri

systemd Nedir ve Nasıl Çalışır? ​

systemd, modern Linux dağıtımlarında önyükleme (boot) sonrasında çekirdek tarafından kullanıcı alanında (userspace) çalıştırılan ilk süreçtir (PID 1). Sistemdeki diğer tüm süreçlerin atası konumundadır.

Temel çalışma ilkeleri:

  • Sistem ve kullanıcı süreçlerinin başlatılmasını, durdurulmasını ve durum takibini yönetir.
  • Süreçleri cgroups altına alarak alt süreçlerin (child processes) arka planda yetkisiz şekilde kaçmasını önler.
  • Tanımlanan politikalara göre çöken servislerin yeniden ayağa kaldırılmasını sağlar.

Unit (Birim) Kavramı ​

systemd mimarisinde kontrol edilen her yapılandırılabilir kaynak bir Unit (Birim) olarak adlandırılır. Birimler uzantılarına göre ayrılır:

  • .service: Sistem servislerini ve arka plan süreçlerini yönetir.
  • .target: Sistem durumlarını ve servis gruplandırmalarını temsil eder.
  • .timer: Zamanlanmış görevleri yürütür.
  • .socket: IPC veya ağ soketlerini dinler; talep geldiğinde ilgili servisi dinamik başlatır (socket activation).
  • .mount / .automount: Dosya sistemi bağlama noktalarını denetler.

systemd Arka Plan Teknolojileri ​

  • D-Bus: Servislerin ve systemd bileşenlerinin IPC (Inter-Process Communication) mekanizması üzerinden birbirleriyle yapılandırılmış haberleşmesini sağlar.
  • cgroups (Control Groups): Süreçlerin CPU, bellek (RAM), disk I/O ve görev sayısı gibi donanım kaynaklarını sınırlandırır, önceliklendirir ve muhasebesini (accounting) tutar.
  • Linux Namespaces: Süreçlerin dosya sistemi, ağ ve süreç kimliklerini birbirinden yalıtarak servis bazlı sandbox sağlar.
  • Socket Activation: Bir servisin sürekli bellekte çalışması yerine, ilgili port veya soket dinlenir; ilk istek geldiğinde servis anında uyandırılır.

Başlatma ve Çalışma Mantığı ​

  1. Sistem genelindeki birim dosyaları (/etc/systemd/system/, /lib/systemd/system/) taranır.
  2. Servisler arasındaki ilişkilere göre bir bağımlılık ağacı (dependency graph) oluşturulur.
  3. Birbirini engellemeyen birimler eşzamanlı (paralel) olarak ayağa kaldırılır.
  4. Süreçler ait oldukları cgroups dilimleri (system.slice) içerisinde izlenir.

Siber Güvenlik Açısından Kritik Noktalar

  • Şüpheli Bağımlılıklar: Bir birim dosyasına sonradan eklenen şüpheli Requires= veya Wants= bağımlılıkları, saldırganların güvenlik araçlarını saf dışı bırakma veya zararlı kodları sistemle birlikte tetikleme taktikleri olabilir.
  • Açılışta Otomatik Çalışma (Persistence): Sistem başlangıcında etkinleştirilen (enabled) servisler, saldırganların kalıcılık sağlamak adına sıklıkla hedeflediği bileşenlerdir.

Runlevel ve Target Mimarisi ​

Geleneksel SysVinit mimarisindeki numaralandırılmış Runlevel mantığı, systemd ile yerini modüler Target birimlerine bırakmıştır. Target birimleri, birden fazla servisi belirli bir çalışma durumu altında gruplayan geçiş hedefleridir.

Runlevel (SysVinit)systemd Target KarşılığıAçıklama / Sistem Durumu
0poweroff.targetSistemin tamamen kapatılması.
1rescue.targetTek kullanıcılı kurtarma ve bakım modu.
2multi-user.targetÇok kullanıcılı, metin tabanlı (CLI) mod. (Debian tabanlı dağıtımlarda SysVinit döneminde varsayılan grafik seviyesi iken, systemd altında multi-user olarak eşlenir)
3multi-user.targetÇok kullanıcılı, ağ destekli, grafik arayüzsüz (CLI) standart çalışma modu.
4multi-user.targetÖzelleştirilebilir kullanıcı seviyesi (systemd'de standart olarak multi-user.target'a yönlendirilir).
5graphical.targetAğ destekli, masaüstü yöneticisinin ve grafik kullanıcı arayüzünün (GUI) çalıştığı mod.
6reboot.targetSistemin yeniden başlatılması.

systemd Servis Oluşturma (.service) ​

Bir uygulamanın veya betiğin systemd altında bağımsız bir servis olarak çalışması için şu adımlar izlenir:

  1. Servis tarafından yürütülecek betik/ikili dosya hazırlanır ve çalıştırma yetkisi (chmod +x) verilir.
  2. /etc/systemd/system/ dizininde .service uzantılı birim yapılandırma dosyası oluşturulur.
  3. Yapılandırma değişiklikleri systemd süreç yöneticisine tanıtılır (daemon-reload).
  4. Servis test amacıyla başlatılır (start) ve açılışta otomatik çalışması isteniyorsa etkinleştirilir (enable).

1. Çalışma Betiğinin Hazırlanması ​

Logların doğrudan dosyaya yazılması yerine standart çıktı (stdout / stderr) üzerinden üretilmesi, logların systemd-journald tarafından otomatik toplanmasını sağlar:

bash
#!/bin/bash
# /usr/local/bin/demo-task.sh

echo "==== Demo Görevi Başlatıldı: $(date) ===="
journalctl -n 5 --no-pager
echo "==== Demo Görevi Tamamlandı ===="

Betik çalıştırılabilir hale getirilir:

bash
sudo chmod +x /usr/local/bin/demo-task.sh

2. Unit Dosyası Bölümleri ​

Bir .service dosyası üç ana bölümden meydana gelir:

  • [Unit]: Servisin meta verilerini ve diğer birimlerle olan bağımlılık ilişkilerini tanımlar.
    • Description: Birimin açıklayıcı başlığı.
    • After: Yalnızca sıralama belirtir. Bu servisin, belirtilen birim(ler) çalıştırılmaya başlandıktan sonra devreye gireceğini söyler; kendi başına bir bağımlılık zorunluluğu kurmaz.
    • Wants: Zayıf bağımlılık oluşturur. İlgili birim başlatılmaya çalışılır; başaramasa dahi ana servisin çalışması engellenmez.
    • Requires: Güçlü bağımlılık oluşturur. Belirtilen birim başarıyla başlatılamazsa bu servis de devreye giremez.
  • [Service]: Sürecin nasıl yürütüleceğini belirler.
    • Type: Servis modelini tanımlar (simple, exec, oneshot, forking vb.).
    • User / Group: Sürecin çalıştırılacağı kullanıcı ve grup. Tanımlanmazsa varsayılan olarak root yetkileriyle çalışır.
    • ExecStart: Servis tetiklendiğinde yürütülecek mutlak dosya yolu ve parametreler.
    • Restart: Sürecin beklenmedik şekilde sonlanması durumunda devreye girecek kurtarma kuralı (no, always, on-failure).
    • RestartSec: Yeniden başlatma denemeleri arasındaki bekleme süresi.
  • [Install]: Servisin sistem başlangıcında hangi hedefe (.target) bağlanacağını belirler.
    • WantedBy: Servis etkinleştirildiğinde (enable), hedefin .wants dizinine bir sembolik bağ (symlink) eklenir (ör. multi-user.target).

3. Örnek Sürekli Servis Yapılandırması (/etc/systemd/system/demo.service) ​

Aşağıda standart bir arka plan servisi örneği yer almaktadır:

ini
[Unit]
Description=Demo Log İzleme Servisi
After=network.target

[Service]
Type=simple
User=kali
ExecStart=/usr/local/bin/demo-task.sh
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

4. Servis Yönetim Komutları ​

bash
# Yapılandırma dosyası değişikliklerini PID 1 yöneticisine tanıt
sudo systemctl daemon-reload

# Servisi anlık olarak başlat
sudo systemctl start demo.service

# Servisi durdur
sudo systemctl stop demo.service

# Sistem açılışında otomatik başlaması için sembolik bağ oluştur
sudo systemctl enable demo.service

# Hem etkinleştir hem de tek komutla hemen başlat
sudo systemctl enable --now demo.service

# Servis durumunu, cgroup sürecini ve son loglarını incele
sudo systemctl status demo.service

# Servise ait journald loglarını canlı takip et
journalctl -u demo.service -f

start ve enable Arasındaki Fark

  • systemctl start: Servisi o an çalışır duruma getirir; sistem yeniden başlatıldığında açılışta kendiliğinden ayağa kalkmasını sağlamaz.
  • systemctl enable: /etc/systemd/system/ altına ilgili hedefe yönelik sembolik bağ oluşturur; servisi o anda başlatmaz, yalnızca bir sonraki sistem açılışında çalıştırılmasını planlar. İkisini aynı anda yapmak için systemctl enable --now tercih edilir.

systemd Zamanlayıcıları (.timer) ​

systemd Timer birimleri; geleneksel cron aracına kıyasla daha ayrıntılı hata takibi, journald entegrasyonu, bağımlılık kontrolü ve mikro saniye düzeyinde tetikleme hassasiyeti sunar.

Timer birimleri kendi başlarına bir kod çalıştırmaz; aynı ada sahip .service birimini (veya Unit= direktifinde belirtilen servisi) tetikler.

Zamanlayıcı Tipleri ​

  1. Realtime Timers (Takvim Zamanlayıcıları): OnCalendar= ifadesiyle belirli gün, saat ve periyotlarda tetiklenir (örneğin Mon..Fri *-*-* 03:00:00).
  2. Monotonic Timers (Bağıl Süre Zamanlayıcıları): Sistem açılışı veya birimin son durumu gibi değişken olay başlangıçlarına göre süre sayar.

Başlıca Monotonic Parametreler ​

ParametreAnlamı ve Çalışma Mantığı
OnActiveSec=Zamanlayıcı biriminin kendisinin aktifleştiği andan itibaren geçen süreye göre tetikler.
OnBootSec=Sistemin çekirdek seviyesinde açıldığı (boot) andan itibaren geçen süreye göre tetikler.
OnStartupSec=systemd servis yöneticisinin (PID 1) ilk başlatıldığı andan itibaren geçen süreye göre tetikler.
OnUnitActiveSec=Tetiklenen servisin en son başlatıldığı (active duruma geçtiği) andan itibaren geçen süreye göre tetikler.
OnUnitInactiveSec=Tetiklenen servisin işini bitirip en son durduğu (inactive olduğu) andan itibaren geçen süreye göre tetikler.

Periyodik Görev Örneği (Timer ve Tek Seferlik Servis) ​

Bir görevi periyodik olarak timer ile yürütmek için, hedef servisin sürekli döngüde çalışması (Restart=always) değil, tek seferlik bir işlem yürütüp kapanması (Type=oneshot) gerekir.

1. Servis Dosyası (/etc/systemd/system/demo-task.service) ​

ini
[Unit]
Description=Tek Seferlik Demo Görevi

[Service]
Type=oneshot
User=kali
ExecStart=/usr/local/bin/demo-task.sh

2. Timer Dosyası (/etc/systemd/system/demo-task.timer) ​

Unit= belirtilmediğinde systemd, timer ile aynı dosya adına sahip demo-task.service birimini varsayılan olarak tetikler:

ini
[Unit]
Description=Demo Görevini Periyodik Çalıştırıcı

[Timer]
# Sistem açıldıktan 1 dakika sonra ilk tetiklemeyi yap
OnBootSec=1m
# Servisin son tamamlanmasından 10 saniye sonra tekrar tetikle
OnUnitInactiveSec=10s
# Zamanlama sapmalarını ve güç yönetimini optimize eden hassasiyet
AccuracySec=1ms

[Install]
WantedBy=timers.target

3. Timer Birimini Etkinleştirme ve İzleme ​

bash
# Yapılandırmayı yeniden yükle
sudo systemctl daemon-reload

# Timer birimini hemen başlat ve açılışa ekle
sudo systemctl enable --now demo-task.timer

# Sistemdeki tüm aktif timer birimlerini ve bir sonraki tetiklenme anlarını listele
systemctl list-timers

İpucu

AccuracySec=, sistemin CPU'yu uyandırma maliyetini optimize etmek adına timer tetiklenmelerini ne kadar esnetebileceğini belirler. 1ms hassasiyet sapmaları en aza indirirken, kritik olmayan görevlerde varsayılan 1m değeri sistem kaynaklarını korur.


Servis Güvenliği ve Sistem Sıkılaştırma (Hardening) ​

Birçok servis geliştirilirken root yetkileriyle veya kısıtlamasız çalıştırılır. Bu durum, serviste meydana gelebilecek bir güvenlik açığında (ör. RCE) saldırganın tüm işletim sistemini ele geçirmesine zemin hazırlar.

systemd; ek yazılımlara gerek kalmadan, Linux çekirdeğinin sunduğu Namespaces, cgroups, Seccomp ve Capabilities yeteneklerini birim dosyası üzerinden devreye alabilir.

Temel Güvenlik Parametreleri ​

  • User= / Group=: Servisin root yerine en az yetkili özel bir servis kullanıcısıyla çalışmasını sağlar.
  • CapabilityBoundingSet=: Servise tahsis edilebilecek Linux çekirdek yeteneklerini kısıtlar. Örneğin servis ham paket dinlemeyecek veya port açmayacaksa CAP_NET_RAW veya CAP_NET_BIND_SERVICE gibi yetenekler çıkarılır.
  • ProtectSystem=strict: Kök dosya sistemini (/) servis için tamamen salt okunur (read-only) yapar. Yalnızca ReadWritePaths= ile açıkça izin verilen dizinlere yazma hakkı tanır.
  • ProtectHome=yes: Kullanıcı dizinlerini (/home, /root, /run/user) servisin süreç alanından tamamen gizler ve boş bir sanal alan sunar.
  • PrivateTmp=yes: Sürece özel izole bir /tmp ve /var/tmp namespace'i atar; sistemdeki diğer süreçlerin geçici dosyalarına erişimi ve manipülasyonları önler.
  • PrivateDevices=yes: /dev altındaki fiziksel donanım aygıtlarına (diskler, bellek alanları) erişimi kısıtlayarak yalnızca /dev/null, /dev/zero gibi sanal aygıtları görünür kılar.
  • NoNewPrivileges=yes: Sürecin ve alt süreçlerinin setuid/setgid bitleri üzerinden yetki yükseltmesini kesin olarak engeller.
  • PrivateNetwork=yes: Servis için yalıtılmış bir ağ namespace'i oluşturur; harici ağ arayüzlerine erişimi engellerken yalnızca sanal bir loopback arabirimi sunar.
  • ProtectKernelModules=yes: Sürecin çekirdeğe modül yüklemesini veya kaldırmasını engeller.
  • ProtectKernelTunables=yes: /proc/sys, /sys gibi çekirdek parametrelerini barındıran dosya sistemlerine yazma erişimini kapatır.
  • MemoryMax= / CPUQuota=: Servisin tüketebileceği azami bellek miktarını ve işlemci payını sınırlayarak sistemin kilitlenmesini ve DoS riskini azaltır.

Sıkılaştırılmış Güvenli Servis Örneği ​

Aşağıdaki örnekte servis; ayrıcalıksız bir servis kullanıcısıyla (svc-demo) çalıştırılmış, dosya sistemi kilitlenmiş ve yalnızca ihtiyaç duyduğu log dizinine yazma hakkı verilmiştir:

ini
[Unit]
Description=Sıkılaştırılmış Güvenli Demo Servisi
After=network.target

[Service]
Type=simple
# Ayrıcalıksız servis kullanıcısı
User=svc-demo
Group=svc-demo
ExecStart=/usr/local/bin/demo-task.sh
Restart=on-failure
RestartSec=5s

# Yetki Yükseltme Koruması
NoNewPrivileges=yes

# Dosya Sistemi İzolasyonu
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes

# Yazma İzni Gereken Özel Dizinler
ReadWritePaths=/var/log/demo/

# Çekirdek ve Donanım Koruması
ProtectKernelModules=yes
ProtectKernelTunables=yes
CapabilityBoundingSet=

# Kaynak Tüketim Sınırları
MemoryMax=256M
CPUQuota=20%

[Install]
WantedBy=multi-user.target

ProtectSystem Değerleri Arasındaki Fark

  • ProtectSystem=true (veya yes): /usr ve /boot dizinlerini salt okunur yapar; /etc dizinine yazma izni devam eder.
  • ProtectSystem=full: /usr, /boot ve /etc dizinlerini salt okunur yapar.
  • ProtectSystem=strict: Tüm işletim sistemi dosya hiyerarşisini salt okunur bağlar. Sürecin yazması gereken alanlar (ör. loglar veya veritabanları) mutlaka ReadWritePaths= ile açıkça belirtilmelidir.

Güvenlik Analizi: systemd-analyze security ​

systemd, birim dosyasında yapılandırılan güvenlik parametrelerini denetleyen ve genel saldırı yüzeyini puanlayan yerleşik bir araca sahiptir:

bash
systemd-analyze security demo.service

Varsayılan (Sıkılaştırılmamış) vs. Sıkılaştırılmış Servis Karşılaştırması ​

Varsayılan bir servis dosyası analiz edildiğinde, çekirdek yetkilerinin ve dosya sistemi yollarının kısıtlanmadığı görülür:

text
→ Sıkılaştırılmamış Varsayılan Servis:
Overall exposure level for demo.service: 9.6 UNSAFE 🔴
✗ NoNewPrivileges=
✗ ProtectHome=
✗ ProtectSystem=
✗ CapabilityBoundingSet=

Yukarıdaki demo.service birimine sıkılaştırma direktifleri (NoNewPrivileges=yes, ProtectSystem=strict, CapabilityBoundingSet= vb.) eklendikten sonra analiz tekrar çalıştırıldığında risk skoru düşer:

text
→ Sıkılaştırılmış Servis:
Overall exposure level for demo.service: 1.8 OK 🟢
✔ NoNewPrivileges=
✔ ProtectHome=
✔ ProtectSystem=
✔ CapabilityBoundingSet=

Bu araç sayesinde üretim ortamına alınacak servislerin güvenlik duruşu nesnel olarak doğrulanabilir.


Kaynakça ​

Modern Servis Yönetimi ve systemd İçin Kaynakça