实验环境:vmware虚拟centos5.3
虚拟机:192.168.83.137 (自己编译的mysqld 5.1.55)
192.168.83.133 mysql client
一、原理
Mysql审计无非抓包(tcp and 3306),目前mysqlsniffer已经很好的完成了抓包功能,加点自己的功能也简单,这个下次有机会再说,mysqlsniffer的代码量很少,对于用过pcap的人来说,都是a piece of cake!!
今天还是说下从mysql的源码入手,大家都知道mysql有了慢log功能,让我们先看看一条慢log:
这个语句似乎已经满足了审计的功能,谁在那里在什么时间做了什么???
Root于11:00:22在localhost上执行了insert操作
我们大胆的想下,如果mysql每条语句都打log是不是就完成审计了呢?absolutely,不过这个似乎太黄太暴力了,只针对特定用户特定机器执行审计操作是不是就达到审计的要求了呢….嗯哼、嗯哼~~~
那我们再添加两个选项 audit-user、audit-ip不就ok了么,so just do it
Ps:
在这个的基础上,可以将慢log修改成发送到另一台server上统一分析,这样对性能也没有什么影响。我这个只是个非常非常粗糙的版本,请原谅我修改mysql代码后make && make install后,居然启动成功,审计成功的惊喜吧…留待后面完善
二、代码修改
2.1 添加配置选项
2.1.1 加载源码
Sourceinsight加载mysql 5.1.55源码(si,默认不加载.cc文件,options->Document options设置下)
2.1.2 如何添加配置选项
让我们先了解下log-error这个配置选项(因为我们添加的配置选项,也将是字符串滴,注意是log-error不是log_error),我们在依葫芦画,search下主要有:
struct my_option my_long_options[] = {
….
{"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
&log_error_file_ptr, &log_error_file_ptr, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0}
…
}
看下就知道mysql读取配置选项为log-error的值到log_error_file_ptr这个变量中,这里var_type(GET_STR, GET_STR_ALLOC等)和arg_type(NO_ARG, OPT_ARG,REQUIRED_ARG)你懂的,我就不说了
接下来就是log_error_file_ptr这个变量是怎么使用的了,还是按潜规则,search了哦
其实最主要的就是在init_server_components中将log_error_file_ptr赋值到了log_error_file中
fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
MY_UNPACK_FILENAME | MY_SAFE_PATH);
接下来就是如何用这个变量了,大家注意我标红的
在mysql_priv.h中extern了,在log.cc和set_var.cc中使用了log_error_file这个变量。。
先看看set_var.cc吧 sys_log_error的类型为sys_var_const,sys_var_const的构造函数有个chain_sys_var,看字面意思就这个这个函数是将所有变量(其实也就是配置选项串起来了),这里就不细说了,有兴趣的自己跟下
到这里如何添加配置选项就清晰了
2.1.3
首先在mysqld中添加一个我们自己的配置选项
至于opt_audit_user的定义,这些就不说了
将这个变量保存到一个数组中(这里完全模仿log-error),在init_server_components中添加:
snprintf(audit_user, sizeof(audit_user), "%s", opt_audit_user);
在mysql_priv.h中添加:
extern char* opt_audit_user;
extern char audit_user[FN_REFLEN];
2.2 审计原理
利用慢log,search下long_query_time在log_slow_statement中
if (((end_utime_of_query - thd->utime_after_lock) >
thd->variables.long_query_time || …
一路追寻,找到
具体的语句打印在
bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
ulonglong current_utime)
那么一切都清晰而又明了了,如果设置long_query_time为0,把>修改为>=,在的slow_log_print里过滤掉一些不想审计的东东,就ok了
三、源码编译安装
具体源码怎么修改的,我就不写了,代码我给出来…
Make && make install后cp ./support-files/mysql.server /etc/init.d/mysqld就可以了。。。
四、使用
4.1 配置文件/etc/my.cnf
修改配置文件,添加下面的几个选项
哈哈,上面两个配置选项就是自己添加的,表示只审计来自192.168.86.133上的secutcs用户,log-slow-queries表示log存放的文件名,long_query_time=0表示记录任何log(聪明的你可能已经想到了还需要修改某处的>为>=)
4.2 启动mysql,查看审计log
[root@localhost ~]# /etc/init.d/mysqld start
这里的mysqld就是mysql.server cp过来的,强烈建议使用mysql.server这个启动脚本,在137上查看审计log
4.3 133上使用secutcs账户连接
[root@localhost ~]# mysql -usecutcs -p123456 -h192.168.83.137 test
4.4 137上audit_log
4.5 137上自己使用root帐号看是否能审计
[root@localhost ~]# mysql -uroot -p123456 test -S /var/lib/mysql/mysql.sock
使用root账户,没有效果
在133上使用 另一个账户haha也没有反映
[root@localhost ~]# mysql -uhaha -p123456 -h192.168.83.137 test
4.6 来查看下我们设置的变量
五、后续
目前这种做法,对正常的慢log有影响,后续再专门添加一个audit-log表示审计功能开启与否,long-query-time也再另添加一个audit-long-query-time就可以了
六、附件patch包
有些地方我可能敲了回车,patch包不一定对,但是vim打开下audit.patch基本在那里修改了,已经很清除了
如果patch包不行,直接使用 ,我把sql子目录打包了,如果设计到路径问题,我configure的时候使用的是./configure –prefix=/usr/local
上传上来变了,fuck,附件也不行,整个word大小又不行...
bbs地址: