如何记录 ssh 客户端连接/命令?

如何记录 ssh 客户端连接/命令?

我想知道如何记录用户在服务器上使用的 SSH 命令行。例如,如果我的服务器上的用户 Alex 正在执行以下命令集:

$ cd /tmp
$ touch myfile
$ ssh [email protected]
$ ssh [email protected]
$ vim anotherfile
$ ssh [email protected]

我想将服务器上使用的 ssh 命令记录在一个文件中,如下所示:

[2014-07-25 10:10:10] Alex : ssh [email protected]
[2014-07-25 10:18:20] Alex : ssh [email protected]
[2014-07-25 11:15:10] Alex : ssh [email protected]

我不关心他在 ssh 会话期间做了什么,我只想知道他何时何地连接到另一台服务器。

用户没有使用 bash,而且我想避免操作 .bash_history,因为用户可以修改它。

对此有什么线索吗?

谢谢 :)

编辑:更具体地说:

一个用户连接到服务器 A,然后从服务器 A 连接到服务器 B。我想追踪他从服务器 A 通过 ssh 连接到哪个服务器。

答案1

在我看来,你可以用三种不同的方法来实现这一点 - 很可能还有许多其他方法可以实现这一点!最好的方法是将审计工具附加到内核 sysexec 调用,这样用户等就无法跟踪它了。另外两种方法就是修改 shell 环境来记录它。

我不会(从谷歌抓取代码/答案)向您展示如何做到这一点。我会给您提供已经详细解释过这一点的网站链接。我希望这正是您所需要的。

顺便说一句,迄今为止最简单的方法就是在主 bashrc/profile 中包含一些内容来影响所有用户。

无论如何,这里是 bashrc 解决方案的链接。

1)bashrc解决方案:如何记录Linux中所有用户执行的命令? 2)bashrc/trap解决方案:Bash:将历史记录保存到 Syslog

另一种方法(内核级)是查看工具 audit 或 acct。有许多网站会告诉您如何通过内核 sysexec 调用设置命令日志记录。

答案2

这是一个脚本,您可以使用它来捕获用户 ID 和其他信息,以便在启动 ssh 之前将其放入日志文件中。我使用几个非常复杂的多行 ssh 命令对其进行了测试。

#!/bin/bash

# Title......: ssh (wrapper)
# Description: this script replaces the ssh binary and runs the real binary after logging the connection attempt

# variables
#----------------------------------
REALBINARY=/usr/bin/sshu
THISHOST=$(uname -n)
LOGFILE=/var/log/sshclient.log
CALLINGPROC=$(ps -o comm= $PPID)

log() {  # creates a basic log entry; $LOGFILE must be defined
 echo "$(date '+%Y-%m%d %H:%M:%S %Z') $$  $*">>$LOGFILE
}

SSHTARGETOPTS=$(echo "$@" | head -1)
while getopts :l: OPT 2> /dev/null
do
 case "$OPT" in
  l) TARGETUSER="$OPTARG" ;;
 esac
done

#after parsing with getopts, OPTIND will be the positional parameter number of the first argument after the options
FIRSTARG=$(echo $SSHTARGETOPTS | awk "{print \$$OPTIND}")
#if there is an '@' symbol in the FIRSTARG, parse out the LOGIN and TARGETSERVER, if not, TARGETSERVER is FIRSTARG
if [[ "$FIRSTARG" =~ '@' ]] ; then
 TARGETUSER="${FIRSTARG%@*}"
 TARGETSERVER=${FIRSTARG##*@}
else
 TARGETSERVER="$FIRSTARG"
fi
TARGETUSER="${TARGETUSER:-$LOGNAME}"

if [[ "$SUDO_USER" ]] ; then
 log "$THISHOST CallingProc='$CALLINGPROC' SUDO_USER='$SUDO_USER' became LOGNAME='$LOGNAME' ssh to TARGETSERVER='$TARGETSERVER' as TARGETUSER='$TARGETUSER' with command '$0 $SSHTARGETOPTS'"
else
 log "$THISHOST CallingProc='$CALLINGPROC' LOGNAME='$LOGNAME' ssh to TARGETSERVER='$TARGETSERVER' as TARGETUSER='$TARGETUSER' with command '$0 $SSHTARGETOPTS'"
fi

exec $REALBINARY "$@"

答案3

查看 SSHLoghttps://github.com/sshlog/agent/

我是该项目的代码贡献者。

您可以使用此工具记录每个 ssh 会话(包括连接和断开连接)的日志条目。配置文件如下所示:

events:
  - event: ssh_connections_in
    triggers:
      - connection_established
      - connection_close
    filters:
      ignore_existing_logins: True
    actions:
      - action: log_events
        plugin: eventlogfile_action
        log_file_path: /var/log/ssh_connections_in.log
        max_size_mb: 10
        number_of_log_files: 5

  - event: ssh_connections_out
    triggers:
      - command_start
    filters:
      command_name: ssh
    actions:
      - action: log_events
        plugin: eventlogfile_action
        log_file_path: /var/log/ssh_connections_out.log
        max_size_mb: 10
        number_of_log_files: 5

这将在 /var/log/ 中创建两个日志文件

第一个日志文件将在用户登录服务器时写入事件。第二个日志文件将在用户执行“ssh”命令时写入事件,其中包括传递的任何参数(即它连接到哪个服务器)。

您可以在这里找到其他配置选项: https://github.com/sshlog/agent/tree/master/daemon/config_samples

答案4

最明显的、与 shell 无关的方法是用执行所需日志记录的包装脚本/程序替换 ssh,然后执行 ssh。

使用包装程序意味着用户使用什么 shell 并不重要(是的,除了 bash 之外还有其他 shell!),并且来自其他程序(例如 emacs、vi、mailx 等)的“shell 转义”也将被记录。

相关内容