Comment enregistrer automatiquement toutes vos sessions de terminal avec l'utilitaire de script

28

Ce que je veux réaliser, c'est pouvoir enregistrer mes sessions de terminal pour les déposer automatiquement chaque fois que j'utilise Yakuake / Konsole.

C'est facile à réaliser si au début de ma session je fais:

script -f /home/$USER/bin/shell_logs/$(date +"%d-%b-%y_%H-%M-%S")_shell.log

Mais je veux exécuter ce qui précède automatiquement chaque fois que je démarre Yakuake ou ouvre un nouvel onglet.

L'utilisation de .bashrc ne fonctionne pas car il crée une boucle sans fin car le «script» ouvre une nouvelle session, qui à son tour lit .bashrc et démarre un autre «script» et ainsi de suite.

Donc, je suppose que j'ai besoin de script Yakuake / Konsole pour exécuter le script une fois qu'un nouvel onglet est ouvert. La question est de savoir comment?

Stan
la source
essayez la solution problématique avec le problème de boucle, mais ajoutez le execau début de la ligne. il doit démarrer le script -fdans le même shell PID.
Hanan N.
La version modifiée de cette question est également intéressante: comment forcer les utilisateurs non-root à rooter également toutes leurs sessions ...
Yordan Georgiev

Réponses:

26

Si quelqu'un souhaite enregistrer automatiquement ses sessions de terminal - y compris les sessions SSH (!) - à l'aide de l' scriptutilitaire, voici comment procéder.

Ajoutez la ligne suivante à la fin de .bashrcdans votre répertoire personnel, ou sinon /etc/bash.bashrcsi vous souhaitez uniquement enregistrer toutes les sessions des utilisateurs. Nous testons le processus parent du shell scriptet nous l'exécutons script.

Pour Linux:

test "$(ps -ocommand= -p $PPID | awk '{print $1}')" == 'script' || (script -f $HOME/$(date +"%d-%b-%y_%H-%M-%S")_shell.log)

Pour BSD et macOS, passez script -fà script -F:

test "$(ps -ocommand= -p $PPID | awk '{print $1}')" == 'script' || (script -F $HOME/$(date +"%d-%b-%y_%H-%M-%S")_shell.log)

C'est tout!

Maintenant, lorsque vous ouvrez un nouveau terminal, vous verrez:

Script started, file is /home/username/file_name.log

scriptva écrire vos sessions dans un fichier de votre répertoire personnel en les nommant comme 30-Nov-11_00-11-12_shell.logrésultat.

Plus de personnalisation:

  • Vous pouvez ajouter vos sessions à un seul fichier volumineux plutôt que d'en créer un nouveau pour chaque session avec script -a /path/to/single_log_file
  • Vous pouvez ajuster où les fichiers sont écrits en changeant le chemin après script -f(Linux) ou script -F(BSD et macOS)

Cette réponse suppose que vous avez scriptinstallé, bien sûr. Sur les distributions basées sur Debian, scriptfait partie du bsdutilspaquet.

Stan
la source
Vous pouvez modifier vous-même votre question et son titre. Cliquez simplement sur le editbouton qui apparaît juste en dessous.
Mat
8
Vous voudrez peut-être envisager d'ajouter un ${RANDOM}et / ou $$au nom de fichier, car le démarrage de deux shells dans la seconde entraînera une collision de nom de fichier. Personnellement, j'utilise souvent script.$(date -u +%Y%m%dt%H%M%S).${HOSTNAME:-$(hostname)}.$$.${RANDOM}.logpour m'assurer que les fichiers sont automatiquement triés par date / heure et qu'ils sont cohérents sur TZ, je connais l'hôte qui l'a initié, je connais le processus de propriété et il n'y a pas de collisions de noms. J'utilise rarement ${USER}parce que c'est généralement quelque chose pour moi seulement.
nicerobot
"assurez-vous que vous avez réellement créé / var / log / script et rendu accessible en écriture par les autres", avez-vous écrit. Je me demandais s'il était conseillé du point de vue de la sécurité d'utiliser "sudo chmod 777 / var / log / script" dans ce cas.
Teo
10

Bien que cette question ait été posée par une personne souhaitant enregistrer ses propres sessions, un autre cas d'utilisation pourrait être un administrateur système qui souhaite garder une trace de ce que font les différents utilisateurs.

J'ai peur de courir script à l'intérieur du système bashrcne soit pas adapté dans le cas où les utilisateurs de la machine hésitent à faire enregistrer leurs sessions.

Les utilisateurs qui souhaitent rester incognito pourraient contourner la journalisation en demandant à sshd d'ouvrir un autre shell (par exemple zsh) ou d'exécuter bash --rcfile ___pour empêcher/etc/bash.bashrc d'être chargé.

Une approche alternative

Ce guide de 2008 ( archivé ) utilise une méthode différente pour forcerscript son exécution lorsqu'un utilisateur se connecte avec ssh, ce qui oblige les utilisateurs à se connecter avec une clé publique / privée.

Cela se fait en ajoutant un script au .ssh/authorized_keysfichier de l'utilisateur , devant la clé:

command="/usr/local/sbin/log-session" ssh-dss AAAAB3NzaC1kc3MAAAEBAMKr1HxJz.....

Le script log-session( archivé ) décide ensuite s'il doit s'exécuter ou non /usr/bin/scriptpour enregistrer la session de cet utilisateur.

exec script -a -f -q -c "$SSH_ORIGINAL_COMMAND" $LOGFILE

Pour empêcher l'utilisateur de supprimer la commande ajoutée, l'administrateur devra assumer la propriété du authorized_keysfichier de l'utilisateur .

chown root:root ~user/.ssh/authorized_keys

Malheureusement, cela signifie que l'utilisateur ne pourra pas ajouter lui-même de clés supplémentaires ou, plus important encore, révoquer la clé existante si elle est compromise, ce qui est loin d'être idéal.

Avertissements

Il est courant que la configuration par défaut de sshd permette aux utilisateurs d'exécuter SFTP via leur connexion ssh. Cela permet aux utilisateurs de modifier des fichiers sans que les modifications soient enregistrées. Si l'administrateur ne souhaite pas que les utilisateurs soient en mesure de le faire, il doit activer la journalisation pour SFTP ou désactiver le service. Bien que même dans ce cas, les utilisateurs puissent toujours apporter des modifications invisibles aux fichiers en exécutant quelque chose comme ceci dans leur terminal:

curl "http://users.own.server/server/new_data" > existing_file

Il peut être possible de surveiller des modifications comme celle-ci en utilisant un système de fichiers de copie sur écriture qui enregistre tout l'historique des fichiers.

Mais une astuce similaire permettrait à un utilisateur d'exécuter des commandes sans qu'il soit connecté:

curl "http://users.own.server/server/secret_commands_824" | sh

Je ne connais aucune solution simple à cela. Les possibilités peuvent être:

  • Consigner toutes les données du réseau (et les démêler plus tard).
  • Enregistrement de tous les appels système.

Ce genre de chose pourrait être possible avec auditd .

Mais peu importe...

Il est peu probable que la journalisation des sessions utilisateur offre une réelle sécurité aux administrateurs. Par défaut, un utilisateur ne peut manipuler que ses propres fichiers et ne peut pas endommager le système. Si un utilisateur malveillant parvient à augmenter les privilèges, il peut désactiver la journalisation et supprimer les journaux (sauf si l'administrateur a configuré les journaux pour qu'ils soient stockés sur une machine distincte, en ajoutant uniquement).

Les administrateurs qui enregistrent automatiquement les sessions utilisateur devraient probablement informer les utilisateurs que cela est en cours . Dans certaines juridictions, cette forme de collecte de données peut violer les lois sur les données ou la confidentialité . Et à tout le moins, il serait respectueux des utilisateurs de les informer.

Il est plus probable qu'un administrateur serait intéressé par la journalisation des sessions des sudoutilisateurs. Cela pourrait peut-être être abordé dans une réponse différente, voire une question différente.

joeytwiddle
la source
2

Au lieu de:

test "$(ps -ocommand= -p $PPID | awk '{print $1}')" == 'script' ||

J'utiliserais:

grep -qx "$PPID" <(pgrep -x "script") ||

Les guillemets doubles ne sont pas nécessaires dans ce cas, mais j'ai tendance à les utiliser de toute façon comme pratique standard. Je recommande vraiment d'utiliser le commutateur "x" à la fois pour le grep et le pgrep, pour éviter une correspondance rare mais problématique avec les sous-chaînes.

William Dye
la source