systemd-palvelujen kovettaminen Linuxissa 2026: systemd-analyze security, sandboxing ja seccomp käytännössä

Kovenna systemd-palvelu käytännössä: drop-in override, systemd-analyze security -pistemäärän tulkinta, ProtectSystem, seccomp-BPF ja capabilities. Sisältää nginx-esimerkin, jossa altistumispistemäärä putoaa 9.6:sta 2.1:een ilman että yksikään tavallinen käyttötapaus rikkoutuu.

Päivitetty: 20. elokuuta 2026

systemd-palvelun kovettaminen tarkoittaa yksikkötiedoston ympärille kirjoitettavaa hiekkalaatikkoa (sandbox), joka rajoittaa palvelun tiedostojärjestelmänäkyvyyttä, sallittuja järjestelmäkutsuja, verkkoperheitä ja kapasiteetteja pelkillä [Service]-osion direktiiveillä. Käytännössä kirjoitat drop-in override -tiedoston systemctl edit -komennolla, lisäät NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes ja SystemCallFilter=@system-service, ja mittaat tuloksen systemd-analyze security -komennolla. Tavoitteena on pudottaa altistumispistemäärä 9+:sta alle 3:n rikkomatta palvelua.

  • systemd-analyze security antaa jokaiselle yksikölle altistumispistemäärän 0.0–10.0 (matalampi on parempi) ja listaa jokaisen direktiivin, jota et vielä käytä. Käytä sitä työlistana.
  • Neljä korkeimman tuoton direktiiviä ovat NoNewPrivileges=yes, ProtectSystem=strict, PrivateTmp=yes ja tiukka CapabilityBoundingSet=. Nämä kattavat suurimman osan hyökkäyspinnasta.
  • Muokkaa aina drop-in override -tiedostoa polussa /etc/systemd/system/<name>.service.d/override.conf, älä koskaan jakelun toimittamaa unit-tiedostoa polussa /usr/lib/systemd/system, koska paketinpäivitys kirjoittaa sen yli.
  • SystemCallFilter=@system-service ottaa käyttöön seccomp-BPF-suodattimen, joka estää vaaralliset järjestelmäkutsut ytimen tasolla. Aseta SystemCallErrorNumber=EPERM debuggauksen ajaksi, jottei palvelu kuole SIGSYS-signaaliin.
  • Alle 3:n pistemäärä ei yksin riitä. Kovettaminen on yksi kerros syvyyssuojausta SELinuxin/AppArmorin, verkon segmentoinnin ja sovellustason turvallisuuden rinnalla.
  • Kernel 5.10+ ja systemd v247+ tukevat kaikkia tässä kuvattuja direktiivejä, mukaan lukien ProtectHostname=, ProtectClock= ja ProtectProc=invisible.

Miksi systemd-palvelut pitää kovettaa

Oletusasetuksin jokainen systemd-palvelu perii saman käyttöoikeuspinnan kuin käyttäjä, jonka nimissä se ajetaan. Palvelin, joka pyörii www-data-käyttäjällä, näkee koko juurihakemistorakenteen, voi luoda uusia prosesseja, ladata ytimen moduuleja jos CAP_SYS_MODULE on läsnä, ja avata mielivaltaisia verkkoyhteyksiä. Jos palveluun löytyy RCE-haavoittuvuus (vaikka logi4shell-tyyppinen deserialisaatiovirhe), hyökkääjä perii kaiken tämän. Tämä on nykyinen todellisuus useimmissa jakelupaketeissa: systemd-analyze security antaa tuoreelle jakelun palvelulle usein pistemäärän 9.0–9.8, ja koko iso taulukko on punaista.

systemd (versiosta v240 alkaen, ja vakaana v247:stä eteenpäin) tarjoaa yli 50 sandboxing-direktiiviä, jotka nojaavat suoraan ytimen ominaisuuksiin: mount-nimiavaruudet, seccomp-BPF, capabilities(7), PR_SET_NO_NEW_PRIVS ja Landlock LSM. Nämä eivät ole korkean tason abstraktioita, jotka on toteutettu käyttäjätilassa. Jokainen niistä kääntyy syscalliin, jonka ydin valvoo. Ero on olennainen: hyökkääjä, joka onnistuu ajamaan koodia palvelussa, ei voi kiertää SystemCallFilter=-suodatinta, koska rajoitus toimii ytimen puolella eikä palvelun omassa muistiavaruudessa.

