声明:

    以下的方法仅为了完成BOSS的任务,仅供参考。其中的一些文件、用户权限并不规范,而且每有一条命令执行,就会进行一次同步,请三思。



目的:

    通过修改/etc/profile,定制命令历史的格式、存储位置,使得每个用户每次登录系统的操作历史都会被记录到对应的文件中。并且将这些文件备份到远程服务器,防止篡改、删除。



步骤:

1、收集各个用户的历史记录

    修改/etc/profile,指定历史记录存储路径、格式等:

#history
USERIP=`who am i 2> /dev/null | awk '{print $NF}' | sed -e 's/[()]//g'`           #获取用户的登录IP
LOGNAME=`who am i 2> /dev/null | awk '{print $1}'`               #获取登录用户名
HISTDIR=/logs/.history                                #定义历史记录存储路径
if [ -z $USER_IP ]                     #如果没有获取到用户IP,则记录为hostname
  then
    USER_IP=`hostname`
fi
if [ ! -d $HISTDIR ]                   #当历史记录存储路径不存在时,在这里创建
  then
    mkdir -p $HISTDIR
    chmod 777 $HISTDIR
fi
if [ ! -d $HISTDIR/${LOGNAME} ]       #创建各个用户对应的存储路径 
  then
    mkdir -p $HISTDIR/${LOGNAME}
    chmod 300 $HISTDIR/${LOGNAME}
