SSD Nodes Learn
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-07-24

Eseguire servizi come utente non root

Evita che un bug comprometta l'intero server. Scopri come limitare i privilegi con account dedicati o usando la funzione DynamicUser di systemd.

Perché non eseguire tutto come root

Root può fare qualsiasi cosa sulla macchina: leggere ogni file, cambiare ogni impostazione, eliminare l'intero sistema. Se si esegue un servizio come root, si delega tutto questo potere a quel servizio. Se il servizio presenta un bug sfruttabile da un attaccante, l'attaccante non ottiene solo il controllo del servizio, ma ottiene root, e root equivale all'intero server. Eseguire i processi come utente non privilegiato limita il danno. Un bug in un servizio che gira con un account limitato concede all'attaccante solo ciò che quell'account può toccare, che dovrebbe essere quasi nulla.

Questo è il principio del minimo privilegio: fornire a ogni parte del sistema esattamente l'accesso necessario per svolgere il proprio compito, e nient'altro. È la pratica più efficace per limitare il raggio d'azione di un compromesso e, su un server moderno, non costa quasi nulla da applicare.

Un account dedicato per ogni servizio

L'approccio classico consiste nel creare un utente di sistema separato per ogni servizio, che possieda solo i file di quel servizio e non possa effettuare il login. Un account di sistema per una web app può apparire così:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

Ogni flag è importante. --system lo rende un account di servizio, non un login per un utente umano. --no-create-home evita la creazione di una home directory non necessaria. --shell /usr/sbin/nologin significa che anche se un attaccante dovesse ottenere l'accesso all'account, non potrebbe aprire una shell. L'account esiste solo per gestire un processo e i suoi file.

Assegnare quindi a quell'utente solo i file necessari, e nient'altro:

sudo chown -R appsvc:appsvc /opt/myapp

Ora il servizio legge e scrive nella propria directory e non ha permessi per operare altrove sul disco. Se viene sfruttato, i file che l'attaccante può modificare sono limitati a /opt/myapp; l'account può ancora leggere tutto ciò che è leggibile da tutti, ma non può modificare il resto del sistema.

Lasciare che systemd lo esegua come quell'utente

Una volta creato l'account, istruire systemd a eseguire il servizio con esso. Nel file di unit, una riga lo permette:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc significa che il processo viene avviato con i privilegi limitati di quell'account invece che con quelli di root. Questo è il modo standard e consolidato per eseguire un'applicazione sotto systemd, ed è opportuno farlo per ogni servizio per cui si scrive una unit.

Oppure saltare l'account con DynamicUser

systemd può fare un passo avanti e creare un utente temporaneo per voi, che esiste solo finché il servizio è in esecuzione. Impostate DynamicUser=yes e non dovrete gestire alcun account:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

All'avvio, systemd assegna un user ID non utilizzato; all'arresto, lo rilascia. Il servizio ottiene anche un /tmp privato, una vista in sola lettura della maggior parte del filesystem, e una directory di stato scrivibile sotto /var/lib/myapp che StateDirectory= configura e gli assegna. Per un servizio autonomo che necessita solo della propria directory di stato, DynamicUser=yes è il metodo con meno sforzo per ottenere un'isolamento forte, poiché non esiste alcun account a lungo termine che un attaccante possa colpire.

Scrivere le unit manualmente è complesso, e la corretta configurazione delle direttive di hardening rappresenta il valore principale. Il generatore in la guida ai servizi e ai timer di systemd può compilare queste opzioni per voi, garantendo che la unit sia corretta fin dal primo tentativo.

Come si integra con il resto

Il minimo privilegio è uno strato e funziona insieme agli altri invece di sostituirli. Un firewall default-deny controlla cosa può raggiungere il servizio; eseguirlo come utente non privilegiato controlla cosa può fare il servizio se viene violato; e un SSH hardened impedisce agli attaccanti di accedere alla macchina fin dall'inizio. Nessuno di questi elementi da solo è sufficiente; insieme garantiscono che un bug in un singolo servizio non diventi un compromesso dell'intero server.

Prima di procedere, esegui una checklist di hardening per l'intero sistema e genera una copia personalizzata da utilizzare:

ToolVPS hardening checklist

FAQ

Perché non dovrei eseguire un servizio come root?

Perché root può fare qualsiasi cosa sulla macchina; un servizio eseguito come root che viene sfruttato consegna all'attaccante l'intero server, non solo il servizio. Eseguire il servizio come account limitato e non privilegiato confina il danno a tutto ciò che quell'account può accedere. Riservate root per l'amministrazione ed eseguite ogni servizio a lunga esecuzione come utente ristretto.

Come creo un utente che non può effettuare il login?

Eseguite sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. La shell nologin significa che l'account non può aprire una sessione interattiva anche se le sue credenziali vengono rubate, --system lo marca come account di servizio e --no-create-home evita la creazione di una home directory non necessaria. Assegnategli la proprietà solo dei propri file con chown.

Cos'è systemd DynamicUser?

DynamicUser=yes istruisce systemd a creare un utente temporaneo per il servizio che esiste solo finché il servizio è in esecuzione, evitando la gestione di un account a lungo termine. Fornisce inoltre al servizio un /tmp privato, una vista del filesystem quasi interamente in sola lettura, e una directory di stato gestita. È il modo più semplice per eseguire un servizio autonomo sotto un'identità temporanea a bassi privilegi.

L'esecuzione come utente non-root sostituisce un firewall?

No. Proteggono cose diverse. L'esecuzione come utente non privilegiato limita ciò che un servizio può fare se viene violato, mentre un firewall limita ciò che può raggiungere il servizio. Utilizzate entrambi, insieme a un SSH protetto, affinché ogni strato copra ciò che gli altri non possono coprire.

Quali file deve possedere l'utente del servizio?

Solo i file di cui il servizio ha effettivamente bisogno, e nient'altro. Assegnate all'account la proprietà della propria directory di lavoro e dei propri dati, e lasciate tutto il resto di proprietà di root. Un buon pattern è sudo chown -R svc-app:svc-app /opt/svc-app per la directory dell'applicazione, mentre la configurazione sotto /etc rimane di proprietà di root ed è leggibile solo dal servizio. L'obiettivo è che, se il processo viene compromesso, i file che può modificare siano limitati ai propri dati, non al resto del sistema.

#security#least-privilege#systemd#users#hardening#linux