自定义脚本通过utmp读取Linux服务器登录信息

Seven 绯闻SEO 绯闻SEO,一个专注中小企业网站优化的SEO爱好者

在清理服务器时想看一下有多少服务器最近是没登录过的,因为服务器登录信息会记录到/var/log/wtmp文件,我们可以自己写脚本来读取wtmp文件,通过utmp函数,可以实现我们的需求。

最近突然要清理闲置服务器,最简单的指标当然是看下有多少服务器是最近没有人登录过的。当登录服务器的时候,init, tty等会将登录和登出信息记录到/var/log/wtmp文件中,通过last命令可以查询服务器的登录情况。

但是直接到服务器上执行last命令有几个问题,一是希望查询一个时间段内的登录情况,而last命令的-t参数只能设置最近时间点;另一个是服务器上的last比较老,不支持-F参数,显示的事件没有年字段,计算的时候可能会存在问题。

最方便的解决方法当然是自己来读取wtmp文件了,linux提供了utmp.h头文件,里面包含了utmp数据结构和操作函数,关于utmp这个结构,可以通过man utmp进行查询,其中比较常用的几个属性有:ut_type(登录/登出类型,具体上面手册中有详细的宏定义说明)、ut_tv(操作的事件)、ut_user(操作用户)、ut_host(操作主机名/ip).

手册中强调了,登录和登出都会单独记录一条,唯一的区别是登出不记录ut_user等字段,所以估计last命令中每次登录的事件计算,应该是根据每次登录和之后的一次登出的ut_line匹配上进行计算的.

再来说下utmp的操作函数,主要操作流程为:setutent -> getutent -> endutent,感觉和文件读写顺序差不多,首先需要通过setutent重新定位到utmp的文件头,循环调用getutent获取每一次的utmp记录,最后通过endutent结束读取,从api可以看出,所有的记录都要顺序读出,然后再进行过滤和运算.

需求是在给定事件段内打印出最后一次登录的时间,所以不去判断那次登录是否有登出操作,大致的实现,代码如下:

  1. time_tfrom=atol(argv[1]);
  2. time_tto=atol(argv[2]);
  3. structutmp*line=NULL;
  4. structutmp*result=NULL;
  5. time_ttimestamp;
  6. utmpname("/var/log/wtmp");
  7. setutent();
  8. while((line=getutent())!=NULL){
  9. if(line->ut_type==USER_PROCESS){
  10. timestamp=line->ut_tv.tv_sec;
  11. if(timestamp>=from&&timestamp<=to){
  12. if(result!=NULL){
  13. free(result);
  14. }
  15. result=malloc(sizeof(*result));
  16. memcpy(result,line,sizeof(*result));
  17. }//phpfensi.com
  18. }
  19. }
  20. if(result!=NULL){
  21. timestamp=result->ut_tv.tv_sec;
  22. printf("%s%s%s%s",result->ut_line,result->ut_user,result->ut_host,asctime(localtime(&timestamp)));
  23. }
  24. endutent();

获取的参数是两个时间段,为了方便运算,直接要求输入时间对应的unix时间戳,可以通过date命令获取,遍历所有记录,只读取USER_PROCESS类型的,然后比较这次登录时间是否在给定时间段内,因为这个顺序刚好是登录时间的顺序,所以最后一次登录的时间,就是最后一条符合if判断的时间,最后打印出来就OK了.

相关广告
  • 自定义脚本通过utmp读取Linux服务器登录信息 自定义脚本通过utmp读取Linux服务器登录信息 自定义脚本通过utmp读取Linux服务器登录信息
相关阅读

自定义脚本通过utmp读取Linux服务器登录信息

2019/10/10 17:44:48 | 谷歌SEO算法 | SEO