Featured image of post systemd: servizi e unit

systemd: servizi e unit

systemd governa cosa parte all'avvio e cosa resta in ascolto: ogni servizio di troppo è superficie d'attacco in più. Capire le unit, enable/disable/mask e come leggere lo stato è il prerequisito per ridurre ciò che gira e, nel capitolo successivo, per metterlo in gabbia. I comandi che contano per l'hardening.

Perché conta

Ogni servizio attivo è una porta potenziale: ascolta su una socket, gira con certi privilegi, ha un suo codice con sue vulnerabilità. Il principio della superficie minima dice: ciò che non gira non può essere attaccato. Prima di indurire i servizi, bisogna vederli e spegnere quelli che non servono. È il lavoro di systemd, il gestore di servizi (e molto altro) di Linux moderno.

Vedere cosa gira e cosa ascolta

1
2
3
4
systemctl list-units --type=service --state=running   # servizi attivi ORA
systemctl list-unit-files --state=enabled              # cosa parte al boot
systemd-analyze blame                                  # cosa rallenta l'avvio (e cosa c'è)
ss -tulpn                                               # porte in ascolto + processo (vedi cap. 12)

La domanda da farsi su ogni voce: mi serve davvero? Un server web non ha bisogno di un server di stampa, un demo Bluetooth, un resolver mDNS. Ogni “no” è superficie d’attacco rimossa.

Anatomia di una unit

Una unit di servizio è un file .ini. Quelle del sistema stanno in /usr/lib/systemd/system/; le tue personalizzazioni in /etc/systemd/system/ (che ha la precedenza).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# /etc/systemd/system/myapp.service
[Unit]
Description=La mia applicazione
After=network-online.target

[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp.yml
User=myapp                 # NON girare da root: account dedicato (vedi cap. 2)
Restart=on-failure

[Install]
WantedBy=multi-user.target

Due righe pesano per la sicurezza: User=myapp (il servizio gira con un account non privilegiato, non root) e tutto ciò che aggiungeremo nel prossimo capitolo per sandboxarlo.

enable, disable, mask

1
2
3
systemctl stop  cups.service          # fermalo ora
systemctl disable cups.service        # non parte più al boot
systemctl mask cups.service           # lo "blinda": non può essere avviato in alcun modo

La differenza che conta: disable toglie l’avvio automatico ma qualcosa può ancora avviarlo (una dipendenza, un socket). mask crea un link a /dev/null: il servizio è impossibile da avviare finché non lo smaschera. Per i servizi che vuoi davvero fuori gioco, mask è la scelta sicura.

Socket e timer: attivazione pigra

systemd può tenere un servizio spento e avviarlo solo alla prima connessione (socket activation), o su schedule (timer, il moderno sostituto di cron). Dal lato sicurezza: un servizio attivato on-demand non è un processo che gira e aspetta di essere attaccato per ore inutili.

1
2
systemctl list-timers                 # i job schedulati (al posto di crontab)
systemctl list-sockets

Il riflesso dell’hardening

1
2
3
4
5
Checklist su ogni servizio:
  1. serve? NO  → stop + disable + mask
  2. serve? SÌ  → gira da account dedicato (User=), non root?
  3. serve? SÌ  → è sandboxato? (prossimo capitolo)
  4. serve? SÌ  → ascolta solo dove deve? (0.0.0.0 vs 127.0.0.1 → cap. 12)

Conclusione

Vedere i servizi, spegnere e maskare l’inutile, far girare il resto da account dedicati: così si riduce la superficie prima ancora di indurire. Ma i servizi che devono restare attivi vanno messi in gabbia, perché anche un servizio non-root può fare danni se compromesso. systemd offre un sandboxing potente e sottovalutato: è il prossimo capitolo.

Built with Hugo
Theme Stack designed by Jimmy