Käytännössä yhden nginx-yksikön kovettaminen vie noin 15 minuuttia ja tuo puolen tunnin auditointityön hyötyihin verrattavan riskinvähennyksen. Kirjoitin itse ensimmäisen kovennetun drop-inin production-palvelimelle vuonna 2019 Debian 10:llä, ja saman mallin siirtäminen 2026:n Ubuntu 24.04 LTS -ympäristöön vaati vain kolmen direktiivin lisäämisen (ProtectClock=, ProtectHostname=, ProtectProc=). Vakaus on ollut poikkeuksellisen hyvä, ja rehellisesti, harva muu muutos antaa yhtä paljon vastinetta työtunnille.

systemd-analyze security: pistemäärän lukeminen

systemd-analyze security <palvelu> laskee jokaiselle direktiiville painotetun altistumisarvon ja summaa niistä kokonaispistemäärän välillä 0.0 (kovennettu) ja 10.0 (auki). Verdikti näytetään värillisenä: SAFE (0–3), MEDIUM (4–6), MEDIUM+ (6–7.5), EXPOSED (7.5–9) ja UNSAFE (9–10). Ajaminen ilman argumentteja tulostaa taulukon kaikista aktiivisista yksiköistä altistumisen mukaan järjestettynä. Se on hyödyllinen ensimmäinen inventaario:

sudo systemd-analyze security | sort -k 2 -n
sudo systemd-analyze security nginx.service
sudo systemd-analyze security --no-pager nginx.service | less -R

Yksittäisen yksikön tulos on pitkä taulukko: jokainen sandboxing-asetus, käytetäänkö sitä (✓/✗), sen paino ja lyhyt kuvaus. Alaosassa on kokonaispisteet ja sanallinen verdikti.

Lue taulukko ylhäältä alas, koska järjestys on painon mukainen. Ylimmät rivit tuovat suurimman parannuksen kun ne kytketään päälle.

Yksi tärkeä varoitus: pistemäärä on heuristiikka, joka arvioi ainoastaan systemd:n omia sandbox-direktiivejä. Se ei tarkasta SELinux-/AppArmor-profiileja, verkkoaltistumista, salaisuuksien hallintaa tai sovelluksen omia haavoittuvuuksia. Palvelu, jonka pistemäärä on 1.2 mutta joka pyörittää haavoittuvaa PHP-koodia rootin oikeuksilla, ei ole turvallinen. Käytä pistemäärää yhtenä syvyyssuojauksen mittarina, ei tikkeriboksina. Lisää taustaa löytyy SELinuxin ja AppArmorin pakollisen pääsynhallinnan käytännön oppaasta, joka täydentää tätä systemd-kerrosta.

Drop-in override -tiedoston luominen oikein

Älä koskaan muokkaa toimitettua yksikkötiedostoa polussa /usr/lib/systemd/system/<name>.service tai /lib/systemd/system/<name>.service. Paketin päivitys kirjoittaa sen hiljaisesti yli, ja kovennuksesi katoaa ilman varoitusta. Oikea työnkulku käyttää drop-in override -tiedostoa polussa /etc/systemd/system/<name>.service.d/, jonka systemd yhdistää alkuperäisen päälle latausvaiheessa.

Suositeltu tapa on käyttää systemctl edit -komentoa, joka luo hakemiston ja avaa oikean tiedoston oletusmuokkaimessa:

# Luo/muokkaa drop-in override -tiedostoa nginxille
sudo systemctl edit nginx.service

# Sisältö menee tiedostoon /etc/systemd/system/nginx.service.d/override.conf
# HUOM: aloita [Service]-osiolla, koska drop-in yhdistetään sen alle

# Vaihtoehtoisesti voit avata koko yksikön nähdäksesi lopullisen yhdistetyn version
sudo systemctl cat nginx.service

# Sovella muutokset ilman uudelleenkäynnistystä (jos direktiivit sen sallivat)
sudo systemctl daemon-reload
sudo systemctl restart nginx.service

systemctl cat näyttää lopullisen yhdistetyn yksikön kaikkine drop-ineineen. Käytä tätä, kun haluat varmistaa, että kovennus todella otettiin käyttöön. Debuggaukseen käytä systemd-delta --type=extended nginx.service, joka listaa kaikki drop-init hakemistosta järjestyksessä.

