需求:linux系统中,将操作指令记录在日志文件中
1 .在 /etc/profile 中添加以下内容
mkdir -m 777 -p /.cmdlog 2>&-
export CMDLOG_FILE="/.cmdlog/cmdlog.$(date +%F)"
[ -f $CMDLOG_FILE -a -s $CMDLOG_FILE ] || install -m 777 /dev/null $CMDLOG_FILE 2>&-
LOGIN_TIMESTAMP=`date +%s`
export PROMPT_COMMAND='{ date "+%F %T ### $(whoami)@${SSH_TTY} ### $(echo ${SSH_CONNECTION}) ### ${PWD} ### $LOGIN_TIMESTAMP ### $(history 1|awk "{\$1=\"\";print}") "; } 2>&- >> $CMDLOG_FILE'
执行:source /etc/profile
2 .输出结果如下:
注意:linux部分系统中,通过su切换用户后,SSH_CONNECTION变量将无法获取到,因此将影响对于连接服务器的源IP和目的IP的获取,改造的采集方法如下:
新方案
mkdir -m 777 -p /.cmdlog 2>&-
declare -r HISTTIMEFORMAT='%F %T ### '
declare -r SSHTTY=$(who am i |awk '{print $2}')
if [ "$SSH_CONNECTION" ];then
declare -r SSH_CLIENTIP=$(echo $SSH_CONNECTION |awk '{ print $1}')
declare -r SSH_HOSTIP=$(echo $SSH_CONNECTION |awk '{ print $3}')
else
declare -r SSH_CLIENTIP=$(who am i|awk '{print $5}' |sed 's/[()]//g')
declare -r SSH_HOSTIP=$(ip addr | grep inet| grep -v 127.0.0.1 | grep -v inet6 |grep -v virbr| head -n 1 | awk -F/ '{print $1}' | awk '{print $2}')
fi
declare -r CMDLOG_FILE="/.cmdlog/cmdlog.$(date +%F)"
[ -f $CMDLOG_FILE -a -s $CMDLOG_FILE ] || install -m 777 /dev/null $CMDLOG_FILE 2>&-
declare -r LOGIN_TIMESTAMP=`date +%s`
declare -r PROMPT_COMMAND='{ date "+%F %T ### ${HOSTNAME} ### ${USER} ### ${SSHTTY} ### ${SSH_CLIENTIP} ### ${SSH_HOSTIP} ### ${SSH_CONNECTION} ### ${PWD} ### $LOGIN_TIMESTAMP ###$(history 1|awk "{\$1=\"\";print}") "; } 2>&- >> $CMDLOG_FILE'
注意:
- declare -r :声明变量为只读变量,防止被人误重写
- history日志格式中增加了指令操作时间
解决回车时记录重复操作
mkdir -m 777 -p /.cmdlog 2>&-
declare -r HISTTIMEFORMAT='%F %T ### '
declare -r HISTCONTROL=''
RSSHTTY=$(who am i |awk '{print $2}')
if [ "$SSH_CONNECTION" ];then
RSSH_CLIENTIP=$(echo $SSH_CONNECTION |awk '{ print $1}')
RSSH_HOSTIP=$(echo $SSH_CONNECTION |awk '{ print $3}')
else
RSSH_CLIENTIP=$(who am i|awk '{print $5}' |sed 's/[()]//g')
RSSH_HOSTIP=$(ip addr | grep inet| grep -v 127.0.0.1 | grep -v inet6 |grep -v virbr| head -n 1 | awk -F/ '{print $1}' | awk '{print $2}')
fi
RCMDLOG_FILE="/.cmdlog/cmdlog.$(date +%F)"
[ -f $RCMDLOG_FILE -a -s $RCMDLOG_FILE ] || install -m 777 /dev/null $RCMDLOG_FILE 2>&-
RLOGIN_TIMESTAMP=`date +%s`
rsprompt_command() {
RHISTCMD_PREV=$(history 1)
if [ "$RHISTCMD_BEFORE_LAST" != "$RHISTCMD_PREV" ]; then
{ date "+%F %T ### ${HOSTNAME} ### ${USER} ### ${RSSHTTY} ### ${RSSH_CLIENTIP} ### ${RSSH_HOSTIP} ### ${SSH_CONNECTION} ### ${PWD} ### $RLOGIN_TIMESTAMP ###$(history 1|awk "{\$1=\"\";print}")"; } 2>&- >> $RCMDLOG_FILE
fi
RHISTCMD_BEFORE_LAST=$RHISTCMD_PREV
}
declare -r PROMPT_COMMAND='rsprompt_command'
注意:上述方法为判断当前操作获取到的操作内容和上次操作是否一样,若一样,说明不是新操作指令,则不记录;
解决新客户端连接时会自动重复记录上次退出时的操作
思路:日志中会记录客户端连接的时间,如果发现指令操作时间比登录时间早,则说明此条指令记录是之前的,不予记录到日志中
mkdir -m 777 -p /.cmdlog 2>&-
declare -r HISTTIMEFORMAT='%F %T ### '
declare -r HISTCONTROL=''
RSSHTTY=$(who am i |awk '{print $2}')
if [ "$SSH_CONNECTION" ];then
RSSH_CLIENTIP=$(echo $SSH_CONNECTION |awk '{ print $1}')
RSSH_HOSTIP=$(echo $SSH_CONNECTION |awk '{ print $3}')
else
RSSH_CLIENTIP=$(who am i|awk '{print $5}' |sed 's/[()]//g')
RSSH_HOSTIP=$(ip addr | grep inet| grep -v 127.0.0.1 | grep -v inet6 |grep -v virbr| head -n 1 | awk -F/ '{print $1}' | awk '{print $2}')
fi
RCMDLOG_FILE="/.cmdlog/cmdlog.$(date +%F)"
[ -f $RCMDLOG_FILE -a -s $RCMDLOG_FILE ] || install -m 777 /dev/null $RCMDLOG_FILE 2>&-
RLOGIN_TIMESTAMP=`date +%s`
rsprompt_command() {
RHISTCMD_PREV=$(history 1);RACTIONDATE=$(history 1|awk '{print $2" "$3}');RACTIONTIME=$(date -d "$RACTIONDATE" +%s)
if [ "$RHISTCMD_BEFORE_LAST" != "$RHISTCMD_PREV" ] && [ "$RACTIONTIME" -ge "$RLOGIN_TIMESTAMP" ]; then
{ date "+%F %T ### ${HOSTNAME} ### ${USER} ### ${RSSHTTY} ### ${RSSH_CLIENTIP} ### ${RSSH_HOSTIP} ### ${SSH_CONNECTION} ### ${PWD} ### $RLOGIN_TIMESTAMP ###$(history 1|awk "{\$1=\"\";print}")"; } 2>&- >> $RCMDLOG_FILE
fi
RHISTCMD_BEFORE_LAST=$RHISTCMD_PREV
}
declare -r PROMPT_COMMAND='rsprompt_command'