我想知道如何记录用户在服务器上使用的 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 转义”也将被记录。