在上一篇文章《6.2.0-通过Nginx获取CDSW的登录信息(续2)》中,通过Nginx的配置进一步捕获了用户的一些操作,然后存入数据库中进行查询分析,具体是捕获了用户进行Kerberos认证的Principal,但是在后续使用过程中发现,在两个以上的用户进行登陆时,Kerberos和点击Share操作捕获的用户信息永远是最后登陆的那个用户,这样与实际需求不符合,没有捕获到实际进行Kerberos认证和点击Share操作的究竟是哪个用户,本文档针对这一情况进行完善。
1.CM和CDH版本为6.2.0
2.CDSW版本为1.5
3.Nginx版本为1.16.0
4.集群启用Kerberos
实现过程
基于新的拦截需求,需要对以下几个部分进行修改:
Nginx的配置不用修改,保持和之前一致,如下图:
1.修改脚本,对用户点Share和Kerberos认证部分进行修改
#!/bin/bash
HOSTNAME="192.168.0.178"
PORT="3306"
DBNAME="cdsw_login_info"
TABLENAME="login_info"
log_dir=/usr/local/nginx/logs/
log_name=$(date -d "yesterday" +"%Y%m%d")
#将nginx日志中的十六进制引号转为正常显示的引号并定向到前一天日期命令的新日志文件
sed 's#\\x22#"#g' ${log_dir}access.log > ${log_dir}${log_name}.log
#将nginx日志文件清空,确保每次处理的是前一天的日志
cat /dev/null > ${log_dir}access.log
#按行读取新的日志文件进行处理
cat ${log_dir}${log_name}.log | while read line
do
if [[ $line =~ "authenticate" ]] && [[ $line =~ "POST" ]] && [[ $line =~ "login" ]]; then
OIFS=$IFS; IFS="|"; set -- $line; aa=$1;bb=$3;cc=$4;source_ip=$5;referer=$6;user_agent=$7 IFS=$OIFS
OIFS=$IFS; IFS='""'; set -- $cc; username=$7 IFS=$OIFS
occur_time=${aa:0:10}" "${aa:11:8}
if [[ $bb = "200" ]]; then
login_state='1'
elif [[ $bb = "401" ]]; then
login_state='0'
else
login_state=''
fi
insert_sql="insert into ${DBNAME}.${TABLENAME}(source_ip,name,referer,user_agent,login_state,occur_time) values('$source_ip','$username','$referer','$user_agent',$login_state,'$occur_time')"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${insert_sql}"
fi
if [[ $line =~ "sharing" ]]; then
OIFS=$IFS; IFS="|"; set -- $line; aa=$1;bb=$3;cc=$4;source_ip=$5;referer=$6;user_agent=$7 IFS=$OIFS
OIFS=$IFS; IFS='""'; set -- $cc; share_flag=$9 IFS=$OIFS
OIFS=$IFS; IFS='/'; set -- $referer; username=$4 IFS=$OIFS
occur_time=${aa:0:10}" "${aa:11:8}
if [[ $share_flag = "" ]]; then
share_flag="clickShare"
fi
insert_sql="insert into ${DBNAME}.${TABLENAME}(source_ip,name,referer,user_agent,login_state,occur_time,share_flag) values('$source_ip','$username','$referer','$user_agent','1','$occur_time','$share_flag')"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${insert_sql}"
fi
if [[ $line =~ "kerberos-credentials" ]]; then
OIFS=$IFS; IFS="|"; set -- $line; aa=$1;request=$2;bb=$3;cc=$4;source_ip=$5;referer=$6;user_agent=$7 IFS=$OIFS
OIFS=$IFS; IFS='""'; set -- $cc; kerberos_principal=$5 IFS=$OIFS
if [[ $referer =~ "settings" ]]; then
OIFS=$IFS; IFS='/'; set -- $referer; username=$5 IFS=$OIFS
else
OIFS=$IFS; IFS='/'; set -- $referer; username=$4 IFS=$OIFS
fi
occur_time=${aa:0:10}" "${aa:11:8}
if [[ $bb = "204" ]] && [[ $request =~ "POST" ]]; then
kerberos_bind_state='1'
elif [[ $bb = "422" ]]; then
kerberos_bind_state='0'
else
kerberos_bind_state=''
fi
insert_sql="insert into ${DBNAME}.${TABLENAME}(source_ip,name,referer,user_agent,login_state,occur_time,request,kerberos_principal,kerberos_bind_state) values('$source_ip','$username','$referer','$user_agent','1','$occur_time','$request','$kerberos_principal','$kerberos_bind_state')"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${insert_sql}"
fi
done
2.表结构不进行修改,与之前保持一致,如下图:
CREATE TABLE `login_info` (
`id` int(5) primary key NOT NULL AUTO_INCREMENT,
`source_ip` varchar(32) DEFAULT NULL,
`name` varchar(16) DEFAULT NULL,
`referer` varchar(64) DEFAULT NULL,
`user_agent` varchar(256) DEFAULT NULL,
`login_state` char(1) DEFAULT NULL,
`occur_time` timestamp ,
`request` varchar(256) DEFAULT NULL,
`share_flag` varchar(16) DEFAULT NULL,
`kerberos_principal` varchar(64) DEFAULT NULL,
`kerberos_bind_state` char(1) DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
使用两个用户同时登陆进行测试
1.使用test用户登陆CDSW
2.用另一个浏览器,使用qqq用户登陆CDSW,模拟同时登陆
3.使用test用户测试点击Share功能
4.使用test用户进行Kerberos认证,认证的账号为test
5.使用qqq用户进行Kerberos认证,认证的账号为test_hdfs1
6.运行脚本,在数据库中查看记录
查看用户进行Kerberos认证记录,可以看到,与测试的一样,test用户使用test进行认证,qqq用户使用test_hdfs1进行认证
查看用户点击Share操作,可以看到,记录的点击Share操作与测试时一样,全部都是test用户进行的
总结
1.对脚本中的判断条件进一步进行修改,对多个用户同时登陆时的情况进行完善,保证每条操作记录对应的用户,是实际进行从操作的用户。
2.完善后的记录中,每一条记录对应实际操作的用户,这样对审计信息会更有帮助。
Fayson的github: https://github.com/fayson/cdhproject