Lista plików, do których program ma dostęp

64

time to genialne polecenie, jeśli chcesz dowiedzieć się, ile czasu zajmuje procesor.

Szukam czegoś podobnego, który może wyświetlić listę plików, do których program i jego dzieci mają dostęp. Albo w czasie rzeczywistym, albo jako raport później.

Obecnie używam:

#!/bin/bash

strace -ff -e trace=file "$@" 2>&1 | perl -ne 's/^[^"]+"(([^\\"]|\\[\\"nt])*)".*/$1/ && print'

ale kończy się niepowodzeniem, jeśli polecenie do uruchomienia dotyczy sudo. Nie jest zbyt inteligentny (byłoby miło, gdyby mógł wyświetlać tylko listę istniejących plików, które miały problemy z uprawnieniami lub pogrupować je w odczytywane pliki i zapisywane). straceJest również powolny, więc dobrze by było z szybszym wyborem.

Ole Tange
źródło
Biorąc pod uwagę twoje użycie strace, zakładam, że jesteś szczególnie zainteresowany Linuksem. Poprawny?
Gilles,
Linux jest moim głównym zmartwieniem.
Ole Tange

Odpowiedzi:

51

Zrezygnowałem i kodowałem własne narzędzie. Cytując z jego dokumentów:

SYNOPSIS
    tracefile [-adefnu] command
    tracefile [-adefnu] -p pid

OPTIONS
    -a        List all files
    -d        List only dirs
    -e        List only existing files
    -f        List only files
    -n        List only non-existing files
    -p pid    Trace process id
    -u        List only files once

Wysyła tylko pliki, więc nie musisz zajmować się danymi wyjściowymi strace.

https://gitlab.com/ole.tange/tangetools/tree/master/tracefile

Ole Tange
źródło
dzięki! Wyjście strace jest absolutnie nieczytelne. Nie wiem jednak, gdzie znaleźć dokumenty - byłoby miło, gdyby miał opcję pomocy -h / -. Doceniłbym również opcję, która pokazuje tylko edycje plików, a nie dostęp.
Xerus
@ Xerus Clone gitlab.com/ole.tange/tangetools i uruchom make && sudo make install. Potem możesz biec man tracefile.
Ole Tange
4
Niezłe narzędzie. Zapakowałem go, aby zainstalować: yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmiyum -y install tracefile
Danila Vershinin
27

Możesz śledzić wywołania systemowe strace, ale rzeczywiście istnieje nieunikniona kara za prędkość. Musisz uruchomić stracejako root, jeśli polecenie działa z podwyższonymi uprawnieniami:

sudo strace -f -o foo.trace su user -c 'mycommand'

Inna metoda to prawdopodobnie szybciej jest przekręceniem biblioteki, który owija się wokół funkcji dostępu do systemu plików: LD_PRELOAD=/path/to/libmywrapper.so mycommand. LD_PRELOADZmienna środowiskowa nie zostanie przekazana do programów wywołany z podwyższonymi uprawnieniami. Musiałbyś napisać kod tej biblioteki opakowań ( oto przykład z „Budowania pośredników bibliotek dla zabawy i zysku” ); Nie wiem, czy w sieci dostępny jest kod wielokrotnego użytku.

Jeśli monitorujesz pliki w określonej hierarchii katalogów, możesz utworzyć widok systemu plików za pomocą LoggedFS, tak aby wszystkie dostępy przez ten widok były rejestrowane.

loggedfs -c my-loggedfs.xml /logged-view
mycommand /logged-view/somedir

Aby skonfigurować LoggedFS, zacznij od przykładowej konfiguracji dostarczonej z programem i przeczytaj składnię pliku konfiguracyjnego LoggedFS .

Inną możliwością jest podsystem kontroli systemu Linux . Upewnij się, że auditddemon jest uruchomiony, a następnie skonfiguruj, z czym chcesz się zalogować auditctl. Każda zarejestrowana operacja jest rejestrowana w /var/log/audit/audit.log(w typowych dystrybucjach). Aby rozpocząć oglądanie określonego pliku:

auditctl -a exit,always -w /path/to/file

Jeśli umieścisz zegarek w katalogu, pliki w nim i jego podkatalogi będą również rekurencyjnie oglądane. Uważaj, aby nie oglądać katalogu zawierającego dzienniki kontroli. Możesz ograniczyć rejestrowanie do niektórych procesów, zobacz auditctlstronę podręcznika dla dostępnych filtrów. Musisz być rootem, aby korzystać z systemu kontroli.

Gilles
źródło
LD_PRELOADnie działa również na statycznych plikach binarnych.
David Biorąc pod uwagę
6

