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

一、应用场景

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

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

二、环境

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

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

三、搭建部署

服务器操作 : 192.168.30.72

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

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

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

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 - 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); } }

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 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 `/root/bash-4.1/po'

5、编译完成后,将新的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:0:0:root:/root:/usr/local/bash_new/bin/bash

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

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

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:09:b6:5f:db:55:1d:43:96:3d root@zhangsan The key's randomart image is: +--[ RSA 2048]----+ | oo| | oE.| | o.| | . o +| | o S .o. o| | o ..*o.o| | . . =...=| | ...=| | o.| +-----------------+

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

2、将公钥上传到服务器上的.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.

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:56:66:91:0c:6e:86:3b:90:19:42:9c:ab:9e:00:f6 root@lisi The key's randomart image is: +--[ RSA 2048]----+ | oo.. . | | o. + o o . | | .+ . + + | |... . + . | |o.. o S + | |o E . * | |o . o . | | o . | | | +-----------------+

4、上传公钥到服务器上

[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:92:ad:ae:ea:1b:fb:67: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.

5、现在去服务器上验证下该文件

[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

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

五、配置服务器

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

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

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

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

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

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

4、在/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 2>&1;}

5、修改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 ]

六、验证

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

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

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

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

七、结束

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

本文分享自微信公众号 - 马哥Linux运维(magedu-Linux)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

EntityFramework 连接数据库出错

本文转载:http://www.cnblogs.com/shuang121/archive/2012/03/19/2406121.html

16310
来自专栏潇涧技术专栏

Using Git with multiple Public Keys

很多时候,如果我们在多个网站有了Git账号,例如Github、GitCafe、CodingNet等,当我们与不同网站的代码库进行连接的时候可能会因为我们没有配置...

8620
来自专栏Brian

Emacs setup for Go Development

---- 概述 最近在我个人笔记本搭建Go开发环境,需要开发基于Go的一些业务模块,所以就把Go开发环境的配置记录下来。废话少说,直接上代码,嘿嘿! Emacs...

1.3K60
来自专栏云计算教程系列

如何使用Python-GnuPG和Python 3验证代码和加密数据

GnuPG包提供用于生成和存储加密密钥的完整解决方案。它还允许您加密和签名数据和通信。

87480
来自专栏运维一切

sentry部署整理 原

sentry是python开发的一个应用,使用python uWSG框架运行,所有安装完sentry要记得在nginx的代理上禁用掉/admin路径,不然uws...

30810
来自专栏cmazxiaoma的架构师之路

MyEclipse使用Git进行Push to Upstream报错 学习笔记

10920
来自专栏Linux驱动

Linux-kill命令(11)

kill:指定将信号发送给某个进程,常用来杀掉进程,可以通过ps、top命令来查看进程 在默认情况下: 采用编号为15的TERM信号。TERM信号将终止所有不能...

25450
来自专栏源码之家

去除word文档保护及去掉打开密码

81240
来自专栏python3

lsyncd实时同步工具

再后来sersync,这个是基于rsync的,需要有rsync客户端和服务端,比较麻烦

29240
来自专栏分布式系统和大数据处理

linux上配置ssh实现免密登录

当有多台服务器彼此进行通信时,可以通过使用ssh来免去输入密码的步骤。这篇文章将以两台服务器作为范例,演示如何通过ssh进行登录。

1.6K20

扫码关注云+社区

领取腾讯云代金券