Solution 1 :
Cela ressemble à un travail parfait pour auditd. Une fois que vous avez lancé auditd, un service par défaut sur les systèmes modernes basés sur RedHat, vous pouvez créer une règle qui fera exactement ce que vous voulez en exécutant
auditctl -a task,always -F uid=0
En brisant cette règle de commande, en faisant un usage excessif de la page de manuel, nous constatons que :
-a list,action task Add a rule to the per task list. This rule list is used only at the time a task is created -- when fork() or clone() are called by the parent task. When using this list, you should only use fields that are known at task creation time, such as the uid, gid, etc. always Allocate an audit context, always fill it in at syscall entry time, and always write out a record at syscall exit time.
Donc, écrivez toujours un enregistrement pour cette action chaque fois qu'un appel système fork ou clone se termine.
La dernière option peut être considérée comme une chaîne de filtre, dans notre utilisation -F uid=0
nous limite simplement aux cas où l'uid du propriétaire du processus est 0.
Notez que cette règle peut être exécutée au moment de l'exécution en s'assurant que auditd est correctement configuré et en ajoutant la règle
-a task,always -F uid=0
dans le fichier correspondant à votre distribution, très probablement /etc/audit/audit.rules
Gardez simplement à l'esprit que cela sera assez bruyant et que la personne qui effectuera vos révisions de journaux devra s'y préparer.
Solution 2 :
Je ne pense pas qu'il existe un moyen propre de le faire sans recompiler votre noyau avec CONFIG_PROC_EVENTS et/ou CONFIG_KPROBES (bien que j'aimerais savoir s'il existe un moyen de le faire, j'ai donc voté pour votre question).
J'ai eu l'idée d'utiliser iwatch/inotify pour la création de répertoires dans /proc mais cela ne semblait pas fonctionner, pas plus que auditctl. Il semble que votre meilleur choix, bien que sale, soit d'analyser continuellement ps pour un changement d'un script. Le code Perl suivant le ferait, bien qu'il soit susceptible d'en manquer et ignore ps
(car il se déclencherait autrement):
perl -e 'my %pids; while(1) { my @pids = `ps -U root -u root`; foreach (@pids) { next if /ps$/; ($pid) = /^\s*(\d+)\D/; if (!$pids{$pid}) { $pids{$pid}++; print "Process $pid created (" . `cat /proc/$pid/cmdline` . ")\n"; } } }