프로그램이 액세스하는 파일을 표시하는 도구는 무엇입니까?


12

AppArmor 불평 모드와 같은 복잡한 도구를 사용하지 않고 특정 프로그램에서 어떤 파일에 액세스하는지 알려주는 쉬운 도구가 필요합니다.


7
어떤 운영 체제에서?
— Jeff Schaller

또한 읽기, 쓰기, 추가, 정보 입수 fstat()또는 lstat()정보 등 어떤 방식으로 프로그램이 파일에 액세스 할 것으로 예상하는지 설명하는 데 유용 할 수 있습니다 .
— Sergiy Kolodyazhnyy

수세와 우분투
— Boll19

내가 알아야 할 방법은 없습니다. fstat () 또는 lstat () 프로그래밍 중입니까?
— Boll19

Sergiy Kolodyazhnyy의 의견 즉, 프로그램이 파일의 길이, 수정 날짜, 권한 또는 기타 속성을 확인하지만 파일의 데이터에 액세스하지 않는 경우 "파일에 액세스"한 것으로 간주합니까?
— telcoM

답변:


12

Chris Down에서는 이미 실행중인 프로세스 strace -p를 검사하여 strace를 종료하거나 프로세스 자체가 완료 될 때까지 지금부터 어떤 파일을 여는 지 확인할 수 있습니다.

프로세스 의 전체 기간 동안 열린 파일을 보려면 처음부터 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"
[...]
#

2
open유일한 관련 시스템 호출이 아닙니다. 예를 들어, 유닉스 소켓을 통해 프로세스간에 파일 디스크립터를 전달할 openat수 있으며 파일을 열 수 있는 시스템 호출이 있습니다.
— kasperd

---- SIGUSR1 {si_signo = SIGUSR1, si_code = SI_TKILL, si_pid = 6026, si_uid = 1002} ---- 그게 뭐죠
— Boll19

kaspers, strace 출력 명령에서 'openat'만 검색해야합니까?
— Boll19

'strace'출력에도 파일을 열려고 시도했지만 파일이 존재하지 않을 수 있습니까?
— Boll19

존재하지 않기 때문에 파일이 열리지 않는 Boll19 파일은 즐겁게보고됩니다 strace. 예제의 ENOENT 행을 참조하십시오.
— 스티브

5

opensnoop후드 아래에서 eBPF를 사용하는 BCC에서 사용할 수 있습니다 .

# ./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의 일부로 syscall을 다시 시작하는 작동 방식은 응용 프로그램의 속도를 다소 느리게합니다.

# 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].


5

응용 프로그램이 여는 파일을 모니터링하는 데 가장 좋아하는 도구는 강력한 모니터링 프레임 워크 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많은 리눅스에서 사용되지 않습니다,하지만 여전히 * 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 과 같은 도구를 사용 하여 바이너리를 실시간으로 디버깅 할 수 있습니다 .


aaa43bb66 : ~ # sudo proc.name = exe_file sysdig -p "% 12user.name % 6proc.pid % 12proc.name % 3fd.num % fd.typechar % fd.name"evt.type = open 드라이버 에러를로드 할 수 없습니다 / dev / sysdig0 장치 열기 루트 자격 증명이 있고 sysdig-probe 모듈이로드되어 있는지 확인하십시오.
— Boll19

/ * <pre> aaa43bb66 : ~ # sudo proc.name = exe_file sysdig -p "% 12user.name % 6proc.pid % 12proc.name % 3fd.num % fd.typechar % fd.name"evt.type = open 사용할 수 없습니다 / dev / sysdig0 장치를 여는 드라이버 오류를로드합니다. 루트 자격 증명이 있고 sysdig-probe 모듈이로드되어 있는지 확인하십시오. <code> * /
— Boll19

@ Boll19 오류가 발생하여 수정했습니다. 이 메시지는 sysdig버그 에 관한 것 같습니다 (ARM을 사용하고 있습니까?). 새로운 질문을 게시하십시오.
— Rui F Ribeiro
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.