出发点

在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度。不出问题还好,出了问题,就很难找出源头。
  这里介绍下,如何利用编译bash使不同的客户端在使用root登陆服务器时,记录各自的操作,并且可以在结合ELK 日志分析系统,来收集登陆操作日志

环境

  • CentOS 6.7
  • Development tools
  • SElinux 关闭

搭建部署

下载bash源码

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

修改bash源码,开启syslog功能

先修改config-top.h文件,删除以下行注释(注释符号是/* */)修改如下:

/* #define SYSLOG_HISTORY */

修改为:

#define SYSLOG_HISTORY

然后修改以下行:

#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_USER
# define SYSLOG_LEVEL LOG_INFO
#endif

修改为:

#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_LOCAL1
# define SYSLOG_LEVEL LOG_DEBUG
#endif

修改下bashhist.c文件,根据自己的需要指定的格式,并传入相应的变量,修改如下:

void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
 
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
}
}

修改为:

void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
 
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PPID=%d PID=%d SID=%d UID=%d User=%s %s", getppid(), getpid(), getsid(getpid()), current_user.uid, current_user.user_name, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PPID=%d PID=%d SID=%d UID=%d User=%s %s", getppid(), getpid(), getsid(getpid()), current_user.uid, current_user.user_name, trunc);
}
}

编译安装

[root@yum_repo bash-4.1]# ./configure --prefix=/usr/local/bash_new
[root@yum_repo bash-4.1]# make && make install

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

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

检查效果

使用syslog-ng

安装syslog-ng

[root@yum_repo bash-4.1]# yum install syslog-ng

配置syslog-ng

编辑/etc/syslog-ng/syslog-ng.conf
在末尾增加以下内容,将local1debug级别日志输出到/var/log/bash文件中

filter f_bash { facility(local1) and level(debug); };
destination d_bash { file("/var/log/bash"); };
log { source(s_sys); filter(f_bash); destination(d_bash); };

配置完成后重启syslog-ng

[root@yum_repo bash-4.1]# /etc/init.d/syslog-ng restart

使用rsyslog

安装rsyslog(系统默认已安装)

[root@yum_repo bash-4.1]# yum install rsyslog

配置rsyslog

编辑/etc/rsyslog.conf
在末尾增加以下内容,将local1debug级别日志输出到/var/log/bash文件中

local1.debug  /var/log/bash

配置完成后重启rsyslog

[root@yum_repo bash-4.1]# /etc/init.d/rsyslog restart

最终效果

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

[root@yum_repo bin]# tail -f /var/log/bash 
Sep  2 16:43:51 localhost bash: HISTORY: PPID=1811 PID=7921 SID=9638 UID=0 User=root exit
Sep  2 16:44:01 localhost bash: HISTORY: PPID=1811 PID=8021 SID=9638 UID=0 User=root tail -f /var/log/bash 
Sep  2 16:44:33 localhost bash: HISTORY: PPID=8084 PID=8105 SID=8084 UID=0 User=root ls
Sep  2 16:44:37 localhost bash: HISTORY: PPID=8084 PID=8105 SID=8084 UID=0 User=root ps -ef
Sep  2 16:57:39 localhost bash: HISTORY: PPID=8084 PID=8105 SID=8084 UID=0 User=root history |grep wget
Sep  2 16:58:56 localhost bash: HISTORY: PPID=8084 PID=8105 SID=8084 UID=0 User=root cd /root/rpmbuild/

打包成rpm包

配置完成后的bash需要打包成rpm包然后发布在私有源中,方便所有机器批量部署

  1. 将编辑好的bash源码重新打包成.tar.gz格式,之后置于rpmbuild工作目录的SOURCES文件夹中
  2. SPECS文件夹中新建bash.spec
Name:Bash_with_syslog	
Version:v4.1
Release:	1%{?dist}
Summary:This bash is enable syslog to local1,and the level is debug	

Group:System Environment/Shells	
License:GPLv3 license	
URL:https://www.gnu.org/software/bash/
Source0:bash-4.1.tar.gz


%description
Bash with syslog

%prep
rm -rf /root/rpmbuild/BUILD/bash-4.1
zcat /root/rpmbuild/SOURCES/bash-4.1.tar.gz | tar -xvf -

%build
cd $RPM_BUILD_DIR/bash-4.1
./configure --prefix=/usr/local/logbash/
make 

%install
cd $RPM_BUILD_DIR/bash-4.1
make install DESTDIR=%{buildroot}

%files
%defattr(-,root,root)
/usr/local/logbash

%clean
cd $RPM_BUILD_DIR/bash-4.1
make clean
  1. build

总结

相对于使用PROMPT_COMMAND的方式,直接更改源码编译bash存在:
优点:

  • 分发部署更加简单
  • 命令开始执行时记录,而不是结束时记录

问题:

  • 更换bash 和 sh 以外的shell操作不会被记录 依然存在
  • 使用shell脚本只会记录执行的脚本名称,内容不会被记录 依然存在
  • 被ssh远程执行的命令不会被记录 依然存在

rsyslog v8配置

Server:

template( name="hongjiu_bash_dyna" type="string" string="/data/command-audit/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log" )
if ( $syslogfacility-text == "local1" ) then {
    action(type="omfile" DynaFile="hongjiu_bash_dyna")
    stop
}

Client:

local1.debug  /var/log/bash

if ($syslogfacility-text == "local1") then {
        action(
        type="omfwd"
        Target="es"
        Port="514"
        Protocol="tcp"
        action.resumeRetryCount="-1"
        name="action_forward_hongjiu_bash"
        queue.filename="action_forward_hongjiu_bash"
        queue.size="50000"
        queue.dequeuebatchsize="1000"
        queue.maxdiskspace="5G"
        queue.type="linkedlist"
        queue.maxfilesize="500M"
        queue.saveonshutdown="on"
    )
    stop
}

参考