Eu quero executar um script quando um novo processo raiz aparecer. (no Linux) Como posso simplesmente fazer isso?
obrigado
Eu quero executar um script quando um novo processo raiz aparecer. (no Linux) Como posso simplesmente fazer isso?
obrigado
Respostas:
Isso soa como um trabalho perfeito para o auditd. Depois de executar o auditd, um serviço padrão nos modernos sistemas baseados em RedHat, você pode criar uma regra que fará exatamente o que você deseja, executando
auditctl -a task,always -F uid=0
Quebrando essa regra de comando, fazendo uso excessivo da página de manual, descobrimos 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.
Portanto, sempre escreva um registro para esta ação sempre que uma chamada do sistema fork ou clone terminar.
A opção final pode ser pensada como uma sequência de filtros, em nosso uso -F uid=0
simplesmente nos restringe aos casos em que o uid do proprietário do processo é 0.
Observe que esta regra pode ser executada em tempo de execução, certificando-se de que o auditd esteja configurado corretamente e adicionando a regra
-a task,always -F uid=0
ao arquivo relevante para sua distribuição, provavelmente/etc/audit/audit.rules
Lembre-se de que isso será bastante barulhento e quem estiver fazendo suas revisões de log precisará estar preparado para isso.
Eu não acho que exista uma maneira limpa de fazer isso sem recompilar seu kernel com CONFIG_PROC_EVENTS e / ou CONFIG_KPROBES (embora eu adoraria saber se existe uma maneira de fazê-lo, por isso eu votei na sua pergunta).
Eu tive uma idéia de usar o iwatch / inotify para criação de diretório dentro do / proc, mas não parecia funcionar, nem o auditctl. Parece que sua melhor escolha, apesar de suja, é analisar continuamente o ps para alterar um script. O código Perl a seguir faria isso, embora estivesse propenso a perder alguns e ignora ps
(como seria acionado por si mesmo):
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"; } } }
A melhor maneira de pensar seria construir a biblioteca snoopy . snoopy é uma biblioteca compartilhada muito pequena que é conectada /etc/ld.so.preload
e envolveexecve()
chamadas do sistema. É configurável para registrar todos exec()
, ou apenas aqueles da raiz. Na encarnação atual, o snoopy registra no syslog toda vez que um evento correspondente (um syscall execve()
) acontece. Porém, não é um programa grande (no máximo algumas centenas de linhas de código) e pode ser modificado sem muita dificuldade para executar um script em vez de (ou além de) registrar a atividade. Snoopy é escrito em C.
Algumas coisas a serem observadas: