Unix & Linux
process open-files lsof audit
Updated Fri, 23 Sep 2022 00:50:14 GMT

How do I monitor opened files of a process in realtime?


I know I can view the open files of a process using lsof at that moment in time on my Linux machine. However, a process can open, alter and close a file so quickly that I won't be able to see it when monitoring it using standard shell scripting (e.g. watch) as explained in "monitor open process files on linux (real-time)".

So, I think I'm looking for a simple way of auditing a process and see what it has done over the time passed. It would be great if it's also possible to see what network connections it (tried to) make and to have the audit start before the process got time to run without the audit being started.

Ideally, I would like to do this:

sh $ audit-lsof /path/to/executable
4530.848254 OPEN  read  /etc/myconfig
4530.848260 OPEN  write /var/log/mylog.log
4540.345986 OPEN  read  /home/gert/.ssh/id_rsa          <-- suspicious
4540.650345 OPEN  socket TCP ::1:34895 -> 1.2.3.4:80    |
[...]
4541.023485 CLOSE       /home/gert/.ssh/id_rsa          <-- would have missed
4541.023485 CLOSE socket TCP ::1:34895 -> 1.2.3.4:80    |   this when polling

Would this be possible using strace and some flags to not see every system call?




Solution

Running it with

strace -e trace=open,openat,close,read,write,connect,accept your-command-here

would probably be sufficient.

You'll need to use the -o option to put strace's output somewhere other than the console, if the process can print to stderr. If your process forks, you'll also need -f or -ff.

Oh, and you might want -t as well, so you can see when the calls happened.


Note, you may need to tweak the function call list depending on what your process does - I needed to add getdents for example, to get better sample using ls:

$ strace -t -e trace=open,openat,close,read,getdents,write,connect,accept ls >/dev/null
...
09:34:48 open("/etc/ld.so.cache", O_RDONLY) = 3
09:34:48 close(3)                       = 0
09:34:48 open("/lib64/libselinux.so.1", O_RDONLY) = 3
09:34:48 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@V\0\0\0\0\0\0"..., 832) = 832
09:34:48 close(3)                       = 0
...
09:34:48 open("/proc/filesystems", O_RDONLY) = 3
09:34:48 read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tb"..., 1024) = 366
09:34:48 read(3, "", 1024)              = 0
09:34:48 close(3)                       = 0
09:34:48 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
09:34:48 close(3)                       = 0
09:34:48 open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
09:34:48 getdents(3, /* 5 entries */, 32768) = 144
09:34:48 getdents(3, /* 0 entries */, 32768) = 0
09:34:48 close(3)                       = 0
09:34:48 write(1, "file-A\nfile-B\nfile-C\n", 21) = 21
09:34:48 close(1)                       = 0
09:34:48 close(2)                       = 0




Comments (5)

  • +2 – That's getting into the right direction, thanks! Would like a more user friendly output, but it does the job. I might take the time to write a tool with a more top-like interface for this. I was hoping an ncurses-based or 'top'-like tool would exist to inspect the binary's actions real-time. — Dec 19, 2012 at 14:43  
  • +0 – How would you like it to look? It's probably possible to munge the strace output into something friendlier. — Dec 19, 2012 at 14:44  
  • +7 – You can also attach strace to a running process with the -p PID option. — Mar 18, 2017 at 18:44  
  • +3 – Add -y to "[p]rint paths associated with file descriptor arguments" — Aug 23, 2019 at 09:47  
  • +6 – Don't forget openat and such! — Mar 24, 2020 at 20:16  


External Links

External links referenced by this document: