Jak monitorować otwarte pliki procesu w czasie rzeczywistym?

41

Wiem, że mogę przeglądać otwarte pliki procesu używającego lsof w tym momencie na moim komputerze z systemem Linux. Jednak proces może otwierać, modyfikować i zamykać plik tak szybko, że nie będę go widział podczas monitorowania go przy użyciu standardowych skryptów powłoki (np. watch), Jak wyjaśniono w „monitorowaniu otwartych plików procesu w systemie Linux” (w czasie rzeczywistym) ” .

Tak więc myślę, że szukam prostego sposobu przeprowadzenia audytu procesu i zobaczenia, co zrobiło z upływem czasu. Byłoby wspaniale, gdyby można było również zobaczyć, jakie połączenia sieciowe nawiązał (próbował) i rozpocząć audyt, zanim proces uzyskał czas na uruchomienie bez rozpoczęcia audytu.

Idealnie chciałbym to zrobić:

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

Czy byłoby to możliwe przy użyciu straceniektórych flag, aby nie wyświetlały się wszystkie wywołania systemowe?

gertvdijk
źródło

Odpowiedzi:

50

Uruchamianie z

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

prawdopodobnie byłby wystarczający.

Musisz użyć -oopcji, aby umieścić wyjście strace w innym miejscu niż konsola, jeśli proces może wydrukować na stderr. Jeśli proces się rozwiąże, będziesz potrzebować również -flub -ff.

Aha, możesz też chcieć -t, abyś mógł zobaczyć, kiedy nastąpiły połączenia.


Uwaga: może być konieczne dostosowanie listy wywołań funkcji w zależności od tego, co robi Twój proces - musiałem getdentsna przykład dodać , aby uzyskać lepszą próbkę, używając ls:

$ strace -t -e trace=open,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
Nieprzydatny
źródło
1
To idzie w dobrym kierunku, dzięki! Chciałbym uzyskać bardziej przyjazny dla użytkownika wynik, ale spełnia swoje zadanie. Mogę poświęcić trochę czasu na napisanie narzędzia z bardziej podobnym do tego interfejsem. Miałem nadzieję, że będzie istniało narzędzie oparte na ncurses lub „top” podobne do sprawdzania działań binarnych w czasie rzeczywistym.
gertvdijk
Jak by to wyglądało? Prawdopodobnie możliwe jest zamrożenie wyniku strace w coś bardziej przyjaznego.
Bezużyteczne
zdecydowanie chcesz użyć -odo wypchnięcia danych wyjściowych do pliku (ów). Następnie możesz uruchomić tail -F strace.outputw innym terminalu, aby uzyskać aktualizację „na żywo”.
Peter
4
Możesz także dołączyć stracedo uruchomionego procesu z -p PIDopcją.
Frank Breitling
Dodaj -ydo „[p] ścieżek rint powiązanych z argumentami deskryptora pliku”
ricab