如何使用脚本实用程序自动记录所有终端会话


28

我想要实现的是能够在每次使用Yakuake / Konsole时自动记录我的终端会话以归档。

如果在会议开始时我很容易做到:

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

但是我想在每次启动Yakuake或打开新标签时自动运行以上命令。

使用.bashrc无效,因为它会产生无限循环,因为'script'打开了一个新会话,该会话依次读取.bashrc并启动了另一个'script',依此类推。

因此,大概我需要以某种方式编写脚本Yakuake / Konsole,以在打开新标签页后立即运行“脚本”。问题是如何?


尝试用循环问题解决有问题的解决方案,但是exec在行的开头添加。它应该script -f在相同的Shell PID中启动。
Hanan N.

这个问题的另一个有趣的扩展版本是如何以非root用户身份强制非root用户编写所有会话的脚本……
Yordan Georgiev 2014年

Answers:


26

如果有人想使用该script实用工具自动记录其终端会话(包括SSH会话(!)),则方法如下。

将以下行添加到.bashrc主目录的末尾;否则,/etc/bash.bashrc如果只想记录所有用户的会话,则添加其他行。我们测试shell的父进程是否不存在script,然后运行script

对于Linux:

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

对于BSD和macOS,更改script -fscript -F

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

就这样!

现在,当您打开一个新终端时,您将看到:

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

script会将您的会话写入主目录中的文件,从而将其命名为类似30-Nov-11_00-11-12_shell.log的结果。

更多定制:

  • 您可以将会话附加到一个大文件,而无需为每个会话创建一个新文件 script -a /path/to/single_log_file
  • 您可以通过在script -f(Linux)或script -F(BSD和macOS)之后更改路径来调整写入文件的位置

script当然,此答案假设您已安装。在基于Debian的发行版中,script是该bsdutils软件包的一部分。


您可以自己编辑问题及其标题。只需单击其edit下方显示的按钮即可。

8
您可能要考虑在文件名中添加${RANDOM}和和$$,因为在彼此之间相差一秒之内启动两个shell会导致文件名冲突。就个人而言,我经常script.$(date -u +%Y%m%dt%H%M%S).${HOSTNAME:-$(hostname)}.$$.${RANDOM}.log用来确保文件按日期/时间自动排序,并且在整个TZ中它们是一致的,我知道启动它的主机,我知道拥有过程,并且没有名称冲突。我很少使用,${USER}因为它通常仅对我有用。
nicerobot 2011年

您写道:“确保您实际上已经创建了/ var / log / script并使其可被其他人写入”。我想知道从安全角度来看,在这种情况下是否建议使用“ sudo chmod 777 / var / log / script”。
张二

10

尽管这个问题是由想要记录自己的会话的个人提出的,但另一个用例可能是系统管理员,他想跟踪各种用户的行为。

我担心,如果机器的用户不愿意记录自己的会话,则可能无法script在系统范围内运行bashrc

希望保持隐身状态的用户可以通过要求sshd打开其他外壳程序(例如zsh)或运行bash --rcfile ___以防止/etc/bash.bashrc加载来绕过日志记录。

另一种方法

2008年的本指南已存档)使用了一种不同的方法来强制script用户使用ssh登录时运行,该方法要求用户使用公钥/私钥登录。

这是通过在脚本.ssh/authorized_keys前面的用户文件中添加脚本来完成的:

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

然后,log-session存档的)脚本决定是否运行/usr/bin/script以记录该用户的会话。

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

为了防止用户删除添加的命令,管理员将需要承担用户authorized_keys文件的所有权。

chown root:root ~user/.ssh/authorized_keys

不幸的是,这意味着用户将无法自己添加任何其他密钥,或者更重要的是,如果现有密钥被泄露,则将其撤销是很不理想的。

注意事项

sshd的默认配置通常允许用户通过其ssh登录名执行SFTP。这为用户提供了一种在不记录更改的情况下编辑文件的方法。如果管理员不希望用户能够执行此操作,则他应该为SFTP启用某些日志记录,或者禁用该服务。尽管即使那样,用户仍然可以通过在其终端中运行以下内容来对文件进行看不见的更改:

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

通过使用记录所有文件历史记录的写时复制文件系统,可以监视类似的更改。

但是类似的技巧可以使用户在不记录命令的情况下执行命令:

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

我不知道有什么简单的解决方案。可能是:

  • 记录所有网络数据(并在以后对其进行整理)。
  • 记录所有系统调用。

使用auditd可能会发生这种情况。

但不管怎么说...

记录用户会话不太可能为管理员提供任何真正的安全性。默认情况下,用户只能操作自己的文件,而不会损害系统。如果恶意用户确实设法提升了权限,则他可以禁用日志记录并删除日志(除非管理员已将日志配置为以仅追加方式存储在单独的计算机上)。

自动记录用户会话的管理员可能应该通知用户这已完成。在某些辖区,这种形式的数据收集可能违反数据或隐私法。至少,要让用户知道它们是尊重的。

管理员更有可能对记录sudo用户的会话感兴趣。也许可以用不同的答案或不同的问题来解决。


2

代替:

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

我会用:

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

在这种情况下,双引号不是必需的,但是无论如何我还是倾向于将其用作标准做法。我绝对建议同时对grep和pgrep使用“ x”开关,以避免与子字符串罕见但有问题的匹配。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.