介绍linux下利用编译bash设置root账号共用的权限审计设置

在日常运维工作中,公司不同人员(一般是运维人员)共用root账号登录linux服务器进行维护管理,在不健全的账户权限审计制度下,一旦出现问题,就很难找出源头,甚是麻烦!
在此,介绍下利用编译bash使不同人员在使用root账号登陆服务器后,能记录各自的操作,并且可以结合ELK日志分析系统收集登陆操作日志

废话不多说!下面分享下操作记录:

服务器ip:192.168.1.180

首先是编译bash
[root@dev ~]# cd /usr/local/src/
[root@dev src]# wget http://ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
[root@dev src]# tar -zvxf bash-4.1.tar.gz

先修改下config-top.h文件,大概91行、104行,由于c 语言中注释是/* */ ,所以不要删除错了!删除下面第91和104行内容前后的/* */注释符!
确保修改如下:
[root@dev bash-4.1]# vim config-top.h
......
91   #define SSH_SOURCE_BASHRC
......
104 #define SYSLOG_HISTORY

修改下bashhist.c 文件,让终端上的命令记录到系统messages 中,并且以指定的格式。并传入获得的变量。
确保下面的内容修改后如下:
[root@dev bash-4.1]# vim bashhist.c
......
void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
const char *p;
p = getenv("NAME_OF_KEY");
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d PPID=%d SID=%d User=%s USER=%s CMD=%s", getpid(), getppid(), getsid(getpid()), current_user.user_name, p, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = ' ';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d PPID=%d SID=%d User=%s USER=%s CMD=%s", getpid(), getppid(), getsid(getpid()), current_user.user_name, p, trunc);
}
}

接着继续编译安装,编译到/usr/local/目录下。

