Ich möchte keine komplizierten Tools wie den AppArmor-Beschwerdemodus verwenden. Ich benötige einfache Tools, um festzustellen, auf welche Dateien ein bestimmtes Programm zugreift.
fstat()
lstat()
Ich möchte keine komplizierten Tools wie den AppArmor-Beschwerdemodus verwenden. Ich benötige einfache Tools, um festzustellen, auf welche Dateien ein bestimmtes Programm zugreift.
fstat()
lstat()
Antworten:
Per Chris Down können Sie strace -p
einen bereits laufenden Prozess untersuchen, um festzustellen, welche Dateien von jetzt an geöffnet werden, bis Sie strace beenden oder der Prozess selbst abgeschlossen ist.
Wenn Sie möchten, dass Dateien für die gesamte Dauer eines Prozesses geöffnet werden, verwenden Sie sie von Anfang an strace
mit dem Namen der ausführbaren Datei. Durch -f
das Hinzufügen wird sichergestellt, dass auch gegabelte Unterprozesse gemeldet werden. Beispiel
# 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 +++
#
Verwenden Sie, um lsof
zu sehen, welche Dateien ein Prozess derzeit geöffnet hat
# 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
[...]
#
Wenn Sie über SystemTap verfügen, können Sie den gesamten Host auf geöffnete Dateien überwachen.
[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
ist nicht der einzige relevante Systemaufruf. Beispielsweise ist es möglich, Dateideskriptoren zwischen Prozessen über einen Unix-Socket zu übergeben, und es gibt den openat
Systemaufruf, mit dem auch eine Datei geöffnet werden kann.
strace
den Zeilen ENOENT im Beispiel angezeigt.
Sie können opensnoop
von BCC verwenden, das eBPF unter der Haube verwendet:
# ./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
[...]
Dies ist ziemlich performant, da kprobes verwendet wird, anstatt wie üblich syscalls neu starten zu strace
müssen.
Sie können dies auch mit strace
(möglicherweise mit -f
, um den untergeordneten Elementen des verfolgten Prozesses zu folgen) tun , aber seine Funktionsweise, bei der Syscalls als Teil von ptrace neu gestartet werden, verlangsamt Ihre Anwendung etwas:
# 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
[...]
Sie können Ihre Anwendung bei Bedarf auch auf diese Weise starten, indem Sie strace [executable]
oder verwenden strace -f [executable]
.
Mein Lieblingswerkzeug zur Überwachung der von einer Anwendung geöffneten Dateien ist das leistungsstarke Überwachungsframework sysdig
.
Zum Überwachen aller geöffneten Dateien, die von einem Programm mit dem Namen geöffnet wurden exe_file
:
sudo sysdig -p "proc.name=exe_file %12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open
Überwachen aller auf dem Server geöffneten Dateien:
sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open
Erstellen einer Trace-Datei, die nur Schreibereignisse in Home-Verzeichnissen enthält (die wir später überprüfen können 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
Wenn Sie alles auf Syscall-Ebene sehen, führt ein Prozess mit dem Namen exe_file
Folgendes aus:
sudo sysdig proc.name=exe_file
Sysdig hat viele Meißel, sehen Sie nach interessanteren Dingen, die es tun kann:
Sie haben auch dtrace
das, was unter Linux nicht viel verwendet wird, aber mit * BSD-Betriebssystemen immer noch viel verwendet wird:
# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
Außerdem sysdig
, strace
und dtrace
Sie haben auch bekommen ltrace
, die Aufzeichnungen / abfängt Signale / dynamische Bibliotheken / Systemaufrufe , die durch einen Prozess namens / empfangen werden:
ltrace
ist ein Programm, das den angegebenen Befehl einfach ausführt, bis er beendet wird. Es fängt die dynamischen Bibliotheksaufrufe ab und zeichnet sie auf, die vom ausgeführten Prozess aufgerufen werden, und die Signale, die von diesem Prozess empfangen werden. Es kann auch die vom Programm ausgeführten Systemaufrufe abfangen und drucken.
$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) +++
Wenn das Programm klein ist, können Sie es auch zerlegen objdump -d exe_file
oder zerlegen / dekompilieren Hopper
, um alle Dateien anzuzeigen, mit denen es sich befasst.
Weitere Informationen finden Sie unter: Verstehen, was eine Linux-Binärdatei tut
Als ersten Ansatz würde ich auch tun:
strings exe_file
Dies ist ein kostengünstiger Ansatz, und mit etwas Glück können einige der Dateinamen mit etwas Glück im ASCII-Modus in der Binärdatei vorhanden sein.
Siehe auch verwandte Antwort Warum sind wahr und falsch so groß?
Bei Binärdateien / Dateien, die mit der Distribution geliefert werden, können Sie die Quellen auch aus den Quell-Repositorys der Distribution oder den offiziellen Repositorys des eigentlichen Dienstprogramms abrufen.
Als letzte Ressource können Sie immer Tools wie gdb oder rr verwenden , um die Binärdatei in Echtzeit zu debuggen.
sysdig
Fehler zu haben (verwenden Sie ARM?). Bitte stellen Sie eine neue Frage.