fi
DATETIME=`date +"%Y%m%d%H%M%S"`
export HISTFILE="$HISTDIR/${LOGNAME}/${DATETIME}.${USERIP}.history"       #定义历史记录文件
export HISTSIZE=10000                      #定义历史记录的最大条数
export HISTTIMEFORMAT="[%Y-%m-%d %H:%M:%S] "  #定义历史记录时间格式
chmod 300 $HISTDIR/${LOGNAME}/*.history* 2> /dev/null      #修改文件权限
export PROMPT_COMMAND='{ echo "$(pwd) $(history 1 | { read x cmd; echo "$cmd"; })"; } >> $HISTFILE'    #在第一条命令结束,第二条命令开始之前,将命令写入到历史记录文件

    问:这里为什么用“who am i”命令获取登录用户名?

    答:其实在初始的/etc/profile文件中,已经通过“USER="`/usr/bin/id -un`;LOGNAME=$USER”方式获取了用户名。这种方式获取的用户名是当前执行命令的用户名。

           而“who am i”则获取当前登录系统的用户名。如:使用test用户登录到系统,执行“who am i”获取到的就是“test”。即使通过su切换到root用户,再次执行“who am i”获取到的仍是“test”。


    执行source /etc/profile使更改生效:

[root@slave1 ~]# source /etc/profile


    达到的效果:

        各个用户都有对应的目录,该目录下的文件名定义为:"登录时间.登陆IP"。

[root@slave1 ~]# tree -pD /logs/.history/
/logs/.history/
├── [d-wx------ Jul  8 15:20]  root
│   ├── [--wx------ Jul  8 15:12]  20190708151107.192.168.1.38.history
│   ├── [--wx------ Jul  8 15:12]  20190708151248.192.168.1.38.history
│   ├── [--wx------ Jul  8 15:16]  20190708151331.192.168.1.38.history
│   ├── [--wx------ Jul  8 15:17]  20190708151609.192.168.1.38.history
│   ├── [--wx------ Jul  8 15:18]  20190708151714.192.168.1.38.history
│   └── [-rw-r--r-- Jul  8 15:33]  20190708151825.192.168.1.38.history
└── [d-wx------ Jul  8 15:31]  test
    └── [-rw-rw-r-- Jul  8 15:34]  20190708153159.192.168.1.38.history



2、特殊情况

    系统管理员为某些特权用户设定了sudo权限,这使得他们可以切换到root用户执行一些命令。

现象:

    假如在系统里存在一个“test”用户,设定了sudo权限,如下:

[root@slave1 ~]# visudo
test    ALL=(ALL)       NOPASSWD:ALL


    使用test用户登录系统,并切换到root用户,执行一些命令,并查看历史记录文件:

[test@slave1 ~]$ sudo bash
[root@slave1 test]# date
2019年 07月 08日 星期一 15:32:13 CST
[root@slave1 test]# cd
[root@slave1 ~]# cat /logs/.history/test/20190708153159.192.168.1.38.history
/home/test
/home/test [2019-07-08 15:32:04] sudo bash

    发现只有一条命令“sudo bash”被记录了。


原因:

    这种情况跟环境变量有关。

    当以test身份登录系统后,相关的变量如下:

[test@slave1 ~]$ set | grep -E -i '(logname|^his*)'
HISTCONTROL=ignoredups
HISTDIR=/logs/.history
HISTFILE=/logs/.history/test/20190708153159.192.168.1.38.history
HISTFILESIZE=10000
HISTSIZE=10000
HISTTIMEFORMAT='[%Y-%m-%d %H:%M:%S] '
LOGNAME=test


    当通过sudo bash方式切换到root身份时,相关的变量如下:

[root@slave1 ~]# set | grep -E -i '(logname|^hist*)'
HISTFILE=/root/.bash_history
HISTFILESIZE=10000
HISTSIZE=10000
LOGNAME=root

    所以,历史记录会被记录到/root/.bash_history文件中,而不是定义的/logs/.history/test/20190708153159.192.168.1.38.history文件。


解决方案:

    在sudoers文件里添加一行,使切换用户时保留当前用户的一些环境变量:

visudo
Defaults    env_keep += "HISTCONTROL HISTDIR HISTFILE HISTTIMEFORMAT LOGNAME PROMPT_COMMAND"


    修改之后,退出,再次查看环境变量:

[root@slave1 ~]# exit
exit
[test@slave1 ~]$ sudo bash
[root@slave1 test]# set | grep -E -i '(logname|^hist*)'
HISTCONTROL=ignoredups
HISTFILE=/logs/.history/test/20190708153159.192.168.1.38.history
HISTFILESIZE=10000
HISTSIZE=10000
HISTTIMEFORMAT='[%Y-%m-%d %H:%M:%S] '
LOGNAME=test



3、将保存的history文件同步到远程服务器

    在远程服务器master(192.168.1.204)上操作:

[root@master ~]# yum -y install rsync
[root@master ~]# vim /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = yes
max connections = 10
pid file = /var/run/rsyncd.pid
exclude = lost+found/
transfer logging = yes
timeout = 900
ignore nonreadable = yes
dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
address = 192.168.1.204
hosts allow = 192.168.1.202
[history]
       path = /logs
       read only = no
       write only = no
       auth users = rsync
       secrets file = /etc/rsync_users.db
[root@master ~]# mkdir /logs
[root@master ~]# chmod 777 /logs/
[root@master ~]# vim /etc/rsync_users.db
rsync:123123
[root@master ~]# chmod 600 /etc/rsync_users.db
[root@master ~]# /usr/bin/rsync --daemon
[root@master ~]# ps -ef | grep -v grep | grep rsync
root      6148     1  0 17:23 ?        00:00:00 /usr/bin/rsync --daemon


    在需要收集history的服务器slave1(192.168.1.202)上操作:

[root@slave1 ~]# yum -y install rsync inotify-tools
[root@slave1 ~]# vim /etc/server.pass
123123
[root@slave1 ~]# chmod 600 /etc/server.pass
[root@slave1 ~]# cd /logs/
[root@slave1 logs]# vim rsync.sh
#!/bin/bash
I_CMD="inotifywait -mrq -e modify,create /logs/.history"
R_CMD="rsync -azH /logs/.history [email protected]::history --password-file=/etc/server.pass"
$I_CMD | while read DIRECOTRY EVENT FILE
do
  $R_CMD
done
[root@slave1 logs]# sh rsync.sh

    好了,当slave1上有命令执行时,就会开始同步了。