bash和mysql的代码一个低成本、实用性能高的日志审计方案

描述

概述

不怕出问题,就怕出问题找不到原因运维团队一般会有个需求就是记录运维或者开发同事在服务器上的操作记录,比如进行一些常规审核或者是服务器被黑了、服务器日志被删的情况需要知道发生过什么事情,今天和大家分享下我们现在的服务器的shell和mysql操作日志记录的DIY方案。团队内部之前有测试过一些堡垒机硬件,但终端操作方面不够人性化,不够灵活,而且价格昂贵,硬件容易形成单点故障。当然也接触过一些开源的方案,比如可以直接用ttyrec对终端进行录制,并且支持文本匹配,但是在实际使用中发现过严重bug,还有另外一些openssh的修改方案也不尽人意。鉴于上述问题,我们针对bash和mysql的代码进行简单的修改来实现一个低成本、实用性能高的日志审计方案。 

服务器日志:

服务器

服务器

服务器

下面来“开源”这个解决方案,希望对大家有小小帮助。

1.linux bash审计大家应该有听说过网络说的bash修改方案,我们从2011年开始使用,中间经历过很多bug,修复和优化过多次版本,下面会详细地给出我们现在的线上方案。现在的功能支持大致如下:

同一系统用户精确到具体人员的shell操作记录

支持远程通过ssh IP “command”执行和scp时候的日志记录

支持不同系统用户进行切换时候能继续记录日志

新支持mysql的操作日志

上述每一个功能列表都是经过多次实践出来的需求,虽然不是非常完美,但是如果不是刻意来逃避日志记录的话,基本可以满足大家的需求,上述的记录对应的人员是指多个人同时使用同一个系统帐号的情况,比如root帐号。1.1 基本功能实现基本功能就是需要记录到每个人的操作记录,网络上有个方案雏形,修改bashhist.c文件,701行左右修改bash_syslog_history函数,修改完之后内容:

服务器

1.2. 指纹变量处理接下来重点就是处理NAME_OF_KEY这个指纹变量,原理也比较简单,每个人登录系统的时候,我们让他自动执行一个脚本,然后设置这个变量为具体人就可以了。--------别说有人还在利用密码登录Linux服务器,太不专业了-_---------在这个文件里面~/.ssh/authorized_keys加key的时候,第三列设置为具体的人员,我们是用工号@姓名拼音的模式,然后通过脚本进行处理即可。脚本路径 /etc/bash_ywjt,内容:

服务器

服务器

服务器

服务器
服务器

2. Mysql操作日志很早以前找过相关的mysql插件,也尝试过audit之类的方案,但结果不是我们需要的效果,我们需要的是运维方面在服务器上的mysql操作,和mysql的binlog等日志不是同一个事情,而且和.mysql_history记录的也不一样,我们需要精确到同一系统用户的不同人员。以下mysql版本是指Percona-Server-5.5。2.1 初步解决mysql自带了syslog日志功能,但是需要手动配置开启,配置比较简单:在/etc/my.cnf里面的client字段加上syslog即可。

服务器
服务器

1)在mysqldump时候会报错:

服务器

2)可以轻易地绕过这个日志,在敲mysql命令行的时候加个参数--no-defaults即可。3)日志里面只有是root帐号操作的,没有体现出具体是某个人操作的。解决这几个问题还得靠开源的优势进行代码修改。2.2 源码开启我们可以在源码里面就把syslog这个开关开启,比较容易,找到client/mysql.cc这个文件,开关逻辑比较简单,找到以下代码:

服务器

2.3 交互式记录单纯那样改会发现还有个小问题,就是在shell终端下面直接mysql可以用-e进行命令操作,比如:
服务器

但是按照之前那样开启syslog也无法记录日志。我们是有记录shell操作记录的,这个问题可以忽略,不过一定要显示的话也是有办法的,继续修改代码。稍微看下逻辑分析可以看到是需要满足connect_flag == CLIENT_INTERACTIVE才写日志,找到CLIENT_INTERACTIVE的定义:原来这个就是交互模式的定义,所以我们把这个“与”条件去掉即可,改为这样:

服务器

2.4 海量日志问题在实际环境中会有新的问题,比如导入sql语句时候,会生成同样大小的日志,比如导入2G的sql,会生成2G的日志,这样明显不符合我们的需求。想到我们已经有bash审核了,-e执行时候可以忽略记录,但是如果在mysql里面通过source命令引用sql语句时候同样有这个问题,所以还得继续改代码。找到write_syslog函数,正式写日志时候是用的syslog函数,里面有个for循环的逻辑,意思是当sql语句很大时候,需要“切割”一下再写入,所以从这里入手,把syslog改为定义的MAX_SYSLOG_MESSAGE长度之内就写,超过的话就直接忽略。另外之前说需要精确到不同人员,所以我们引入了我们的bash审核里面的指纹,变量NAME_OF_KEY,然后在mysql.cc里面引入即可。关键修改如下:

服务器

2.5 自定义参数这样虽然是在源码里面写死了一定有日志,但是还是可以提供一个备用的参数来取消这个功能。在参数定义那里改动,把之前的syslog改为这样:

服务器

服务器

3. 远程日志中心上述日志全部是通过syslog服务记录到/var/log/messages文件,更合理的是再传输到远程的日志中心来统一备案管理。这个方法比较简单,在/etc/rsyslog.conf里面加入配置:

 服务器

4. 内网日志拦截这个段落是额外的参考,我们的定制系统是写死了配置全部发送到公网的某一台日志中心服务器,但是我们内网机房也有很多服务器,这样会导致在日志中心那里无法查看原始的内网IP,只有办公网的出口IP,而且不方便每个机器都去更改日志中心的IP,那样会很容易漏掉,解决办法是进行“日志劫持”。在我们的juniper防火墙那里进行日志拦截,然后转发到内网的一个日志中心即可,参考配置:

服务器

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分