So che gli spazi dei nomi di Linux, tra molte altre cose, possono essere sfruttati per gestire la limitazione e il jailing dei processi figlio in modo sicuro senza alcuna possibilità che vengano zombi e scaricati su init
. Ma sono confuso sui dettagli di implementazione. Come potrei usare gli strumenti forniti da util-linux
come mount
e nsenter
controllare, monitorare e garantire che tutti i processi avviati siano i diretti discendenti dello spazio dei nomi di un altro processo?
Risposta accettata:
Crea uno spazio dei nomi PID
Il comando corretto da usare qui è unshare
. Nota che le opzioni necessarie per farlo sono disponibili solo da util-linux 2.23
. L'idea è di creare un nuovo spazio dei nomi PID per il programma in esecuzione in modo tale che tutti i suoi figli vengano creati anche in questo spazio dei nomi. Puoi eseguire un comando in un nuovo spazio dei nomi PID semplicemente facendo:
sudo unshare -fp some_command
Per eseguire una shell, ometti semplicemente il comando. Questo creerà un processo che, insieme a tutti i suoi figli, avrà un PID come al solito all'interno dello spazio dei nomi padre (sistema). Tuttavia, all'interno del nuovo spazio dei nomi, avrà un PID di 1
insieme ad alcune delle caratteristiche speciali di init
processi. Forse la caratteristica più rilevante dal punto di vista del monitoraggio è che se uno qualsiasi dei suoi discendenti è orfano, sarà ricondotto a questo processo piuttosto che al vero init
processo.
Semplicemente farlo può essere sufficiente per la maggior parte dei casi di monitoraggio. Come accennato in precedenza, i processi all'interno dello spazio dei nomi hanno tutti PID all'interno dello spazio dei nomi padre, quindi è possibile utilizzare i normali comandi per monitorare la loro attività. Siamo inoltre certi che se un processo nello spazio dei nomi diventa orfano, non cadrà dai rami dell'albero dei processi sotto il PID del programma di livello superiore, il che significa che è ancora possibile tenerne traccia facilmente.
Combina con uno spazio dei nomi di montaggio
Tuttavia, ciò che non possiamo fare è monitorare il processo rispetto al PID che pensa cioè ha. Per fare questo, e in particolare per poter utilizzare il ps
comando all'interno del nuovo spazio dei nomi, è necessario montare un procfs
separato filesystem per lo spazio dei nomi. Questo a sua volta porta a un altro problema poiché l'unica posizione che ps
accetta per procfs
è /proc
. Una soluzione sarebbe creare un chroot
jail e montare il nuovo procfs
là. Ma questo è un approccio ingombrante poiché come minimo dovremmo copiare (o almeno un collegamento fisico) tutti i binari che intendiamo utilizzare insieme a tutte le librerie da cui dipendono nella nuova radice.
La soluzione consiste nell'usare anche un nuovo spazio dei nomi di montaggio . All'interno di questo possiamo montare i nuovi procfs
in un modo che utilizza la vera radice /proc
directory, può essere utilizzato all'interno dello spazio dei nomi PID e non interferisce con nient'altro. Per rendere questo processo molto semplice, unshare
il comando fornisce il --mount-proc
opzione:
sudo unshare -fp --mount-proc some_command
Ora in esecuzione ps
all'interno degli spazi dei nomi combinati mostrerà solo i processi con lo spazio dei nomi PID e mostrerà il processo di livello superiore come avente un PID di 1
.
Che dire di nsenter
?
Come suggerisce il nome, nsenter
può essere utilizzato per inserire uno spazio dei nomi che è già stato creato con unshare
. Questo è utile se vogliamo ottenere informazioni disponibili solo dall'interno dello spazio dei nomi da uno script altrimenti non correlato. Il modo più semplice è accedere fornendo il PID di qualsiasi programma in esecuzione all'interno dello spazio dei nomi. Per essere chiari questo deve essere il PID del programma di destinazione all'interno dello spazio dei nomi da cui nsenter
è in esecuzione (poiché gli spazi dei nomi possono essere nidificati, è possibile che un singolo processo abbia molti PID). Per eseguire una shell nel PID di destinazione/spazio dei nomi di montaggio, eseguire semplicemente:
sudo nsenter -t $PID -m -p
Se questo spazio dei nomi è impostato come sopra, ps
ora elencherà solo i processi all'interno di quello spazio dei nomi.