日常开发中使用python可以做一些小工具,相对C语言和shell脚本来说使用起来很简单,而且是解释执行的,所以开发和使用效率比较高。
需求
审计一下linux(或者说是类unix系统)下系统的开关机、登录、注销情况。
分析
linux下系统的开关机、登录和注销行为都有日志记录,该日志文件位于/var/log/wtmp, 我们只需要监测日志文件的变化,通过对比变化前后的内容就可以知道我们要监测变更信息。
另外这个日志文件是二进制形式的,不能直接打开查看,可以使用last命令查看,另外通过添加以下last命令的参数可以更好地获取里面的信息。
实践
这里是通过c文件调用python脚本获取python脚本执行的输出信息来进行行为审计的,重点将以下python部分,也就是处理日志信息的那里。
整个工作流程是这样的,c文件负责定时调用python脚本,python脚本负责获取当前last命令下输出的内容信息,然后对比本地缓存的之前的last信息,通过差异项来判断那些是登录操作,哪些是注销操作,是本地行为还是远程链接等等。
通过下面的命令可以获取到最近的30条系统登录信息:1
last -F -x -n 30
比如本机的
1 | 第一列 第二列 第三列 第四列 第五列 第六列 |
第一列是用户名,第一列是reboot的表示系统启动,第二列是表示虚拟终端登录信息,比如图形界面登录有的是“:0”,有的是“ttyx”,不同发行版的系统是有细微差别的。
第三列是用户的登录IP获取内核信息,如果是第一列是reboot,那么第三列就是内核信息,如果是正常用户登录,那么第三列就是本地或者远程IP地址。
再接下来第四列是开始时间,即系统的启动时间或者登录时间。
第五列是结束时间,可能是系统的关机时间或者是用户的注销时间,当然如果是still running,则代表该系统还在运行中,我们可以通过第四列判断出系统的开机时间。
如果是still logged in,则表示用户还在连接中,我们可以通过第四列判断出用户的登录时间。
第六列是运行时间统计,这里有个问题需要注意以下,有时候这个值是负的,这很神奇?时间怎么可能是负的,其实是因为系统开机时记录的时间不准确造成的,记录的时间比实际时间晚了8个小时。
在获取系统开机时间时,我们需要将这个八个小时减去才能获取到正确的时间。具体要不要减去这8个小时要根据你电脑的世纪情况来判断,基本方法就是第六列有负值,那么肯定就需要减去这8个小时。
这里面其实还是需要你仔细分析差异点,然后找出规律,最后通过不同的条件判断出系统的行为。
关键代码
1 | if __name__ == '__main__': |
deal_log的内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14def deal_log(content_new, now_str):
content_words = content_new.split(' ')
while '' in content_words :
content_words.remove('')
ret, plat = subprocess.getstatusoutput('uname -m')
if plat == 'aarch64' :
#print('kylin')
deal_kylin_log(content_new, content_words)
elif plat == 'i686':
#print('cods')
deal_cods_log(content_new, content_words, now_str)
elif plat == 'mips64' :
#print('neo')
deal_neo_log(content_new, content_words)
其实就是根据具体不同的平台来进行不同的处理。
比如kylin平台:
1 | def fix_time(time) : |
最后把日志组织成相应的格式输出,由c程序捕获这些输出就可以了。
总结
总体思路就是用python做一个中间处理的小工具,通过调用这个小工具可以将固定格式的日志信息处理之后组织成我们想要的信息返回回来,这里我是通过直接打印然后让c程序获取python的打印信息。
我知道c和python可以通过相应的api互相调用,暂时没有研究,回头研究一下看能不能做个改进。
2018.7.20 北京 晴