Я не збираюся на такі складні інструменти, як AppArmor у режимі скарг, мені потрібні легкі інструменти, щоб підказати, до яких файлів доступна конкретна програма.
fstat()
або lstat()
інформації і т.д.
Я не збираюся на такі складні інструменти, як AppArmor у режимі скарг, мені потрібні легкі інструменти, щоб підказати, до яких файлів доступна конкретна програма.
fstat()
або lstat()
інформації і т.д.
Відповіді:
За Криса Дауна ви можете використовувати strace -p
для вивчення вже запущеного процесу, щоб побачити, які файли він відкривається відтепер до моменту, коли ви припиняєте страйк або процес завершується.
Якщо ви хочете, щоб файли відкривались протягом усієї тривалості процесу, з самого початку скористайтеся strace
ім'ям виконуваного файлу. Додавання -f
гарантує, що про будь-які роздвоєні підпроцеси також надходять звіти. Приклад
# 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 +++
#
Використовується lsof
для того, щоб побачити, які файли відкритий в даний час
# 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
[...]
#
Якщо у вас є SystemTap, ви можете відстежувати весь хост на предмет відкриття файлів.
[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"
[...]
#
open
не єдиний відповідний системний дзвінок. Наприклад, можна передавати дескриптори файлів між процесами через unix-сокет, і є openat
системний виклик, який також може відкрити файл.
strace
, див. Рядки ENOENT у прикладі.
Ви можете використовувати opensnoop
з BCC, який використовує eBPF під кришкою:
# ./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
[...]
Це досить ефективно, оскільки він використовує kprobes замість того, щоб перезапускати системні виклики, як strace
це робиться.
Ви також можете це зробити за допомогою strace
(можливо, -f
це слідкувати за дітьми відстежуваного процесу), але його спосіб роботи, включаючи перезапуск системних викликів у складі ptrace , дещо уповільнить вашу програму:
# 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
[...]
Ви також можете запустити свою заявку таким чином, якщо бажаєте, використовуючи strace [executable]
або strace -f [executable]
.
Мій улюблений інструмент для моніторингу файлів, які відкриває програма, - потужна система моніторингу sysdig
.
Для моніторингу всіх відкритих файлів, відкритих програмою під назвою exe_file
:
sudo sysdig -p "proc.name=exe_file %12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open
Моніторинг усіх файлів, відкритих на сервері:
sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open
Створення файлу трасування, який буде містити лише записи подій у домашніх каталогах (які ми можемо перевірити згодом 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
Переглядаючи все на рівні syscall, процес, названий exe_file
:
sudo sysdig proc.name=exe_file
Sysdig має багато зубил, перегляньте ще цікаві речі, які він може зробити:
Ви також отримали dtrace
те, що не так часто використовується в Linux, але все ще використовується багато з * BSD операційними системами:
# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
Крім того sysdig
, strace
і dtrace
ви також отримали ltrace
, що записує / перехоплює сигнали / динамічні бібліотеки / системні виклики, які викликаються / приймаються процесом:
ltrace
це програма, яка просто запускає вказану команду, поки вона не завершиться. Він перехоплює та записує динамічні виклики бібліотеки, які викликаються виконаним процесом, і сигнали, які приймаються цим процесом. Він також може перехоплювати та друкувати системні дзвінки, виконані програмою.
$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) +++
Якщо програма невелика, ви також можете розглянути її демонтаж objdump -d exe_file
або розбирання / декомпіляцію Hopper
, щоб побачити всі файли, з якими вона працює.
Докладніше див. Розуміння того, що робить бінарний файл Linux
В якості першого підходу я також би зробив:
strings exe_file
Це недорогий підхід, і, на щастя, деякі імена файлів можуть просто бути присутніми в режимі ASCII у двійковому файлі з удачею.
Дивіться також відповідну відповідь Чому правдиві та неправдиві такі великі?
Якщо бінарні файли / файли, що постачаються з дистрибутивом, ви також можете отримати джерела з джерельних сховищ дистрибутива або з офіційних сховищ фактичної утиліти.
Як останній ресурс, ви завжди можете використовувати такі інструменти, як gdb або rr, для налагодження бінарного файлу в режимі реального часу.
sysdig
помилку (ви використовуєте ARM?), Будь ласка, опублікуйте нове запитання до нього.