Alat untuk menampilkan file mana yang diakses oleh suatu program?

12

Saya tidak akan menggunakan alat yang rumit seperti mode pengaduan AppArmor, saya perlu alat yang mudah untuk memberi tahu saya file mana yang diakses oleh program tertentu.

Boll19
sumber
7
Di bawah Sistem Operasi apa?
Jeff Schaller
Mungkin juga bermanfaat untuk menjelaskan Anda mengharapkan program mengakses file dengan cara apa - membaca, menulis, menambahkan, hanya mendapatkan fstat()atau lstat()info, dll.
Sergiy Kolodyazhnyy
Baik Suse dan Ubuntu
Boll19
Tidak mater apa cara saya harus tahu, apakah itu fstat () atau lstat () pemrograman?
Boll19
Komentar Sergiy Kolodyazhnyy dengan kata lain: jika suatu program memeriksa panjang file, tanggal modifikasi, izin atau properti lainnya tetapi tidak mengakses data file, apakah Anda akan menghitungnya sebagai "mengakses file" atau tidak?
telcoM

Jawaban:

12

Per Chris Down, Anda dapat menggunakan strace -puntuk memeriksa proses yang sudah berjalan , untuk melihat file apa yang dibuka dari sekarang sampai saat Anda mengakhiri strace atau proses itu sendiri selesai.

Jika Anda ingin melihat file dibuka untuk seluruh durasi proses, langsung dari awal, gunakan stracedengan nama yang dapat dieksekusi. Menambahkan -fmemastikan bahwa setiap sub-proses bercabang dua juga dilaporkan. Contoh

# strace -e open -f /bin/id
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/proc/thread-self/attr/current", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/proc/self/task/1581/attr/current", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+++ exited with 0 +++
#

Menggunakan lsofuntuk melihat file apa proses saat ini telah terbuka

# lsof -p $(pidof NetworkManager)
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
NetworkMa 722 root  cwd       DIR              253,0       224       64 /
NetworkMa 722 root  rtd       DIR              253,0       224       64 /
NetworkMa 722 root  txt       REG              253,0   2618520   288243 /usr/sbin/NetworkManager
NetworkMa 722 root  mem       REG              253,0     27776    34560 /usr/lib64/libnss_dns-2.17.so
[...]
#

Jika Anda memiliki SystemTap, Anda dapat memantau seluruh host untuk file yang dibuka.

[root@localhost tmp]# cat mon
#!/usr/bin/env stap
probe syscall.open { printf ("pid %d program %s opened %s\n", pid(), execname(), filename) }
# ./mon
pid 14813 program touch opened "/etc/ld.so.cache"
pid 14813 program touch opened "/lib64/libc.so.6"
pid 14813 program touch opened 0x7f7a8c6ec8d0
pid 14813 program touch opened "foo2"
[...]
#
steve
sumber
2
openbukan satu-satunya panggilan sistem yang relevan. Misalnya dimungkinkan untuk meneruskan deskriptor file antara proses melalui soket unix, dan ada openatpanggilan sistem yang juga dapat membuka file.
kasperd
---- SIGUSR1 {si_signo = SIGUSR1, si_code = SI_TKILL, si_pid = 6026, si_uid = 1002} ---- whats that
Boll19
Kaspers, apakah saya hanya perlu mencari 'openat' di perintah output strace?
Boll19
Mencoba membuka file (tetapi file tersebut mungkin tidak ada) juga ditampilkan dalam output 'strace'?
Boll19
Boll19, file yang gagal dibuka karena tidak ada dengan senang hati dilaporkan di dalamnya strace, lihat baris ENOENT dalam contoh.
steve
5

Anda dapat menggunakan opensnoopdari BCC, yang menggunakan eBPF di bawah tenda:

# ./opensnoop -p 1576
PID    COMM      FD ERR PATH
1576   snmpd     11   0 /proc/sys/net/ipv6/conf/lo/forwarding
1576   snmpd     11   0 /proc/sys/net/ipv6/neigh/lo/base_reachable_time_ms
1576   snmpd      9   0 /proc/diskstats
1576   snmpd      9   0 /proc/stat
1576   snmpd      9   0 /proc/vmstat
[...]

Ini cukup performan karena menggunakan kprobes daripada harus me-restart syscalls, seperti stracehalnya.

Anda juga dapat melakukan ini dengan strace(berpotensi dengan -fmengikuti proses yang dilacak anak-anak), tetapi cara operasinya, melibatkan restart syscalls sebagai bagian dari ptrace akan agak memperlambat aplikasi Anda:

