Existe uma maneira fácil de registrar todos os comandos executados, incluindo argumentos de linha de comando?

11

Estou tentando descobrir como registrar uma instanciação específica rrdtoolpara ver se o caminho que está recebendo está incorreto.

Eu sei que poderia envolver o executável em um script de shell que registraria os parâmetros, mas fiquei pensando se havia uma maneira mais específica de monitorar o kernel, talvez um retorno de chamada do sistema de arquivos que veja quando um / proc / pid / exe específico corresponde a um dado binário?

Peter Grace
fonte
Existe uma maneira de auditdregistrar os argumentos da linha de comando e o programa executado? serverfault.com/questions/765179/…
Neil

Respostas:

16

Sim, existe um recurso de kernel: o subsistema de auditoria. O auditddaemon faz o log e o comando auditctlconfigura as regras de log. Você pode registrar todas as chamadas em um sistema específico alls, com alguma filtragem. Se você deseja registrar todos os comandos executados e seus argumentos, registre a execvechamada do sistema:

auditctl -a exit,always -S execve

Para rastrear especificamente a chamada de um programa específico, adicione um filtro ao executável do programa:

auditctl -a exit,always -S execve -F path=/usr/bin/rrdtool

Os logs são exibidos /var/log/audit.logou onde quer que sua distribuição os coloque. Você precisa ser root para controlar o subsistema de auditoria.

Depois de concluir a investigação, use a mesma linha de comando em -dvez de -aexcluir uma regra de log ou execute auditctl -Dpara excluir todas as regras de auditoria.

Para fins de depuração, a substituição do programa por um script de wrapper oferece mais flexibilidade para registrar coisas como o ambiente, informações sobre o processo pai etc.

Gilles 'SO- parar de ser mau'
fonte
Por que o -F path=/ust/bin/rrdtool? Eu não entendo como rrdtoolé o software relacionado.
Graeme
@ Graeme O problema descrito na pergunta foi rastrear uma chamada de rrdtool. Se você deseja registrar invocações de todos os programas, solte a -F path=…parte (você obterá muitos registros, é claro).
Gilles 'SO- stop be evil'
Certo ... primeira linha da pergunta. Obrigado.
Graeme
Tudo isso é ótimo, mas como redefinir a configuração para o estado inicial? Caso contrário, ele continuará preenchendo o log com novos e novos comandos iniciados ... ou esse auditctlcomando só será efetivo até a reinicialização?
Ruslan
@Ruslan O efeito de auditctlsobreviver apenas até a reinicialização, mas é um bom argumento, eu adicionei instruções sobre como removê-las sem reiniciar a minha resposta.
Gilles 'SO- stop be evil'
6

Você poderia usar snoopy .

Snoopy é uma solução mais leve, pois não precisa de cooperação do kernel. Tudo o que é necessário é o carregador dinâmico (dl) que pré-carrega a biblioteca snoopy, caminho para o qual é especificado /etc/ld.so.preload.

Divulgação: Sou atual mantenedor do Snoopy.

Bostjan Skufca
fonte
É possível fazer o log de comandos gerados direta ou indiretamente somente a partir de um shell específico?
rv
Não sei se entendi a sua pergunta - você quer dizer "shell" como um programa específico usado como shell (bash, dash, zsh etc.) ou quer dizer que deseja registrar apenas um PTY específico? O Snoopy fornece estrutura de filtragem, mas atualmente apenas alguns filtros muito básicos são implementados, veja aqui a lista: link . Se você tem um caso de uso concreto que pode ser aplicável a outros, por favor, explicar em pedido de recurso, e, oh, btw, os remendos são bem-vindos :)
Bostjan Skufca
Eu quis dizer apenas um PTY específico.
rv
Não há filtro específico para o ATM disponível em PTY. No entanto, você pode usar o snoopy para registrar tudo, incluindo em qual PTY o evento ocorreu e, em seguida, faça a filtragem no seu daemon syslog. Não sei qual você está usando, mas o syslog-ng (por exemplo) pode fazer a correspondência de expressões regulares, positiva ou negativa.
Bostjan Skufca
Claro, obrigado! A ferramenta e a abordagem são geralmente bastante úteis. Posso filtrar facilmente para conseguir o que preciso.
rv
2

O subsistema de "auditoria" do kernel Linux pode fazer o que você precisa.

por exemplo, se você executar estes comandos:

auditctl -a exit,always -F arch=b64 -S execve
auditctl -a exit,always -F arch=b32 -S execve

Em seguida, todo evento de execução é registrado e muitas informações são fornecidas em torno desse

por exemplo, esta é a saída de mim correndo tail /var/log/audit/audit.log

exit=0 a0=7f0e4a21e987 a1=7f0e4a21e6b0 a2=7f0e4a21e808 a3=8 items=2 ppid=906 pid=928 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="tail" exe="/usr/bin/tail" subj=kernel key=(null)
type=EXECVE msg=audit(1543671660.203:64): argc=2 a0="tail" a1="/var/log/audit/audit.log"
type=CWD msg=audit(1543671660.203:64):  cwd="/home/sweh"
type=PATH msg=audit(1543671660.203:64): item=0 name="/usr/bin/tail" inode=266003 dev=fd:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=unlabeled objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1543671660.203:64): item=1 name="/lib64/ld-linux-x86-64.so.2" inode=273793 dev=fd:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=unlabeled objtype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1543671660.203:64): proctitle=7461696C002F7661722F6C6F672F61756469742F61756469742E6C6F67

Existem alguns valores interessantes que podem ser vistos; por exemplo, "auid" é 500, que é o meu ID de login, mesmo que "uid" seja zero (porque estou executando abaixo su). Portanto, mesmo que o usuário tenha trocado de conta suou sudoainda possamos rastrear seu "ID de auditoria"

Agora esses auditctlcomandos serão perdidos em uma reinicialização. Você pode colocá-los em um arquivo de configuração (por exemplo, no /etc/audit/rules.d/diretório, no CentOS 7). A localização exata dependerá da versão do seu sistema operacional. A auditctlpágina do manual deve ajudar aqui.

Cuidado, porém ... isso fará com que muitas mensagens de log sejam geradas. Verifique se você tem espaço suficiente no disco!

Se necessário, as regras podem ser limitadas a um usuário específico ou a um comando específico.

E também tenha cuidado; se um usuário colocar a senha na execução do comando (por exemplo mysql --user=username --password=passwd), ela será registrada.

Stephen Harris
fonte