Назад | Перейти на главную страницу

Кто-нибудь знает простой способ отслеживать порождение корневого процесса

Я хочу запустить скрипт, когда появится новый корневой процесс. (в Linux) Как я могу это сделать?

Спасибо

Похоже, это идеальная работа для auditd. После запуска auditd, службы по умолчанию в современных системах на базе 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.

Поэтому всегда записывайте это действие при выходе из системного вызова fork или clone.

Последний вариант можно рассматривать как строку фильтра, в нашем случае -F uid=0 просто ограничивает нас случаями, когда uid владельца процесса равен 0.

Обратите внимание, что это правило можно выполнить во время выполнения, убедившись, что auditd правильно настроен, и добавив правило
-a task,always -F uid=0
в соответствующий файл для вашего дистрибутива, скорее всего /etc/audit/audit.rules

Просто имейте в виду, что это будет чертовски шумно, и кто бы ни делал ваши обзоры журналов, должен быть к этому готов.

Я не думаю, что есть чистый способ сделать это без перекомпиляции ядра с помощью CONFIG_PROC_EVENTS и / или CONFIG_KPROBES (хотя мне бы хотелось узнать, есть ли способ сделать это, поэтому я поддержал ваш вопрос).

У меня была идея использовать iwatch / inotify для создания каталогов внутри / proc, но это не сработало, как и auditctl. Похоже, ваш лучший выбор, хотя и грязный, - это постоянно разбирать 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 - это очень маленькая разделяемая библиотека, которая подключается к /etc/ld.so.preload и оборачивается вокруг execve() системные вызовы. Можно настроить регистрацию всех exec()s, или только от root. В его текущем воплощении snoopy регистрирует в системном журнале каждый раз соответствующее событие (системный вызов для execve()) бывает. Однако это небольшая программа (максимум несколько сотен строк кода), и ее можно без особых трудностей изменить, чтобы выполнить сценарий вместо (или в дополнение к) регистрации активности. Снупи написан на C.

Несколько замечаний:

  • Если вы запускаете скрипт каждый раз, когда запускается корневой процесс, ваш скрипт будет корневым процессом, которому нужно будет снова порождать скрипт, который будет другим корневым процессом и т. Д. Будьте осторожны, чтобы не попасть в цикл там.
  • В типичном Linux-компьютере есть много процессов, которые запускаются от имени root и регулярно порождаются. Например, cron может порождать системные cronjobs как root каждую минуту или несколько минут. Если вы просто хотите, чтобы это произошло, когда пользователь входит в систему как root, это будет больше работы.