一、为什么?

  在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度。不出问题还好,出了问题,就很难找出源头。

  这里介绍下,如何利用编译bash 使不同的客户端在使用root 登陆服务器使,记录各自的操作,并且可以在结合ELK 日志分析系统,来收集登陆操作日志

二、环境

  服务器:centos 6.5、Development tools、使用密钥认证,SElinux 关闭。

  客户端:生成密钥对,用于登录服务器 (2台)

三、搭建部署 (服务器操作 192.168.30.72)

3.1 下载编译bash

[root@open1 ~]# wget http://ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
[root@open1 ~]# tar xvf bash-4.1.tar.gz
[root@open1 ~]# cd bash-4.1

3.2 先修改下 config-top.c文件,大概94行、104行,由于c 语言中 注释是/**/ ,所以不要删除错了。修改如下:

[root@open1 bash-4.1]# vim config-top.c
#define SSH_SOURCE_BASHRC
#define SYSLOG_HISTORY

3.3 修改下bashhist.c 文件,让终端上的命令记录到系统messages 中,并且以指定的格式。并传入获得的变量。修改后的内容如下:

[root@open1 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 - ] = ' ';
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);
}
}

3.4 配置安装路径,编译安装,编译到/usr/local/目录下。

[root@open1 bash-4.1]# ./configure --prefix=/usr/local/bash_new
[root@open1 bash-4.1]# make && make install
...
if test "bash" = "gettext-tools"; then \
/bin/sh /root/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 ./$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[]: Leaving directory `/root/bash-4.1/po'

编译完成后,将新的bash 追加到 /etc/shells 中,并修改root用户的登陆shell 环境为新编译的shell。如下

[root@open1 bash-4.1]# echo "/usr/local/bash_new/bin/bash" >> /etc/shells
[root@open1 bash-4.1]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/usr/local/bash_new/bin/bash
[root@open1 bash-4.1]# vim /etc/passwd
root:x:::root:/root:/usr/local/bash_new/bin/bash

注销当前root用户,重新登陆后,查看/var/log/messages,如下就可以看到记录了操作命令

四、SSH客户端生成密钥部分

4.1 在client1上(192.168.30.99)操作,用户zhangsan

[root@rsyslog ~]# ssh-keygen -t rsa -C "root@zhangsan"
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:
c8:bd:5d:3b:a5:d9:6d::b6:5f:db::1d:::3d root@zhangsan
The key's randomart image is:
+--[ RSA ]----+
| oo|
| oE.|
| o.|
| . o +|
| o S .o. o|
| o ..*o.o|
| . . =...=|
| ...=|
| o.|
+-----------------+

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

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

[root@rsyslog ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.30.72
root@192.168.30.72's password:
Now try logging into the machine, with "ssh 'root@192.168.30.72'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.

4.3 client 2(192.168.30.71) 上同样的操作,用户lisi

[root@swift3 ~]# ssh-keygen -t rsa -C "root@lisi"
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:
8f::::0c:6e::3b::::9c:ab:9e::f6 root@lisi
The key's randomart image is:
+--[ RSA ]----+
| oo.. . |
| o. + o o . |
| .+ . + + |
|... . + . |
|o.. o S + |
|o E . * |
|o . o . |
| o . |
| |
+-----------------+

上传公钥到服务器上

[root@swift3 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.30.72
The authenticity of host '192.168.30.72 (192.168.30.72)' can't be established.
RSA key fingerprint is 8f:a7:1b:8d:e4::ad:ae:ea:1b:fb::0b:0b:7c:ac.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.30.72' (RSA) to the list of known hosts.
root@192.168.30.72's password:
Now try logging into the machine, with "ssh 'root@192.168.30.72'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.

4.4 现在去服务器上验证下该文件。

[root@open1 ~]# cat ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6fM+bpWEP3luauvOjmTB55ugUzVVMesmHCw4RNZ/C2e+KGXAYuxuAmEBbMcXQQj7OTAqVCQ0PWja58wReyZ7etiUGAtvoSBmSBpTPXteBMl40kDn4GdmXQ9UT/jnQ9gSZUQYJLMLJGWJks9S4xUI2cZ7oIytclrsUnKuOA1U6+luIJwJu9z7ya5OXh5FmmJQFnYtAEIhrLt4S8Ru5S00c0jiQCRk3RFlHYNc0IR02MXMH7d9bq7l04heAcT/y1EBS3EwINX8r0y6OridjJPCwxnm1sSfMKvLAbq/B+ufDjEOp7Y2SatL3qXaiP7NxdnhoJ4+Xar0zCoYi2A9oRGgUQ== root@zhangsan
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAupGSgXOWpQfzOVkHXYqN2BjMiAyaFRdKs6Wam3xGpMYRjZbIFX14kNR4CbrQtbUK8YonZPYdXG589blFmqF17sUPCNEqZEjCNer+yzDu+hYg/jAn4dCVtTBqUtBsTYUHSHIR0srruJ9keHNgU9aDRok8nulMUi/9Ej0NJZsBQ2npVNCf0YHgAd/ON5VsBYVLPvAT/cG3MuCjg5mgtU59qgAHyLKxkfpVc0/TRZ4eamX/1V0dsCxx9oYDbpn4YKLBAOaAS4kF6qEdrwRh0ssyWtWOo/CdyfLXKgwdbPtPfWZ63SM7wY7bAtcdxxu/QDkYVP+4oDfAtMxXZlY2bT5qMQ== root@lisi

现在上面两个客户端已经可以免密钥登陆了,现在去服务器上配置,并创建脚本。

五、配置服务器

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

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

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

[root@open1 ~]# cat /etc/CheckUser.sh
#!/bin/bash
#conding:utf-
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 == ]
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 -`
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

