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


                                                                                一、应用场景                                                                                      

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

    出了问题,就很难找出源头。这里介绍下,如何利用编译bash 使不同的客户端在使用root 登陆服务器使,记录各自的操作,

    并且可以在结合ELK 日志分析系统,来收集登陆操作日志 

                                                                                 二、环境                                                                

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

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

                                                                                三、搭建部署                                                                             

    服务器操作 : 192.168.30.721

    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

    4、去服务器上验证下该文件

    [root@open1 ~]# cat ~/.ssh/authorized_keys

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

                                                                           五、配置服务器                                                                           

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

    4、修改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 用户登陆操作,无法审计的问题。并且可以结合日志转发,将系统日志转发到其它服务器,即使主机被黑了,也能具体的审查登陆时间以及做了哪些操作。

  • 相关阅读:
    hdu 1325 判断有向图是否为树
    poj 1182
    Ubuntu 系统 文件操作命令
    vim 快捷键大全
    Git 上传本地命令
    git错误:fatal: Not a git repository (or any of the parent directories): .git
    Git 如何回到过去,然后 再 回到将来
    Git 提供篇
    Linux 的cp命令
    Linux :: vi E212: Can't open file for writing
  • 原文地址:https://www.cnblogs.com/chenjiahe/p/6054578.html
Copyright © 2020-2023  润新知