Linux系统中的文件监控

前因

公司的ubuntu终端产品上线后出现串口打印机断断续续打印不规则字符的现象。维护人员认为是打印机的问题,厂家来了后当面测试确认不是产品问题。后来我接手处理,发现是因为触控驱动程序不间断的挨个打开串口并写入数据。在这个过程中接触了一些Linux下的文件监控工具。我们对文件的监控需求分类大致为:

  • 特定文件正在被那些进程操作 (lsof)
  • 特定进程正在操作那些文件 (lsof)
  • 实时监控特定文件一段时间 (auditd)
  • 特定的程序在执行过程中会操作那些文件 (strace)

Linux下“一切皆文件”,监控文件,就能掌控系统。

使用到的命令/工具

lsof

这个命令主要用于查询当前打开的文件,太复杂了,关于其的完整介绍请man lsof或者访问,这里只介绍几种常见用法。

  • 特定用户打开的文件
root@zzz:/tmp# lsof -u root
COMMAND     PID USER   FD      TYPE     DEVICE SIZE/OFF       NODE NAME
systemd       1 root  cwd       DIR        8,4     4096          2 /
systemd       1 root  rtd       DIR        8,4     4096          2 /
systemd       1 root  txt       REG        8,4  1538764     543000 /lib/systemd/systemd
systemd       1 root  mem       REG        8,4    18076     523252 /lib/i386-linux-gnu/libuuid.so.1.3.0
systemd       1 root  mem       REG        8,4   293412     523076 /lib/i386-linux-gnu/libblkid.so.1.1.0
systemd       1 root  mem       REG        8,4    13828     523102 /lib/i386-linux-gnu/libdl-2.23.so
systemd       1 root  mem       REG        8,4   472368     523199 /lib/i386-linux-gnu/libpcre.so.3.13.2
systemd       1 root  mem       REG        8,4  1786484     523084 /lib/i386-linux-gnu/libc-2.23.so
  • 特定进程打开的文件
root@zzz:/tmp# lsof -p [pid of process]
  • 特定文件被谁打开
root@zzz:/tmp# lsof -t [file path]

一些编辑器在编辑文件的时候,并不是保持原有文件的打开状态,而是载入内容后关闭文件,这种情况下lsof是不会列出该编辑该文件的编辑器的。

  • 网络连接

这个命令会列出所有的网络连接

root@zzz:/tmp# lsof -i

特定协议、端口上运行的程序

root@zzz:/tmp# lsof -i TCP:1-23
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd   1 root  137u  IPv6  19817      0t0  TCP *:ssh (LISTEN)

如果它能实时监控某个文件就完美了,虽然可以通过watch来不断调用它,但无论间隔多短,都不是实时监控,在使用auditd之前,我是通过多次运行lsof才逮住了往串口设备写数据的进程,有一定的偶然性(这个进程打开串口写入数据后会马上关闭串口)

auditd

Linux下的审计服务,需要安装配置,关于它的介绍可参考Linux man page,这里我们只介绍如何使用它来监控特定文件。首先要在监控规则中加入文件:

root@zzz/tmp:#auditctl -w /tmp/test  -p warx -k [my_test]

其语法为:
auditctl -w path_to_file -p permissions -k key_name
r — read access to a file or a directory.
w — write access to a file or a directory.
x — execute access to a file or a directory.
a — change in the file’s or directory’s attribute
其中-k 参数为可选,产生一个易标识的日志入口关键字,方便查找。

可通过命令查询到该规则:

root@zzz:/tmp# auditctl -l
-w /tmp/test -p rwxa -k [my_test]

日志文件默认会记录在/var/log/audit/audit.log,其格式请参考格式说明

准备测试:

root@zzz:/tmp# echo asd >> /tmp/test

查找相关数据:

root@zzz:/tmp# ausearch -i -k [my_test]
----
type=PROCTITLE msg=audit(2019年02月28日 11:35:37.328:4574) : proctitle=bash 
type=PATH msg=audit(2019年02月28日 11:35:37.328:4574) : item=1 name=/tmp/test inode=521784 dev=08:04 mode=file,644 ouid=root ogid=root rdev=00:00 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 
type=PATH msg=audit(2019年02月28日 11:35:37.328:4574) : item=0 name=/tmp/ inode=521218 dev=08:04 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 
type=CWD msg=audit(2019年02月28日 11:35:37.328:4574) : cwd=/mnt/data/opensource 
type=SYSCALL msg=audit(2019年02月28日 11:35:37.328:4574) : arch=i386 syscall=open success=yes exit=3 a0=0x9531ae8 a1=O_WRONLY|O_CREAT|O_TRUNC a2=0666 a3=0x9531ae8 items=2 ppid=9774 pid=9775 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts13 ses=unset comm=bash exe=/bin/bash key=[my_test]

使用ausearch命令搜索审计记录的时候,使用-i或者–interpret选项将自动将二进制转变为等价的可读信息。对比一下搜索输出信息,先执行命令:

root@zzz:/tmp# cat /tmp/test 

直接使用ausearch -f /tmp/zf:

type=SYSCALL msg=audit(1551323460.883:1712): arch=40000003 syscall=5 
success=yes exit=3 a0=bfa3f27a a1=8000 a2=0 a3=b7efc000 items=1 ppid=9288 
pid=11204 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 
fsgid=0 tty=pts12 ses=4294967295 comm="cat" exe="/bin/cat" key="[test]

使用了-i参数后ausearch -i -f /tmp/zf:

type=SYSCALL msg=audit(2019年02月28日 11:11:00.883:1712) : 
arch=i386 syscall=open success=yes exit=3 a0=0xbfa3f27a a1=O_RDONLY 
a2=0x0 a3=0xb7efc000 items=1 ppid=9288 pid=11204 auid=unset uid=root 
gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root
tty=pts12 ses=unset comm=cat exe=/bin/cat key=[test]

其中的关键信息:
syscall=open
a1=O_RDONLY
exe=/bin/cat

strace

这个命令的详细语法请参考General Commands Manual或者Linux man page。这里我们拿strace来跟踪程序执行过程中要访问那些文件,有点意外吧。
例如,我们要检查geany这个程序在执行中是否打开了/etc/ld.so.cache这个文件(这个命令默认会输出到标准错误,所以需要现将其重定向到标准输出):

root@zzz:/tmp# strace -f -e trace=open geany  2>&1 |grep /etc/ld.so.cache
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18598] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
[pid 18603] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 18603] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 18603] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 18604] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

其他参考工具

  • inotify-tools 它好像只能告诉你文件被操作了,到底是谁不知道
  • loggedfs 无法指定文件,只能接受路径参数
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值