Existe-t-il un moyen simple de consigner toutes les commandes exécutées, y compris les arguments de ligne de commande?

11

J'essaie de trouver comment enregistrer une instanciation spécifique de rrdtoolpour voir si le chemin d'accès qu'il reçoit est incorrect.

Je sais que je pourrais envelopper l'exécutable dans un script shell qui enregistrerait les paramètres, mais je me demandais s'il y avait une façon plus spécifique au noyau de surveiller cela, peut-être un rappel de système de fichiers qui voit quand un / proc / pid / exe particulier correspond à un binaire donné?

Peter Grace
la source
Existe-t-il un moyen d' auditdenregistrer les arguments de la ligne de commande ainsi que l'exécution du programme? serverfault.com/questions/765179/…
Neil

Réponses:

16

Oui, il existe une fonction noyau: le sous-système d'audit. Le auditddémon effectue la journalisation et la commande auditctldéfinit les règles de journalisation. Vous pouvez enregistrer tous les appels vers un système spécifique à tous, avec un certain filtrage. Si vous souhaitez enregistrer toutes les commandes exécutées et leurs arguments, connectez l' execveappel système:

auditctl -a exit,always -S execve

Pour suivre spécifiquement l'invocation d'un programme spécifique, ajoutez un filtre sur l'exécutable du programme:

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

Les journaux s'affichent dans /var/log/audit.log, ou partout où votre distribution les place. Vous devez être root pour contrôler le sous-système d'audit.

Une fois l'enquête terminée, utilisez la même ligne de commande avec -dau lieu de -apour supprimer une règle de journalisation, ou exécutez auditctl -Dpour supprimer toutes les règles d'audit.

À des fins de débogage, le remplacement du programme par un script wrapper vous donne plus de flexibilité pour enregistrer des éléments tels que l'environnement, des informations sur le processus parent, etc.

Gilles 'SO- arrête d'être méchant'
la source
Pourquoi -F path=/ust/bin/rrdtool? Je ne comprends pas comment rrdtoolsont même les logiciels associés.
Graeme
@Graeme Le problème décrit dans la question était le suivi d'une invocation de rrdtool. Si vous souhaitez enregistrer les invocations de tous les programmes, supprimez la -F path=…partie (vous obtiendrez beaucoup de journaux bien sûr).
Gilles 'SO- arrête d'être méchant'
Bon ... première ligne de la question. Merci.
Graeme
C'est très bien, mais comment réinitialiser la configuration à son état initial? Sinon, il continuera à remplir le journal avec de nouvelles et nouvelles commandes lancées ... ou cette auditctlcommande n'est-elle efficace que jusqu'au redémarrage?
Ruslan
@Ruslan L'effet de auditctlne survit qu'au redémarrage, mais c'est quand même un bon point, j'ai ajouté des instructions pour les supprimer sans redémarrer à ma réponse.
Gilles 'SO- arrête d'être méchant'
6

Vous pouvez utiliser snoopy .

Snoopy est une solution plus légère car elle n'a pas besoin de coopération avec le noyau. Tout ce qui est nécessaire est un chargeur dynamique (dl) qui précharge la bibliothèque snoopy, dont le chemin est spécifié dans /etc/ld.so.preload.

Divulgation: Je suis le responsable actuel de Snoopy.

Bostjan Skufca
la source
Est-il possible de faire la journalisation des commandes générées directement ou indirectement à partir d'un shell particulier uniquement?
rv
Je ne suis pas sûr de comprendre votre question - voulez-vous dire "shell" en tant que programme spécifique utilisé comme shell (bash, dash, zsh etc.), ou vous voulez que vous souhaitiez enregistrer uniquement PTY spécifique? Snoopy fournit un cadre de filtrage, mais actuellement seuls quelques filtres très basiques sont implémentés, voir ici pour la liste: lien . Si vous avez un cas d'utilisation concret qui pourrait s'appliquer à d'autres, veuillez expliquer dans la demande de fonctionnalité, et, oh, btw, les correctifs sont les bienvenus :)
Bostjan Skufca
Je voulais juste un PTY spécifique.
rv
Il n'y a pas de filtre spécifique pour ATM PTY disponible. Cependant, vous pouvez utiliser snoopy pour tout enregistrer, y compris sur quel PTY l'événement s'est produit, puis effectuer le filtrage dans votre démon syslog. Je ne sais pas lequel vous utilisez, mais syslog-ng (par exemple) peut faire une correspondance regex, positive ou négative.
Bostjan Skufca
Bien sûr, merci! L'outil et l'approche sont en général assez utiles. Je peux facilement filtrer pour obtenir ce dont j'ai besoin.
rv
2

Le sous-système «audit» du noyau Linux peut faire ce dont vous avez besoin.

par exemple, si vous exécutez ces commandes:

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

Ensuite, chaque événement d'exécution est enregistré et de nombreuses informations sont fournies à ce sujet.

par exemple, c'est la sortie de moi en cours d'exécution 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

Il y a des valeurs intéressantes qui peuvent être vues; Par exemple, "auid" est 500, qui est mon ID de connexion, même si "uid" est zéro ('car je cours sous su). Ainsi, même si l'utilisateur a changé de compte suou que sudonous pouvons toujours retrouver son "ID d'audit"

Maintenant, ces auditctlcommandes seront perdues lors d'un redémarrage. Vous pouvez les mettre dans un fichier de configuration (par exemple dans le /etc/audit/rules.d/répertoire, sur CentOS 7). L'emplacement exact dépendra de la version de votre système d'exploitation. La auditctlpage de manuel devrait aider ici.

Attention, cependant ... cela entraînera la génération de nombreux messages de journal. Assurez-vous d'avoir suffisamment d'espace sur le disque!

Si nécessaire, les règles peuvent être limitées à un utilisateur spécifique ou à une commande spécifique.

Et méfiez-vous également; si un utilisateur met le mot de passe dans l'exécution de la commande (par exemple mysql --user=username --password=passwd), il sera enregistré.

Stephen Harris
la source