Cum auditezi și securizezi un serviciu Linux folosind systemd-analyze

Configurare noua (How To)

Situatie

systemd-analyze are două comenzi foarte utile pentru securizarea unui serviciu:

  • verify verifică sintaxa și problemele de configurare ale unității.
  • security analizează mecanismele de sandboxing și calculează un nivel de expunere. O valoare mai mică înseamnă, în general, mai puține privilegii și o izolare mai strictă.

Vom folosi serviciul fictiv myapp.service. Înlocuiește numele cu serviciul pe care vrei să îl verifici.

1. Verifică serviciul

Începe cu:

systemctl status myapp.service

Vezi configurația efectivă:

systemctl cat myapp.service

Și verifică proprietățile importante:

systemctl show myapp.service \
  -p User \
  -p Group \
  -p ExecStart \
  -p AmbientCapabilities \
  -p CapabilityBoundingSet \
  -p NoNewPrivileges

Scopul este să afli cu ce utilizator rulează serviciul, ce executabil pornește și ce privilegii primește.

2. Rulează auditul de securitate

systemd-analyze security --no-pager myapp.service

Vei primi o listă cu verificări de tipul:

NAME                         DESCRIPTION                         EXPOSURE
✗ User=/DynamicUser=         Service runs as root user            ...
✗ PrivateTmp=                Service has access to /tmp           ...
✓ ProtectSystem=             Service has limited filesystem       ...
...

La final apare nivelul general de expunere. Acest scor trebuie folosit ca instrument de audit, nu ca verdict absolut. systemd verifică mecanismele sale de izolare, nu securitatea internă a aplicației.

3. Verifică fișierul unității înainte de modificări

systemd-analyze verify /etc/systemd/system/myapp.service

Comanda poate identifica directive necunoscute, probleme de sintaxă și alte erori de configurare. Pentru unitățile existente, poți verifica și configurația instalată de distribuție:

systemd-analyze verify myapp.service

4. Rulează serviciul cu un utilizator dedicat

Un serviciu care nu are nevoie de privilegii administrative nu ar trebui să ruleze ca root.

Exemplu:

[Service]
User=myapp
Group=myapp

Verifică mai întâi că utilizatorul există:

id myapp

Separarea utilizatorului este una dintre primele măsuri de reducere a impactului unei eventuale compromiteri.

5. Activează NoNewPrivileges

Adaugă:

[Service]
NoNewPrivileges=yes

Această opțiune împiedică procesul și procesele sale copil să obțină privilegii suplimentare prin mecanisme precum setuid, setgid sau file capabilities. La nivel de kernel, flag-ul devine permanent pentru procesele care îl moștenesc.

6. Izolează filesystem-ul

O configurație uzuală pentru un serviciu care nu trebuie să modifice sistemul este:

[Service]
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes

ProtectSystem=strict face ierarhia filesystem-ului în principal read-only pentru serviciu. ProtectHome ascunde sau restricționează accesul la directoarele utilizatorilor. PrivateTmp oferă serviciului un spațiu separat pentru /tmp și /var/tmp.

Dacă aplicația trebuie să scrie într-un director precis, nu transforma întregul filesystem în writable. Permite doar acea zonă:

[Service]
ProtectSystem=strict
ReadWritePaths=/var/lib/myapp

7. Restricționează accesul la dispozitive

Pentru un serviciu obișnuit care nu are nevoie de dispozitive hardware:

[Service]
PrivateDevices=yes

Acest lucru reduce accesul procesului la dispozitivele sistemului.

8. Protejează interfața kernelului

Pentru servicii normale:

[Service]
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes

Ideea este ca procesul să nu poată modifica facilități ale kernelului sau configurația control groups de care nu are nevoie. Documentația systemd recomandă folosirea acestor mecanisme de sandboxing atunci când compatibilitatea aplicației permite acest lucru.

9. Limitează rețeaua

Dacă aplicația folosește numai conexiuni TCP/IP obișnuite și socketuri Unix:

[Service]
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

Astfel limitezi familiile de adrese pe care procesul le poate folosi prin socket. Nu aplica această regulă unui serviciu înainte să verifici ce tipuri de socket folosește.

10. Limitează capabilities

Verifică mai întâi ce capabilities sunt necesare:

systemctl show myapp.service -p CapabilityBoundingSet

Dacă aplicația nu are nevoie de capabilities, acestea pot fi eliminate:

[Service]
CapabilityBoundingSet=
AmbientCapabilities=

Capability bounding set limitează capabilities care pot fi moștenite de procesele executate ulterior. Nu elimina capabilities necesare pentru operația normală a serviciului.

11. Aplică modificările printr-un drop-in

Pentru un serviciu instalat de distribuție, evită modificarea directă a fișierului original.

Folosește:

sudo systemctl edit myapp.service

Poți introduce, de exemplu:

[Service]
User=myapp
Group=myapp

NoNewPrivileges=yes

ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes

PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes

RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

Acesta este un punct de pornire. Nu toate serviciile acceptă toate restricțiile.

12. Reîncarcă systemd

sudo systemctl daemon-reload

Apoi verifică din nou unitatea:

systemd-analyze verify myapp.service

13. Repornește serviciul

sudo systemctl restart myapp.service

Verifică imediat:

systemctl status myapp.service

Dacă serviciul nu mai pornește, consultă logurile:

journalctl -u myapp.service -b

Pentru urmărire live:

journalctl -u myapp.service -f

14. Rulează din nou auditul

systemd-analyze security --no-pager myapp.service

Compară rezultatul cu cel inițial.

Important: nu urmări doar reducerea scorului. O restricție care face serviciul inutilizabil nu este o îmbunătățire practică. Auditul trebuie să fie urmat de testarea funcționalității. systemd însuși recomandă activarea cât mai multor mecanisme de sandboxing fără a afecta funcționarea serviciului.

Workflow recomandat

systemctl cat
      ↓
systemd-analyze verify
      ↓
systemd-analyze security
      ↓
systemctl edit
      ↓
daemon-reload
      ↓
restart
      ↓
journalctl
      ↓
systemd-analyze security

Checklist rapid

[ ] Nu rulează ca root fără motiv
[ ] NoNewPrivileges=yes
[ ] ProtectSystem=strict
[ ] ProtectHome=yes
[ ] PrivateTmp=yes
[ ] PrivateDevices=yes
[ ] ProtectKernelTunables=yes
[ ] ProtectKernelModules=yes
[ ] ProtectControlGroups=yes
[ ] RestrictAddressFamilies configurat
[ ] Capabilities limitate
[ ] systemd-analyze verify trece
[ ] Serviciul funcționează după restart
[ ] Logurile nu arată erori
[ ] systemd-analyze security a fost rulat din nou

Auditarea cu systemd-analyze nu înseamnă doar să obții un scor. Procesul corect este:

identifici privilegiile → reduci suprafața de atac → verifici compatibilitatea → testezi serviciul → rulezi auditul din nou.

Solutie

Tip solutie

Permanent

Voteaza

(0 din 0 persoane apreciaza acest articol)

Despre Autor

Leave A Comment?