[root@dev bash-4.1]# ./configure --prefix=/usr/local/bash_new
[root@dev bash-4.1]# make && make install
...............
if test "bash" = "gettext-tools"; then \
/bin/sh /usr/local/src/bash-4.1/./support/mkinstalldirs /usr/local/bash_new/share/gettext/po; \
for file in Makefile.in.in remove-potcdate.sin quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot Makevars.template; do \
/usr/bin/install -c -m 644 ./$file \
/usr/local/bash_new/share/gettext/po/$file; \
done; \
for file in Makevars; do \
rm -f /usr/local/bash_new/share/gettext/po/$file; \
done; \
else \
: ; \
fi
make[1]: Leaving directory `/usr/local/src/bash-4.1/po'

[root@dev bash-4.1]# ll /usr/local/bash_new/bin/
总用量 2784
-rwxr-xr-x 1 root root 2838951 10月 17 18:44 bash
-r-xr-xr-x 1 root root 6837 10月 17 18:44 bashbug

编译完成后,追加新的bash到/etc/shells 中,并修改root用户的登陆shell环境为新编译的shell。
如下:
[root@dev bash-4.1]# echo "/usr/local/bash_new/bin/bash" >> /etc/shells
[root@dev bash-4.1]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
/usr/local/bash_new/bin/bash
[root@dev bash-4.1]#

替换root账号的bash环境

[root@dev bash-4.1]# cat /etc/passwd|grep "root:/root"
root:x:0:0:root:/root:/bin/bash
[root@dev bash-4.1]# sed -i 's#root:/root:/bin/bash#root:/root:/usr/local/bash_new/bin/bash#g' /etc/passwd
[root@dev bash-4.1]# cat /etc/passwd|grep "root:/root"
root:x:0:0:root:/root:/usr/local/bash_new/bin/bash

注销当前root用户,重新登陆后,查看/var/log/messages,如下就可以看到记录了操作命令:
[root@dev bash-4.1]# who
root tty1 2016-09-27 23:16 (:0)
root pts/0 2016-10-17 19:11 (192.168.9.155)
[root@dev bash-4.1]# pkill -kill -t pts/0

重新登录该机器,查看/var/log/messages,如下就可以看到记录了操作命令。
下面第4段dev -bash是这台服务器的主机名。这样以后就能根据messages文件里的日志信息,知道这台机器在root账号下的所有操作了!
[root@dev ~]# tail -2f /var/log/messages
Oct 17 19:12:46 dev -bash: HISTORY: PID=7718 PPID=7716 SID=7718 User=root USER=(null) CMD=pkill -kill -t pts/0
Oct 17 19:13:30 dev -bash: HISTORY: PID=7864 PPID=7862 SID=7864 User=root USER=(null) CMD=tail -2f /var/log/messages

-----------------------------------------------------------------------------

下面开始进行客户端的配置:

两台客户机:
elk-node1和elk-node2,两台客户机上分别生成root用户下的公私钥,生成公私钥时最好-C加上用户名,以便于辨别!
客户机elk-node1的用户名是wangshibo,ip是192.168.1.160
客户机elk-node2的用户名是guohuihui,ip是192.168.1.161

1)客户机elk-node1上操作。注意:-C 后面的辨别参数也可以用ip,比如-C “root@192.168.1.160",只是为了ssh远程登录后能识别来源
[root@elk-node1 ~]# ssh-keygen -t rsa -C "root@wangshibo"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
a9:a4:cc:3b:99:bf:68:a7:3d:fd:19:ef:f9:dd:2a:07 root@wangshibo
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| . |
| . S |
| o o . E |
| +o.. . . |
| =+o . +.....|
| .+=+o .o.++o.o|
+-----------------+

将公钥上传到上面的机器192.168.1.180上
[root@elk-node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.180
The authenticity of host '192.168.1.180 (192.168.1.180)' can't be established.
RSA key fingerprint is 3e:62:70:61:c1:90:ce:f3:25:85:28:f9:e1:86:dc:ac.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.180's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'root@192.168.1.180'"
and check to make sure that only the key(s) you wanted were added.

--------------------------------------------------------------------------------
-t 加密算法
-C 注释 (加上这个也是为了最后进行对服务器访问人员进行辨别的一个关键点)

将公钥上传到服务器上的.ssh/authorized_keys 文件中。
ssh-copy-id 命令会自动在服务器上创建.ssh/authorized_keys文件,即使该目录不存在,并自动赋予600权限。
--------------------------------------------------------------------------------

测试,已经可以无密码登陆了~
[root@elk-node1 ~]# ssh root@192.168.1.180
Last login: Mon Oct 17 19:42:58 2016 from 192.168.1.7
[root@dev ~]#

2)客户机elk-node2上操作:
[root@elk-node2 ~]# ssh-keygen -t rsa -C "root@guohuihui"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
fe:ac:7c:3e:05:4d:c1:86:f0:30:6b:a6:8e:b6:d6:22 root@guohuihui
The key's randomart image is:
+--[ RSA 2048]----+
| +. o.. |
| =. + |
| + .+ |
| + . . |
| . S . |
| o . . |
| o.. . . |
| E.o... oo |
| o.. o++. |
+-----------------+

将公钥上传到上面的机器192.168.1.180上
[root@elk-node2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.180
The authenticity of host '192.168.1.180 (192.168.1.180)' can't be established.
RSA key fingerprint is 3e:62:70:61:c1:90:ce:f3:25:85:28:f9:e1:86:dc:ac.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.180's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'root@192.168.1.180'"
and check to make sure that only the key(s) you wanted were added.

测试,已经可以无密码登陆了~
[root@elk-node2 ~]# ssh root@192.168.1.180
Last login: Mon Oct 17 19:52:02 2016 from 192.168.1.160
[root@dev ~]#

3)登陆到192.168.1.180上查看
[root@dev ~]# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3BA2e9bJDGfn80IYKn0RypviBYzYm7lpfexD8nneZ2p6Cd+7Y4xVxqqzemKj4/NB2ak8YGzvUV2kdhu53x9MTRNk03S+Cz1gbK8OzIoXF8qJmWg34Cf8pZDMkzYyTFlt1oc+meKMI1eZjTsOekosmiHj9nGXbe62BWpRY0syRDpdVUWyNhQs1nn37Cwlwy74eJLida1bvKsGSDs1/wjhtl59YtOOLOveitCurQRosxZrA/jsB7kGT8IENkEdI7JTIrHpAIhmGzpKVUP0g8CS5fox0NImem3c0qp2sJz5tLztnAjA+MTJCopI0XzWiYtsoIEbLZtjObvtoBrDMd6uaQ== root@localhost.localdomain
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZIR4RDrioJtBLXDCU2P4AhhzY4erpuWQ5cOKEIB6AAZ2qF3HtcvrhWofF+sJJBaEsEaGo2eV9NY2nVJmr2VhWzb0t2brh21PHCAKKT/qOtllgEY6T9EVoIaYfLuybGFxSNERmCSCs61yOxRvOdcSrdymM0o1OMzQICLjESLVPg0drhAhePvXFNFW+9BZwbnzhkh9jJTY6Lsi44QgDFUKFzAfXtUlPtAbeLYPmSvdXtcT1LRR80Fp+/z3U4FZ7EYX6bFFySkp1HIkGZF87MuM/ndjMHDBqc1FQdORltkT41AjWqoW8Ak8TWzgXMGp0v6JfqCYW+HjmIX4JDJ9mUB+D root@wangshibo
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdY1F1LQH7FTX6cnrvli+O1RIk67BT60PiCR3k7xuQxfBYqE7C1FNLKjlbDXceenU4WleZqVB9n008E7cpm+BR2l9uDUay9jKg3OQej/270emRA3dWUtsW9P3d/66LEVBMQjBgh0XNUsfDhctAwJSsXhxacwKyou1/2tsudFmeSaHqEgOyeFLdKWf76XV5tErzUnws2AOKjM8HOrctyECjajSHS9IhUJaYrY7vePMNZBCbK401iI1lEqb4TQ+j/SdVOrFo6qMPYaFHwyYiv7kYCt7r1SQlwkpnrMr8V88ZFC1pa8ZPiPEyfii9HoMyID2VVUl3G+pas9NRkJ+6Bd+T root@guohuihui

在log目录下创建一个 keys 文件,用于登陆时存进去公钥,之后对其进行取出判断的

[root@dev ~]# touch /var/log/keys

创建检测脚本,内容如下:

[root@dev ~]# cat /etc/CheckUser.sh
#!/bin/bash
#conding:utf-8
pid=$PPID
#在自己home目录得到所有的key,如果/var/log/keys 没有的时候,添加进去
while read line
do
grep "$line" /var/log/keys >/dev/null || echo "$line" >> /var/log/keys
done < $HOME/.ssh/authorized_keys
#得到每个key的指纹
cat /var/log/keys | while read LINE
do
NAME=$(echo $LINE | awk '{print $3}')
echo $LINE >/tmp/keys.log.$pid
KEY=$(ssh-keygen -l -f /tmp/keys.log.$pid | awk '{print $2}')
grep "$KEY $NAME" /var/log/ssh_key_fing >/dev/null || echo "$KEY $NAME" >> /var/log/ssh_key_fing
done
#如果是root用户,secure文件里面是通过PPID号验证指纹
if [ $UID == 0 ]
then
ppid=$PPID
else
#如果不是root用户,验证指纹的是另外一个进程号
ppid=`/bin/ps -ef | grep $PPID |grep 'sshd:' |awk '{print $3}'`
fi
#得到RSA_KEY和NAME_OF_KEY,用来bash4.1得到历史记录
RSA_KEY=`/bin/egrep 'Found matching RSA key' /var/log/secure | /bin/egrep "$ppid" | /bin/awk '{print $NF}' | tail -1`
if [ -n "$RSA_KEY" ];then
NAME_OF_KEY=`/bin/egrep "$RSA_KEY" /var/log/ssh_key_fing | /bin/awk '{print $NF}'`
fi
#把NAME_OF_KEY设置为只读
readonly NAME_OF_KEY
export NAME_OF_KEY
/bin/rm /tmp/keys.log.$pid

配置 profile,在文件末尾添加一行内容,如下:
[root@dev ~]# echo "test -f /etc/CheckUser.sh && . /etc/CheckUser.sh" >> /etc/profile

在/etc/bashrc 末尾添加下面内容:
[root@dev ~]# tail -1f /etc/bashrc
test -z "$BASH_EXECUTION_STRING" || { test -f /etc/CheckUser.sh && . /etc/CheckUser.sh; logger -t -bash -s "HISTORY $SSH_CLIENT USER=$NAME_OF_KEY CMD=$BASH_EXECUTION_STRING " >/dev/null 2>&1;}

修改sshd 配置文件,开启debug 模式,并重启sshd 服务
[root@dev ~]# sed -i 's/#LogLevel INFO/LogLevel DEBUG/g' /etc/ssh/sshd_config
[root@dev ~]# service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]

-----------------------------------------------------
最后验证下:
从两台客户机跳转到192.168.1.180上的操作是否能如实记录下来!

1)从客户机elk-node1上登陆192.168.1.180,并进行操作:
[root@elk-node1 ~]# ssh root@192.168.1.180
Last login: Mon Oct 17 19:55:29 2016 from 192.168.1.161
[root@dev ~]# touch /root/wangshibo
[root@dev ~]# echo 123 > /root/wangshibo
[root@dev ~]#

2)从客户机elk-node2上登陆192.168.1.180,并进行操作:
[root@elk-node2 ~]# ssh root@192.168.1.180
Last login: Mon Oct 17 20:04:53 2016 from 192.168.1.160
[root@dev ~]# rm -f /root/wangshibo
[root@dev ~]# /etc/init.d/sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]
[root@dev ~]#

3)去192.168.1.180服务器上,查看/var/log/messages日志,发现两台客户机登陆后的操作已经如实记录下来了!
[root@dev ~]# tail -f /var/log/messages
Oct 17 19:54:00 dev -bash -bash: HISTORY 192.168.1.161 38886 22 USER= CMD=#012#011#011exec sh -c 'umask 077; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1; if type restorecon >/dev/null 2>&1; then restorecon -F .ssh .ssh/authorized_keys; fi'
Oct 17 19:55:35 dev -bash -bash: HISTORY: PID=12919 PPID=12916 SID=12919 User=root USER=root@guohuihui CMD=cat /root/.ssh/authorized_keys
Oct 17 20:00:28 dev -bash -bash: HISTORY: PID=12582 PPID=12579 SID=12582 User=root USER=root@localhost.localdomain CMD= cat /etc/CheckUser.sh
Oct 17 20:01:47 dev -bash -bash: HISTORY: PID=12582 PPID=12579 SID=12582 User=root USER=root@localhost.localdomain CMD=cat /etc/profile
Oct 17 20:02:15 dev -bash -bash: HISTORY: PID=12582 PPID=12579 SID=12582 User=root USER=root@localhost.localdomain CMD=cat /etc/bashrc
Oct 17 20:04:58 dev -bash -bash: HISTORY: PID=13000 PPID=12997 SID=13000 User=root USER=root@wangshibo CMD=touch /root/wangshibo
Oct 17 20:05:04 dev -bash -bash: HISTORY: PID=13000 PPID=12997 SID=13000 User=root USER=root@wangshibo CMD=echo 123 > /root/wangshibo
Oct 17 20:06:04 dev -bash -bash: HISTORY: PID=13066 PPID=13063 SID=13066 User=root USER=root@guohuihui CMD=rm -f /root/wangshibo
Oct 17 20:06:13 dev -bash -bash: HISTORY: PID=13066 PPID=13063 SID=13066 User=root USER=root@guohuihui CMD=/etc/init.d/sshd restart
Oct 17 20:07:20 dev -bash -bash: HISTORY: PID=12582 PPID=12579 SID=12582 User=root USER=root@localhost.localdomain CMD=tail -f /var/log/messages

如上,可以看出,不通用户的客户端通过公钥登陆的方式,分辨出了谁操作了什么,什么时候操作的。

通过这种方式,能极大的解决了多root用户登陆操作后无法审计的问题。
另外可以结合日志转发,将系统日志转发到其它服务器,即使主机被黑了,也能具体的审查登陆时间以及做了哪些操作。

上一篇:curl传输数据时遇到的问题整理


下一篇:chmod、acl权限