# strace -e open -p 15735
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/gconv/gconv-modules", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/python2.7/site-packages", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 8
[...]

Anda juga dapat memulai aplikasi Anda dengan cara ini jika diinginkan, menggunakan strace [executable], atau strace -f [executable].

Chris Down
sumber
5

Alat favorit saya untuk memantau file mana aplikasi dibuka adalah kerangka pemantauan yang kuat sysdig.

Untuk memantau semua file yang terbuka dibuka oleh program bernama exe_file:

sudo sysdig -p "proc.name=exe_file %12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

Memantau semua file yang dibuka di server:

sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

Membuat file jejak yang hanya akan berisi acara penulisan di direktori home (yang dapat kita periksa nanti dengan sysdig -r writetrace.scap.gz):

sudo sysdig -p "%user.name %proc.name %fd.name" "evt.type=write and fd.name contains /home/" -z -w writetrace.scap.gz

Melihat segala sesuatu di tingkat syscall proses yang dinamai exe_filetidak:

sudo sysdig proc.name=exe_file

Sysdig memiliki banyak pahat, lihat hal-hal menarik yang dapat dilakukan:

Anda juga sudah mendapatkan dtraceyang tidak banyak digunakan di Linux, tetapi masih banyak menggunakan sistem operasi * BSD:

# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'

Selain itu sysdig, stracedan dtrace, Anda juga sudah mendapatkannya ltrace, yang merekam / memotong sinyal / pustaka dinamis / panggilan sistem yang dipanggil / diterima oleh suatu proses:

ltraceadalah program yang hanya menjalankan perintah yang ditentukan sampai keluar. Ini memotong dan merekam panggilan perpustakaan dinamis yang dipanggil oleh proses yang dieksekusi dan sinyal yang diterima oleh proses itu. Itu juga dapat mencegat dan mencetak panggilan sistem yang dijalankan oleh program.

$ltrace exe_file
_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 <unfinished ...>  
time(0)                                                                              = 1508018406  
srand(0x59e288e6, 0x7ffcb7b6d7c8, 0x7ffcb7b6d7d8, 0)                                 = 0  
sprintf("mkdir -p -- '/opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo")        = 28  
system("mkdir -p -- '/opt/sms/AU/mo'" <no return ...>  
--- SIGCHLD (Child exited) ---  
<... system resumed> )                                                               = 0  
rand(2, 0x7ffcb7b6d480, 0, 0x7f9d6d4622b0)                                           = 0x2d8ddbe1  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 3  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 4  
+++ exited (status 0) +++  

Jika program ini kecil, Anda mungkin juga mempertimbangkan untuk membongkar objdump -d exe_fileatau membongkar / mendekompilasi Hopper, untuk melihat semua file yang berhubungan dengannya.

Untuk detail lebih lanjut, lihat: Memahami apa yang dilakukan biner Linux

Sebagai pendekatan pertama, saya juga akan melakukan:

strings exe_file

Ini adalah pendekatan biaya rendah, dan dengan keberuntungan beberapa nama file mungkin hanya hadir dalam mode ASCII dalam file biner dengan keberuntungan.

Lihat juga jawaban terkait. Mengapa benar dan salah begitu besar?

Jika binari / file yang datang dengan distribusi Anda juga dapat mengambil sumber dari sumber repositori distribusi, atau repositori resmi utilitas aktual.

Sebagai sumber daya terakhir, Anda selalu dapat menggunakan alat seperti gdb atau rr untuk men-debug biner secara real time.

Rui F Ribeiro
sumber
aaa43bb66: ~ # sudo proc.name = exe_file sysdig -p "% 12user.name% 6proc.pid% 12proc.name% 3fd.num% fd.typechar% fd.name" evt.type = buka Tidak dapat memuat kesalahan driver membuka perangkat / dev / sysdig0. Pastikan Anda memiliki kredensial root dan modul sysdig-probe dimuat.
Boll19
/ * <pre> aaa43bb66: ~ # sudo proc.name = exe_file sysdig -p "% 12user.name% 6proc.pid% 12proc.name% 3fd.num% fd.typechar% fd.name" evt.type = buka Tidak dapat untuk memuat perangkat pembuka kesalahan driver / dev / sysdig0. Pastikan Anda memiliki kredensial root dan bahwa modul sysdig-probe dimuat. <code> * /
Boll19
@ Boll19 Ada kesalahan di sana, diperbaiki. Tampaknya pesan itu tentang sysdigbug (apakah Anda menggunakan ARM?), Kirimkan pertanyaan baru untuk itu.
Rui F Ribeiro