Myślę, że chcesz lsof (prawdopodobnie dołączony do grepa w programie i to dzieci). Powie ci każdy plik, który jest aktualnie dostępny w systemie plików. Aby uzyskać informacje o tym, do których plików można uzyskać dostęp przez proces ( stąd ):

lsof -n -p `pidof your_app`
unclejamil
źródło
11
Ale to tylko migawka. Potrzebuję tylko plików, do których próbował uzyskać dostęp. Pomyśl o sytuacji, w której program odmawia uruchomienia, ponieważ mówi „brak pliku”. Jak dowiedzieć się, jakiego pliku szukał?
Ole Tange
2

Próbowałem tego tracefile. Dla mnie dało to znacznie mniej wyników niż moje własne strace ... | sed ... | sort -u. Dodałem nawet -s256do strace(1)wiersza poleceń, ale niewiele to pomogło ...

Potem spróbowałem loggedfs. Po pierwsze nie powiodło się, ponieważ nie miałem dostępu do odczytu / zapisu do katalogu, w którym próbowałem się zalogować. Po tymczasowym zrobieniu chmod 755 dostałem kilka hitów ...

Ale dla mnie najlepsze wydaje się wykonanie następujących czynności:

inotifywait -m -r -e OPEN /path/to/traced/directory

A następnie przetwarzaj dane wyjściowe po przetworzeniu interesującego Cię procesu.

Nie łapie to dostępu do procesu procesowego dostępu do katalogu śledzonego ani nie wie, czy jakiś inny proces uzyskał dostęp do tego samego drzewa katalogów, ale w wielu przypadkach jest to wystarczające narzędzie do wykonania zadania.

EDYCJA: inotifywait nie przechwytuje dostępu do dowiązań symbolicznych (tylko cele po rozwiązaniu dowiązań symbolicznych). Uderzyło mnie to, gdy zarchiwizowałem biblioteki, do których program ma dostęp w przyszłości. Użyłem dodatkowej globalnej hackery w Perlu, aby wybrać dowiązania symboliczne wzdłuż powiadomionych bibliotek, aby wykonać zadanie w tym konkretnym przypadku.

EDYCJA 2: przynajmniej podczas powiadamiania samych plików i dowiązań symbolicznych z wiersza poleceń inotifywait (np. inotifywait -m file symlinkLub inotifywait symlink file) pokaże dostęp do tego, który z nich jest pierwszy w wierszu poleceń (niezależnie od tego, który filez nich symlinkjest dostępny). inotifywait nie obsługuje IN_DONT_FOLLOW - co, gdy próbowałem programowo, pozwala tylko zobaczyć dostęp file(który może, ale nie musi, być tym, czego się spodziewa ...) niezależnie od kolejności w wierszu poleceń

Tomi Ollila
źródło
„Dla mnie dało to znacznie mniej wyników niż moje własne” Czy możesz podać przykład tracefilebraku dostępu do pliku?
Ole Tange
Nie jestem pewien, o co dokładnie pytasz:) ... Jeśli spróbuję poszukać plików wewnątrz / path / to / traced / directory / Widzę OPEN w danych wyjściowych inotify ... ALE stat (1) w plikach wydaje się aby nie uzyskać wyników w kilku przypadkach, które próbowałem (zastanawiam się, dlaczego buforowanie ukrywa zawartość katalogu czytając z widoku)
Tomi Ollila
Komentuję poniższy post fanotify (mam tylko 21 reputacji, chociaż mam konto od ponad dekady; wymaganie 50 do komentowania zawsze było dla mnie przeszkodą ...) - fanotify to dobra rzecz, ale nie może obejść problem dereferencji dowiązań symbolicznych (tj. w przypadku dowiązań symbolicznych, końcowy plik, do którego uzyskano dostęp, można znaleźć, czytając / proc / self / fd / <fd> .. w każdym razie +1: wpisując odpowiedź: D
Tomi Ollila
1

Chociaż może nie dać ci wystarczającej kontroli (jeszcze?) Napisałem program, który przynajmniej częściowo spełnia twoje potrzeby, używając fanotify i nieudostępniania jądra linux-to do monitorowania tylko plików zmodyfikowanych (lub odczytanych) przez określony proces i jego potomków . W porównaniu do strace jest dość szybki (;

Można go znaleźć na https://github.com/tycho-kirchner/shournal

Przykład na powłoce:

$ shournal -e sh -c 'echo hi > foo1; echo hi2 > foo2'
$ shournal -q --history 1
  # ...
  Written file(s):                                                                                                                                                                              
 /tmp/foo1 (3 bytes) Hash: 15349503233279147316                                                                                                                                             
 /tmp/foo2 (4 bytes) Hash: 2770363686119514911    
ikra
źródło