5.2 配置 profile,在文件末尾添加一行内容,如下:

[root@open1 ~]# echo "test -f /etc/CheckUser.sh && . /etc/CheckUser.sh" >> /etc/profile

在/etc/bashrc 末尾添加下面内容:

[root@open1 ~]# 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 >&;}

5.3 修改sshd 配置文件,开启debug 模式,并重启sshd 服务

[root@open1 ~]# sed -i 's/#LogLevel INFO/LogLevel DEBUG/g' /etc/ssh/sshd_config
[root@open1 ~]# service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]

六、验证

6.1 在client1 上进行登陆,并删除个文件试下(zhangsan)

6.2 在client2 上进行登陆,也删除个文件,并执行个重启服务的命令(lisi)

6.3 去服务器上查看下 messages 日志,内容如下

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

(注:上图第4段 swift1 是这台服务器的主机名,由于我只是运行了hostname 命令修改主机名,并没有修改networks,所以内核里还是之前的名字:swift1。)

七、结束

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

如有转载请注明出处,谢谢。

Linux 之不同运维人员共用root 账户权限审计的更多相关文章

  1. Linux运维人员共用root帐户权限审计

    Linux运维人员共用root帐户权限审计 2016-11-02 运维部落 一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还 ...

  2. Linux运维人员共用root帐户权限审计(转至马哥Linux运维)

    一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还好, 出了问题,就很难找出源头.这里介绍下,如何利用编译bash 使不同的客 ...

  3. (转)Linux企业运维人员常用的150个命令分享

    Linux企业运维人员常用的150个命令分享 原文:http://www.jb51.net/article/127014.htm 本文将向大家介绍Linux企业运维人员常用的150个命令,如有不足之处 ...

  4. [转帖]Linux企业运维人员最常用150个命令汇总

    Linux企业运维人员最常用150个命令汇总 https://clsn.io/clsn/lx998.html 基本上都用过了. 命令 功能说明 线上查询及帮助命令(2个) man 查看命令帮助,命令的 ...

  5. Linux运维人员如何学习python编程

    Linux运维人员如何学习python编程 从不会写代码,到自己独立能写代码解决问题 .这个问题很重要!盲目学习所谓的项目,最后 还是不会自己写代码解决问题.首先解决了独立能写代码解决问题,再通过项目 ...

  6. [转]2016年linux运维人员必会开源运维工具体系

    linux运维人员必会开源运维工具体系 说明:不同的技术人员,不同的阶段确定知识边界非常重要,否则,就像马拉车,不知道终点在哪,累死也达不到目标.例如拿8K要学多少,拿15K要学多少.一个新手也许只想 ...

  7. (转)2017年Linux运维人员必会开源运维工具体系

    标签:操作系统 中间件 千里马 Linux 技能 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51ct ...

  8. linux运维人员成长

    原文地址:https://blog.csdn.net/kwame211/article/details/78059331 初级篇 linux运维人员常用工具拓扑详见: 1rsync工具 很多地方经常会 ...

  9. Linux运维人员-服务器组成硬件基础

    第1章 1.1关于运维人员 1.1.1 运维的职责 数据不能丢 网站7*24小时运行 保证用户体验(用户体验要好) 1.1.2 运维原则 简单.易用.高效  === 简单.粗暴 1.2 服务器 1.2 ...

随机推荐

  1. (三) ffmpeg filter学习-编写自己的filter

    目录 目录 什么是ffmpeg filter 如何使用ffmpeg filter 1 将输入的1920x1080缩小到960x540输出 2 为视频添加logo 3 去掉视频的logo 自己写一个过滤 ...

  2. 循环中的let和const声明

    一.循环中的let声明 每次循环的时候let声明都会创建一个新变量i,并将其初始化为i的当前值,所以循环内部创建的每个函数都能得到属于他们的i的副本. 最初的: for (var i = 0 ; i ...

  3. oracle对三个列求sum

    oracle数据库对test_table表的三个列count1,count2,count3求sum的两种sql,做个记录 第一种 select sum (case when count1 is not ...

  4. 开源一款ftp软件——filezilla

    filezilla是一款高性能ftp/sftp文件工具,关于它的具体的介绍可参见其官网:https://www.filezilla.cn/.其原作者是Tim Kosse (tim.kosse@file ...

  5. python kd树 搜索 代码

    kd树就是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,可以运用在k近邻法中,实现快速k近邻搜索.构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,依次选择坐标轴对空间 ...

  6. chrome 55 zepto tap事件出错?

    刚才升级chrome后发现的,在54.0.2840.98上点击没有问题,在新升级的55.0.2883.75 上点击后会报错Cannot read property 'trigger' of undef ...

  7. OPEN(SAP) UI5 学习入门系列之四:更好的入门系列-官方Walkthrough

    好久没有更新了,实在不知道应该写一些什么内容,因为作为入门系列,实际上应该更多的是操作而不是理论,而在UI5 SDK中的EXPLORER里面有着各种控件的用法,所以在这里也没有必要再来一遍,还是看官方 ...

  8. JS监听键盘事件(回车键)

    JS监听某个输入框 //回车事件绑定 $('#search_input').bind('keyup', function(event) { if (event.keyCode == "13& ...

  9. 《selenium2 python 自动化测试实战》(12)——跳过验证码登录add_cookie

    微信公众号搜索“自动化测试实战”或扫描下方二维码添加关注~~~

  10. matlab中矩阵式子的不成熟理解

    matlab中的矩阵式的系统方式理解:一个矩阵式代表一个系统的作用,列代表输入,行代表输出,有多少列就有多少输入,有多少行就有多少输出,矩阵式的相加代表的是线性系统的叠加作用,矩阵式的相乘代表的是两个 ...