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

Sta*_*tan 33 scripting bash terminal konsole

我想要实现的是能够在我使用 Yakuake/Konsole 时自动记录我的终端会话到文件。

如果在我的会话开始时我这样做,很容易实现:

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

但是我想在启动 Yakuake 或打开新标签时自动运行上述内容。

使用 .bashrc 不起作用,因为它会在“脚本”打开一个新会话时创建无限循环,而该会话又会读取 .bashrc 并启动另一个“脚本”等等。

所以大概我需要以某种方式编写 Yakuake/Konsole 脚本,以便在打开新选项卡时运行一次“脚本”。问题是如何?

Sta*_*tan 34

如果有人想自动记录他们的终端会话——包括 SSH 会话(!)——使用该script实用程序,这里是如何。

.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)
Run Code Online (Sandbox Code Playgroud)

对于 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)
Run Code Online (Sandbox Code Playgroud)

就这样!

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

Script started, file is /home/username/file_name.log
Run Code Online (Sandbox Code Playgroud)

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 的发行版上,scriptbsdutils软件包的一部分。

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

joe*_*dle 10

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

我担心在机器用户不愿意记录他们的会话的情况下,script在系统范围内运行bashrc可能不适合。

希望保持隐身的用户可以通过要求 sshd 打开不同的 shell(例如zsh)或运行bash --rcfile ___以防止/etc/bash.bashrc被加载来绕过日志记录。

另一种方法

这份 2008 年的指南已归档)使用不同的方法script在用户使用 ssh 登录时强制运行,这要求用户使用公钥/私钥登录。

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

command="/usr/local/sbin/log-session" ssh-dss AAAAB3NzaC1kc3MAAAEBAMKr1HxJz.....
Run Code Online (Sandbox Code Playgroud)

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

exec script -a -f -q -c "$SSH_ORIGINAL_COMMAND" $LOGFILE
Run Code Online (Sandbox Code Playgroud)

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

chown root:root ~user/.ssh/authorized_keys
Run Code Online (Sandbox Code Playgroud)

不幸的是,这意味着用户将无法自己添加任何额外的密钥,或者更重要的是,如果现有密钥受到威胁,则无法撤销,这远非理想。

注意事项

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

curl "http://users.own.server/server/new_data" > existing_file
Run Code Online (Sandbox Code Playgroud)

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

但是类似的技巧将允许用户在没有记录的情况下执行命令:

curl "http://users.own.server/server/secret_commands_824" | sh
Run Code Online (Sandbox Code Playgroud)

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

  • 记录所有网络数据(稍后解开它)。
  • 记录所有系统调用。

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

但无论如何...

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

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

管理员更有可能对记录sudo用户的会话感兴趣。这也许可以在不同的答案中解决,或者实际上是一个不同的问题。