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


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 모드로 표시 될 수 있습니다.

관련 답변 참조 왜 참과 거짓이 그렇게 큰가?

배포와 함께 제공되는 바이너리 / 파일 인 경우 배포의 소스 리포지토리 또는 실제 유틸리티의 공식 리포지토리에서 소스를 가져올 수도 있습니다.

마지막 리소스로 gdbrr 과 같은 도구를 사용 하여 바이너리를 실시간으로 디버깅 할 수 있습니다 .


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.