Відповіді:
Це звучить як ідеальна робота для аудитора. Після запуску аудиту, сервісу за замовчуванням у сучасних системах на базі RedHat, ви можете скласти правило, яке буде виконувати саме те, що ви хочете, виконавши
auditctl -a task,always -F uid=0
Порушуючи це командне правило, надмірно використовуючи довідкову сторінку, ми виявляємо, що:
-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.
Тому завжди виписуйте запис про цю дію, коли виклик системної вилки або клонування завершується.
Остаточний варіант можна розглядати як рядок фільтра, в нашому використанні -F uid=0
просто обмежує нас у випадках, коли uid власника процесу дорівнює 0.
Зауважте, що це правило можна виконати під час виконання, переконавшись, що аудит правильно налаштований, і додавши правило
-a task,always -F uid=0
до відповідного файла для вашого розповсюдження, швидше за все/etc/audit/audit.rules
Тільки майте на увазі, що це буде досить шумно, і хто б не робив огляди ваших журналів, потрібно буде до цього підготуватися.
Я не думаю, що існує чистий спосіб зробити це без перекомпіляції вашого ядра CONFIG_PROC_EVENTS та / або CONFIG_KPROBES (хоча я хотів би знати, чи є спосіб зробити це, тому я підтримав ваше запитання).
У мене була ідея використовувати iwatch / inotify для створення каталогу всередині / proc, але, схоже, це не спрацювало, а також Audctl. Схоже, ваш найкращий вибір, хоча і брудний, - це постійно розбирати ps на зміну від сценарію. Наступний код Perl зробив би це, хоча був би схильний пропускати деякі та ігнорувати ps
(як це в іншому випадку призведе до себе):
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"; } } }
Найкращим способом, що я можу придумати, було б наростити бібліотеку snoopy . snoopy - це дуже маленька спільна бібліотека, яка підключається до системи /etc/ld.so.preload
та обертається навколо execve()
системних дзвінків. Це налаштовується для реєстрації всіх exec()
, або лише тих, з кореня. У своєму поточному втіленні snoopy записує в syslog кожен раз, коли відбувається подія, що відповідає (систематичному виклику execve()
). Хоча це не велика програма (максимум кілька сотень рядків коду), і її можна було змінити без особливих труднощів для виконання сценарію замість (або на додаток до) реєстрації діяльності. Снупи написаний на С.
Кілька речей, які слід зазначити: