编译bash通过Rsyslog记录执行命令日志,并将日志发送到Elastic Stack,实现history审计

此前考虑通过PROMPT_COMMAND环境变量实现history审计,后来发现存在各种问题,就如使用su切换用户时,前后执行的命令不能被准确记录。

看了许多文章,最终找到一种相对完善的处理方法,就是通过编译bash,由Rsyslog记录执行命令日志。之后配置实时将日志数据输出到Elastic Stack,在Kibana上可以监控终端上执行的每一条命令,或对日志数据作分析和审计。

编译安装bash

[root@centos76d77 10:36 ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core) 
[root@centos76d77 10:38 ~]# uname -r
3.10.0-957.el7.x86_64

[root@centos76d77 10:38 ~]# wget http://mirrors.aliyun.com/centos-vault/\
7.6.1810/os/Source/SPackages/bash-4.2.46-31.el7.src.rpm
# 下载bash 4.2的SRC RPM包
# 据说bash 4.1以上版本都支持Rsyslog记录执行命令日志

[root@centos76d77 11:32 ~]# rpm -ivh bash-4.2.46-31.el7.src.rpm
....
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
# 安装,会有许多警告提示,没有关系

[root@centos76d77 11:35 ~]# cd rpmbuild/SOURCES/
[root@centos76d77 11:36 ~/rpmbuild/SOURCES]# ls bash-4.2.tar.gz 
bash-4.2.tar.gz
[root@centos76d77 11:36 ~/rpmbuild/SOURCES]# tar zxvf bash-4.2.tar.gz
[root@centos76d77 11:37 ~/rpmbuild/SOURCES]# cp -a bash-4.2{,-orig}

[root@centos76d77 11:37 ~/rpmbuild/SOURCES]# cd bash-4.2
[root@centos76d77 11:37 ~/rpmbuild/SOURCES/bash-4.2]# vim bashhist.c
....
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s \
Cmd=%s", getpid(), current_user.uid, current_u ser.user_name, line);
....
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s \
Cmd=%s", getpid(), current_user.uid, current _user.user_name, trunc);
# 修改第712和717行

[root@centos76d77 11:44 ~/rpmbuild/SOURCES/bash-4.2]# vim config-top.h
#define SYSLOG_HISTORY
# 解注释第104行
# define SYSLOG_FACILITY LOG_LOCAL6
# define SYSLOG_LEVEL LOG_NOTICE
# 修改syslog的FACILITY为 LOCAL6,日志级别为NOTICE

[root@centos76d77 11:50 ~/rpmbuild/SOURCES/bash-4.2]# cd ..
[root@centos76d77 11:50 ~/rpmbuild/SOURCES]# diff -Npru bash-4.2-orig bash-4.2 > bash_history_syslog.patch
# 制作patch

[root@centos76d77 11:50 ~/rpmbuild/SOURCES]# cd ../SPECS/
[root@centos76d77 11:53 ~/rpmbuild/SPECS]# vim bash.spec
Patch155: bash_history_syslog.patch
....
%patch155 -p1 -b .history_syslog
# 按照格式顺序,加入以上两行

[root@centos76d77 12:00 ~/rpmbuild/SPECS]# yum -y install rpm-build
[root@centos76d77 12:01 ~/rpmbuild/SPECS]# yum -y groups install "Development Tools"
# 安装rpm-build和Development Tools

[root@centos76d77 12:03 ~/rpmbuild/SPECS]# rpmbuild -ba bash.spec
warning: bogus date in %changelog: Wed Jul 24 2014 Ondrej Oprala <[email protected] - 4.2.46-4
warning: bogus date in %changelog: Thu Jun 18 2014 Ondrej Oprala <[email protected] - 4.2.46-1
warning: bogus date in %changelog: Thu May 26 2006 Tim Waugh <[email protected]> 3.1-13
warning: bogus date in %changelog: Tue Mar 26 2003 Tim Waugh <[email protected]> 2.05b-23
warning: bogus date in %changelog: Fri May5 2001 Bernhard Rosenkraenzer <[email protected]> 2.05-4
warning: bogus date in %changelog: Wed Feb 22 2001 Harald Hoyer <[email protected]>
warning: bogus date in %changelog: Fri Sep 14 1999 Dale Lovelace <[email protected]>
error: Failed build dependencies:
      texinfo is needed by bash-4.2.46-31.el7.x86_64
      ncurses-devel is needed by bash-4.2.46-31.el7.x86_64
# 提示缺少texinfo和ncurses-devel
[root@centos76d77 12:06 ~/rpmbuild/SPECS]# yum -y install texinfo ncurses-devel
# 缺什么装什么,解决依赖关系问题

[root@centos76d77 12:07 ~/rpmbuild/SPECS]# rpmbuild -ba bash.spec
# 再次执行rpmbuild,创建RPM程序包
# 此后,可以将该RPM程序包放置到私有Repo中,方便批量部署
....
Wrote: /root/rpmbuild/RPMS/x86_64/bash-debuginfo-4.2.46-31.el7.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.dlpDJQ
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd bash-4.2
+ rm -rf /root/rpmbuild/BUILDROOT/bash-4.2.46-31.el7.x86_64
+ exit 0
# 看到“exit 0”,说明程序包制作完成

[root@centos76d77 12:14 ~/rpmbuild/SPECS]# cd ../RPMS/x86_64/
[root@centos76d77 12:14 ~/rpmbuild/RPMS/x86_64]# ls
bash-4.2.46-31.el7.x86_64.rpm    bash-debuginfo-4.2.46-31.el7.x86_64.rpm
bash-doc-4.2.46-31.el7.x86_64.rpm

[root@centos76d77 12:14 ~/rpmbuild/RPMS/x86_64]# rpm -Uvh --force bash-4.2.46-31.el7.x86_64.rpm
Preparing...                    ################################# [100%]
Updating / installing...
   1:bash-4.2.46-31.el7         ################################# [100%]
# 强制升级安装修改好的bash

配置Rsyslog

# 先在本机测试
[root@centos76d77 12:16 ~/rpmbuild/RPMS/x86_64]# cd
[root@centos76d77 12:20 ~]# touch /var/log/bash.log

[root@centos76d77 12:20 ~]# vim /etc/rsyslog.conf
local6.notice                /var/log/bash.log
# 添加rules,记录local6 facility的notice以上级别的日志到/var/log/bash.log

[root@centos76d77 12:30 ~]# systemctl restart rsyslog.service
[root@centos76d77 12:34 ~]# tail -f /var/log/bash.log

# 再打开一个终端
# 随便输几个命令试一下
[root@centos76d77 12:34 ~]# pwd
[root@centos76d77 12:34 ~]# ls
[root@centos76d77 12:35 ~]# w
[root@centos76d77 12:35 ~]# echo "hahaha"

# 返回原来的终端,可以看到相应的输出
Jun 6 12:34:39 localhost -bash: PID=50648 UID=0 User=root Cmd=pwd
Jun 6 12:35:51 localhost -bash: PID=50648 UID=0 User=root Cmd=ls
Jun 6 12:35:53 localhost -bash: PID=50648 UID=0 User=root Cmd=w
Jun 6 12:36:01 localhost -bash: PID=50648 UID=0 User=root Cmd=echo "hahaha"

[root@centos76d77 12:38 ~]# vim /etc/rsyslog.conf
*.info;mail.none;authpriv.none;cron.none                 /var/log/messages
local6.notice                                            /var/log/bash.log
# 分别修改上面两行为:
*.info;mail.none;authpriv.none;cron.none;local6.none;    /var/log/messages
local6.notice                                            @192.168.1.93:3514
# 配置将bash执行命令日志输出到IP为192.168.1.93的Logstash;使用现有的Elastic Stack

[root@centos76d77 12:38 ~]# systemctl restart rsyslog.service

配置Elastic Stack

当前Elastic Stack的各组件版本都为5.5.1

修改Logstash的配置

[root@centos71d93 12:53 ~]# vim /etc/logstash/conf.d/test.conf
input {
    syslog {
        add_field => { "srcid" => "syslog" }
        port => "3514"
        type => "bash"
    }
}

filter {
    if [srcid] == "syslog" {
        grok {
            match => {
                "message" => "PID=%{NUMBER:processid} UID=%{NUMBER:uid} \
User=%{WORD:user} Cmd=%{GREEDYDATA:cmd}"
            }
        }
        mutate {
            remove_field => [ "message" ]
        }
    }
}

output {
    if [srcid] == "syslog" {
        elasticsearch {
            hosts => ["node1:9200","node2:9200","node3:9200"]
            index => "bash_%{+YYYY.MM.dd}"
        }
    }
}

 
Elasticsearch上添加template

[root@centos71d86 13:04 ~]# curl -XPUT 'node1:9200/_template/template_bash' -d '
{
   "template": "bash_*", 
   "order" : 10,
   "settings" : {
      "number_of_shards": 5,
      "number_of_replicas": 1
   },
   "mappings" : {
    "_default_" : {
      "_all" : {"enabled" : true, "omit_norms" : true},
      "properties" : {
        "host": { "type": "keyword"},
        "cmd": { "type": "keyword"},
        "user": { "type": "keyword"},
        "uid": { "type": "integer"},
        "processid": { "type": "integer"}
      }
    }
  }
}'

 

[root@centos71d93 13:08 ~]# su - logstash 
-bash-4.2$ /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/test.conf
# 启动logstash
# 新打开一个被监控主机的终端
# (注意:要打开新的终端,在原来的终端中输入命令是不会生效的)
# 随便输几个命令
[root@centos76d77 13:27 ~]# pwd
[root@centos76d77 13:27 ~]# ls
[root@centos76d77 13:27 ~]# w
[root@centos76d77 15:05 ~]# echo "hahaha"
[root@centos71d86 13:26 ~]# curl 'node1:9200/_cat/indices'
green open   bash_2019.06.06   yVvxxutPRZ-12PTklDcR-g 5 1 4 0 78.7kb 19.8kb
# Elasticsearch上可以看到新生成的索引bash_2019.06.06

 
 

Kibana创建索引
 

设置一下显示格式,可以看到效果
 

[root@centos76d77 15:06 ~]# useradd user1
[root@centos76d77 15:20 ~]# su user1
[user1@centos76d77 root]$ id
[user1@centos76d77 root]$ pwd
[user1@centos76d77 root]$ who


su也没有问题,终端上执行的命令都能被记录

 
 

参考:
https://dwz.cn/6oxc9HF3
https://dwz.cn/E64aAeXh

发表评论

邮箱地址不会被公开。