Tiedostojärjestelmän eristys: ProtectSystem, PrivateTmp ja ReadWritePaths

Tiedostojärjestelmädirektiivit ovat useimmiten helpoin voitto, koska niiden vaikutus on ennakoitava ja rikkoutuminen näkyy heti journalissa selkeänä "Permission denied" -viestinä. Suosittelen aina aloittamaan näistä ennen seccomp-suodatinta.

ProtectSystem=strict mounttaa koko juurihakemiston read-only-tilaan lukuun ottamatta /dev, /proc ja /sys -hakemistoja. Arvo full jättää /etc:n kirjoitettavaksi, yes vain /usr, /boot ja /efi. Lähes aina käytä strict:iä ja määrittele erikseen kirjoitettavat polut ReadWritePaths=-direktiivillä. Vastaavasti ProtectHome=yes piilottaa /home, /root ja /run/user. Palvelun ei kuulu koskaan nähdä niitä.

PrivateTmp=yes antaa palvelulle oman erillisen /tmp- ja /var/tmp-nimiavaruuden. Tämä poistaa kokonaisen haavoittuvuusluokan: symlinkkiralleja, TOCTOU-hyökkäyksiä ja tilapäistiedostojen ennustettavuuteen perustuvia hyökkäyksiä. Useimmat Red Hat -toimittamat yksiköt asettavat tämän oletuksena, mutta Debian- ja Ubuntu-paketit eivät aina.

[Service]
# Read-only-juuri lukuun ottamatta /dev, /proc, /sys
ProtectSystem=strict
# Piilota /home, /root, /run/user kokonaan
ProtectHome=yes
# Yksityinen /tmp ja /var/tmp
PrivateTmp=yes
# Sallittujen kirjoituspolkujen valkolista
ReadWritePaths=/var/log/nginx /var/cache/nginx /run/nginx
# Piilota täysin tietyt polut, vaikka ne olisivat luettavia
InaccessiblePaths=-/etc/letsencrypt /root
# Piilota muiden käyttäjien prosessit /proc:ssa (systemd v247+)
ProtectProc=invisible
ProcSubset=pid

