【问题标题】:Differentiate between exit and session timeout区分退出和会话超时
【发布时间】:2020-02-18 12:34:34
【问题描述】:

我有以下要求:

  • 当用户终止 bash 会话时生成审核日志(退出)
  • 当 bash 会话超时时生成审核日志

这些审核日志必须不同。我正在玩以下脚本trap.sh

export TMOUT=10

function handle-timeout {
    echo "Timeout"
}

function handle-exit {
    echo "Exit"
}

trap handle-exit EXIT

现在如果我这样做:

valegon@precision ~ (master) $ bash
valegon@precision ~ (master) $ source trap.sh
valegon@precision ~ (master) $ exit
Exit

它按预期工作。相反,我等待超时发生:

valegon@precision ~ (master) $ bash
valegon@precision ~ (master) $ source trap.sh
valegon@precision ~ (master) $ timed out waiting for input: auto-logout
Exit

这里有两个问题:

  1. 超时触发EXIT,我不希望这样
  2. 我不知道如何专门捕获超时

如何解决这些未解决的问题?

【问题讨论】:

  • 如果没有调用过程的合作,我认为这是不可行的。 Bash 没有超时;它是由启动 Bash 的进程处理的(我猜是 SSH,虽然我可能忽略了其他机制……如果你从 1980 年代开始在这里旅行,请使用 Telnet)。
  • @tripleee。 Bash 有超时,来自手册:TMOUT If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin. The select command terminates if input does not arrive after TMOUT seconds when input is coming from a terminal. In an interactive shell, the value is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.
  • 是的,没错,但我仍然相信您实际上在运行 Bash 的父进程中的会话层遇到了超时。
  • @tripleee:一点也不。没有采购traph.sh 不会发生超时。不涉及父进程。
  • 我查看了code in eval.c,它似乎并没有以任何方式区分exit 事件。它在内部使用SIGALRM,但trap '...' ALRM 对我没有任何用处(MacOS 上的 Bash 3.x)。

标签: linux bash audit


【解决方案1】:

第二次尝试

根据反馈,以前在 EXIT 上使用陷阱的解决方案效果不佳。替代方案,基于使用 PROMPT_COMMAND 似乎可以提供更好的里程数。

基本逻辑:

  • 捕获命令提示符时间 - 开始)
  • 在“退出”事件中,检查是否(现在开始)> TMOUT
  • 通常,退出、CTRL/D 等将在 1-2 秒内完成。
#! /bin/bash
function pre_cmd {
        START=$SECONDS
}

function log_exit {
    if [ "$((SECONDS-START-TMOUT))" -ge 0 ] ; then
       echo "TIMEOUT"
    else
       echo "Normal Exit"
    fi
}

TMOUT=15
PROMPT_COMMAND=pre_cmd
trap 'log_exit' EXIT

【讨论】:

  • 好主意!尝试并像魅力一样工作。还将 bash 进程的终止检测为“正常退出”(这对我来说很好)
【解决方案2】:

Distinguish between user logout and session expired logout (SSH and web console)

我发布的答案与我在那里发布的答案相同。

...

对于将有登录事件的正常会话,您可以在“退出”事件上设置陷阱。这将包括显式注销(CTRL/D 或退出)、被信号杀死(不是信号 9)和超时。寻找 bash 'trap' 命令。这些可以在 loginn 启动脚本 (bashrc) 中设置

编辑

可以通过检查“$?”获得“TIMEOUT”的指示在 TRAP 处理程序中。它将是 142 对应于 ALRM 信号(kill -l 142=ARLM)。这不是明确的文档,但与 kill -ALRM 的默认信号处理程序一致。

function my_trap {
  local X=$1
  if [ "$X" = "$(kill -l ALRM)" ] ; then
     Log Timeout
  else
     Log Exit/EOF
  fi
}

trap 'my_trap $?' EXIT

【讨论】:

  • 不幸的是,退出值始终为 0,无论是退出还是超时。通过采购您的实现并设置 TMOUT=10
  • 你是对的,我已经使用显式的“读取”语句(TMOUT=5 ; read ...)测试了代码,并且可以使用 $? 142.需要在提示符下测试超时
  • 如果您得到不同的结果,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 2011-01-11
  • 2015-10-10
  • 2011-03-24
相关资源
最近更新 更多