ProtectProc=invisible yhdistettynä ProcSubset=pid:hen piilottaa muiden käyttäjien prosessit /proc-tiedostojärjestelmässä ja rajoittaa palvelun näkymän pelkkiin PID-hakemistoihin. Tämä katkaisee monta paikallista tiedustelupolkua. Esimerkiksi hyökkääjä ei voi lukea /proc/*/environ-tiedostoista muiden palveluiden ympäristömuuttujia, jotka usein sisältävät salasanoja ja API-avaimia. Tämä yksinään on syy ottaa direktiivit käyttöön useimmilla monikäyttäjäjärjestelmillä.

Ytimen suojaus ja oikeuksien pudotus

Toinen kerros koventamista rajoittaa palvelun kykyä vaikuttaa itse ytimeen tai eskaloitua rootiksi. Nämä direktiivit ovat lähes aina turvallisia, sillä palvelut, jotka oikeasti tarvitsevat ytimen moduuleja tai kernel-tunablejen kirjoitusoikeutta, ovat harvinaisia. Testaa jokainen erikseen tai lisää ne yhdessä ja rullaa taaksepäin, jos jotain hajoaa.

NoNewPrivileges=yes asettaa ytimen PR_SET_NO_NEW_PRIVS-lipun, joka estää palvelua ja kaikkia sen lapsiprosesseja saamasta lisää oikeuksia esimerkiksi setuid-binäärien, filesystem capabilities:n tai SELinux-käyttäjänvaihdon kautta. Tämä yksittäinen direktiivi katkaisee kokonaisen paikallisen oikeudennoston hyökkäysluokan. Se pidetään poissa vain silloin, kun palvelu tosiasiassa tarvitsee setuid-apuohjelmaa (kuten sudo, ping vanhoissa jakeluissa, tai PAM-pinoja). Käytännössä yli 95 % daemoneista ei tarvitse setuid-apuria, joten tämä on aina päällä oletuksena minun kovennuksissani.

[Service]
# Estä oikeudennosto setuid-binäärien tai fs-caps:n kautta
NoNewPrivileges=yes

# Ytimen suojaus
ProtectKernelModules=yes      # Estä modprobe/insmod/rmmod
ProtectKernelTunables=yes     # Read-only /proc/sys ja /sys
ProtectKernelLogs=yes         # Estä /proc/kmsg ja syslog(2)
ProtectClock=yes              # Estä settimeofday/adjtimex
ProtectHostname=yes           # UTS-nimiavaruus, ei voi vaihtaa hostnamea
ProtectControlGroups=yes      # Read-only /sys/fs/cgroup
LockPersonality=yes           # Estä personality(2)-syscall
MemoryDenyWriteExecute=yes    # Estä W|X-muistisivut (JIT-torjunta)
RestrictRealtime=yes          # Estä real-time-scheduling-luokat
RestrictSUIDSGID=yes          # Estä setuid/setgid-bittien asettaminen
RemoveIPC=yes                 # Siivoa SysV IPC exit-tilassa

# Capabilities: aloita tyhjästä ja lisää tarvittavat
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

# Verkkoperheiden rajaus
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
# Namespaces: mikään ei ole sallittu
RestrictNamespaces=yes

MemoryDenyWriteExecute=yes estää palvelua luomasta muistisivuja, joilla on samanaikaisesti kirjoitus- ja suoritusoikeus. Tämä pysäyttää suurimman osan klassisista shellcode-injektioista. Ainoat palvelut, jotka rikkoutuvat, ovat sellaiset, jotka käyttävät JIT-kääntäjää, esimerkiksi V8, LuaJIT tai .NET Core. nginxille, PostgreSQL:lle, sshd:lle ja useimmille daemoneille tämä on turvallinen.

CapabilityBoundingSet= on erityisen tärkeä silloin, kun palvelu tarvitsee jonkin verran root-oikeuksia mutta ei kaikkia. nginxille tarvitaan käytännössä vain CAP_NET_BIND_SERVICE (portin <1024 sitomiseen), joten pudota kaikki muut. Tarkka lista Linux-capabilities:sta löytyy capabilities(7)-man-sivulta. Jos et tiedä, mitä capabilities palvelu tarvitsee, aja se ilman rajoituksia ja katso getpcaps <pid>. Se listaa nykyiset caps:t, joita voi käyttää lähtökohtana.

SystemCallFilter ja seccomp-BPF käytännössä

SystemCallFilter= on kruunujalokivi ja usein myös rikkoutumisherkin direktiivi. Se kääntyy seccomp-BPF-ohjelmaksi, jonka ydin lataa palvelun prosessiin ennen execve-kutsua. Sen jälkeen mitkään kutsut, jotka eivät ole valkolistalla, eivät pääse ytimeen. Tulos on oletuksena SIGSYS-signaali ja välitön prosessin kuolema. Tämä on erittäin tehokas puolustus, mutta samalla ansa: yksi puuttuva syscall ja palvelu ei käynnisty.

Käytännöllinen lähestymistapa on aloittaa systemd:n valmiiksi kuratoidusta @system-service-ryhmästä, joka kattaa mitä tyypilliset daemonit tarvitsevat, ja sitten kieltää erikseen vaaralliset ryhmät kuten @privileged, @mount, @reboot ja @swap. Tildellä (~) alkava rivi kääntyy denylistiksi:

[Service]
# Salli baseline mitä useimmat daemonit tarvitsevat
SystemCallFilter=@system-service
# Kiellä vaaralliset ryhmät sen päälle (~ = deny)
SystemCallFilter=~@privileged @mount @reboot @swap @debug @cpu-emulation
# Palauta EPERM SIGSYS:n sijaan, helpompi debugata
SystemCallErrorNumber=EPERM
# Rajoita natiiviin arkkitehtuuriin (estä x32/i386 x86_64:llä)
SystemCallArchitectures=native

# Verkkoperheiden rajaus toimii käsi kädessä
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

Debuggausvaiheessa aseta aina SystemCallErrorNumber=EPERM. Tällöin estetty syscall palauttaa "Operation not permitted" -virheen sen sijaan, että ydin tappaisi prosessin. Voit silloin ajaa palvelua strace -f -c -p <pid> -komennolla ja nähdä, mitä syscallia se todella tarvitsee. Kun ratkaisu on löytynyt, poista SystemCallErrorNumber=-rivi tuotannossa, jotta SIGSYS toimii "fail closed" -tavalla.

Kaikki systemd:n @-ryhmien sisältö on dokumentoitu systemd.exec(5)-man-sivulla. Ryhmät päivittyvät hitaasti ja seuraavat ytimen syscall-tauluja. v255:ssä ryhmä @system-service sisälsi noin 320 syscallia, mikä on riittävä kaikille normaaleille verkkodaemoneille. Jos palvelu tekee jotain epätavallista (BPF-ohjelmien lataus, nimiavaruuksien luonti, iptablesin manipulointi), joudut lisäämään syscalleja käsin.

Käytännön esimerkki: nginx pistemäärästä 9.6 pistemäärään 2.1

Alla on täydellinen tuotantoympäristössä testattu drop-in override nginxille Ubuntu 24.04 LTS:llä. Ennen sovellusta systemd-analyze security nginx.service antaa pistemäärän 9.6 (UNSAFE). Sovelluksen jälkeen se putoaa 2.1:een (SAFE) rikkomatta yhtään tavallista käyttötapausta: TLS, HTTP/2, static-tiedostojen tarjoilu, PHP-FPM upstream, log rotation.

# /etc/systemd/system/nginx.service.d/override.conf
[Service]
# --- Tiedostojärjestelmä ---
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
ReadWritePaths=/var/log/nginx /var/cache/nginx /var/lib/nginx /run
InaccessiblePaths=-/etc/letsencrypt/archive

# --- /proc-eristys ---
ProtectProc=invisible
ProcSubset=pid

# --- Ytimen suojaus ---
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectClock=yes
ProtectHostname=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RemoveIPC=yes

# --- Capabilities ---
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_CHOWN CAP_DAC_OVERRIDE CAP_SETUID CAP_SETGID
AmbientCapabilities=
NoNewPrivileges=yes

# --- Verkko ---
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes

# --- Seccomp ---
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @mount @reboot @swap @debug @cpu-emulation @obsolete
SystemCallArchitectures=native

# --- Ajonaikainen ---
UMask=0027

Käytännön käyttö:

sudo systemctl edit nginx.service
# Liitä yllä oleva sisältö ja tallenna
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
sudo systemctl status nginx.service --no-pager
sudo systemd-analyze security nginx.service | tail -5

# Odotettu tulos:
# → Overall exposure level for nginx.service: 2.1 SAFE 😀

Master-prosessi tarvitsee CAP_NET_BIND_SERVICE:n portin 443/80 sitomiseen ja CAP_SETUID/CAP_SETGID/CAP_CHOWN/CAP_DAC_OVERRIDE:n workerin vaihtamiseen www-data-käyttäjäksi. Jos ajat nginxin rootless-tilassa portissa >1024, voit pudottaa kaikki muut paitsi mahdollisesti CAP_DAC_OVERRIDE:n. SSH-palvelimen vastaava kovennus on omassa oppaassaan: SSH:n kovettaminen Linuxissa 2026: Ed25519, FIDO2 ja post-kvanttisalaus.

Yleiset virheet ja miten välttää ne

Viiden vuoden aikana kovennettuani satoja yksiköitä olen nähnyt saman käsikirjoituksen toistuvan. Kolme yleisintä virhettä ovat: kaiken sisällyttäminen kerralla, väärän polun sallija-listaus ja seccomp-suodatin ilman EPERM-fallbackia.

1. Kaikki kerralla. Älä kopioi 25 direktiiviä ja käynnistä uudelleen. Systemd hyväksyy configin muttei ilmoita jokaisen direktiivin vaikutuksesta erikseen. Jos jokin rikkoo palvelun, saat vaikean bisektointityön. Sen sijaan lisää ryhminä: ensin tiedostojärjestelmä (ProtectSystem, ProtectHome, PrivateTmp), testaa; sitten ytimen suojaus, testaa; lopuksi seccomp, testaa erikseen. Törmäsin tähän itse ensimmäisellä kerralla ja käytin puolikkaan illan bisektoimaan yksittäistä direktiiviä.

2. Puuttuvat ReadWritePaths=-polut. Klassinen virhe: ProtectSystem=strict päälle, palvelu käynnistyy, mutta ensimmäisessä kirjoituksessa (esim. lokitus /var/log/foo/-hakemistoon) tulee "Read-only file system". Ratkaisu on lisätä polku ReadWritePaths=-listaan. Muista: myös PID-tiedostot, socket-tiedostot ja mahdolliset cache-hakemistot on lueteltava. Tarkista strace -e trace=openat,write -f -p <pid>, mihin palvelu oikeasti kirjoittaa.

3. seccomp SIGSYS:n aiheuttama välitön kuolema. Kun palvelu käynnistyy näennäisesti ja kuolee millisekunneissa ilman lokia, kyseessä on lähes aina seccomp-suodatin. Aseta SystemCallErrorNumber=EPERM väliaikaisesti, käynnistä uudelleen, katso journalctl -u <palvelu> -e. Nyt näet konkreettisen "Operation not permitted" -virheen ja voit paikallistaa syscallin. Vaihtoehtoisesti aja strace -f -c <binäärin polku> ja vertaa @system-service-ryhmän listaan.

4. DynamicUser=yes ilman StateDirectory=-määritystä. DynamicUser= on erinomainen direktiivi: se luo tilapäisen UID:n palvelun ajaksi eikä koskaan luo pysyvää käyttäjää. Mutta jos palvelu tarvitsee pysyvää tilaa, käytä StateDirectory=, jonka systemd luo automaattisesti ja jonka omistus siirtyy dynaamiselle käyttäjälle. Muuten palvelu ei voi kirjoittaa mihinkään pitkäaikaiseen sijaintiin.

Muista lopuksi: kovennus ei korvaa auditointia. Katso, mitä palvelusi todella tekee tunkeutumisen aikana. Linux auditd -sääntöjen ja ausearchin käytännön opas täydentää tätä kovennuskerrosta havaintokerroksella.

Usein kysytyt kysymykset

Mikä on hyvä systemd-analyze security -pistemäärä?

Alle 3.0 on tavoite kriittisille palveluille (SAFE), 4.0–6.0 on hyväksyttävä useimmille (MEDIUM). Oletuspaketit pisteytyvät tyypillisesti 8.0–9.5:een. Muista, että pistemäärä mittaa vain systemd:n sandboxing-direktiivien käyttöä. Se ei arvioi sovelluksen sisäisiä haavoittuvuuksia, SELinuxia tai verkkoaltistumista.

Mikä on ero ProtectSystem=strict ja full -asetuksilla?

strict mounttaa koko juuren read-only-tilaan lukuun ottamatta /dev, /proc ja /sys. full jättää /etc:n kirjoitettavaksi. yes on löyhin ja tekee vain /usr, /boot ja /efi read-onlyksi. Käytä lähes aina strict:iä ja luettele kirjoitettavat polut erikseen ReadWritePaths=-direktiivillä. Tämä on syvyyssuojauksen periaate.

Rikkooko MemoryDenyWriteExecute=yes JIT-kääntäjät?

Kyllä. Kaikki mikä käyttää RWX-muistisivuja rikkoutuu: V8 (Node.js), LuaJIT, .NET Core, Java (osittain), Firefox/Chrome. Perinteiset daemonit kuten nginx, PostgreSQL, Redis, sshd ja Apache toimivat moitteetta. Jos et ole varma, testaa staging-ympäristössä ja katso journalctl:sta "Cannot allocate memory" -virheitä käynnistyksen aikana.

Miten löydän mitkä capabilities palvelu tarvitsee?

Aja palvelu ilman CapabilityBoundingSet=-rajoitusta, hae PID:t systemctl status:lla, ja aja getpcaps <pid>. Se listaa nykyiset caps:t. Vaihtoehtoisesti käytä capsh --print-komentoa palvelun kontekstissa. Vielä tarkempi tapa on bpftrace-skripti, joka seuraa capable()-ytimen funktion kutsuja.

Voiko systemd-kovennus korvata SELinuxin tai AppArmorin?

Ei. Ne ovat toisiaan täydentäviä. systemd-direktiivit suojaavat palvelun ulkopuolelta ytimen kutsuja rajoittamalla, kun taas MAC-järjestelmät (SELinux, AppArmor) määrittelevät tarkkoja politiikkoja siitä, mihin resursseihin palvelu saa päästä. Käytä molempia: syvyyssuojaus tarkoittaa, että yhden kerroksen ohitus ei riitä murtoon.

Yuki Tanaka
Tietoa Kirjoittajasta Yuki Tanaka

Linux kernel security engineer with a background in eBPF and LSM. Likes hardening more than she likes sleeping.