Czy w systemie Linux iptables można zarejestrować nazwę procesu / polecenia, która inicjuje połączenie wychodzące?

27

Chciałbym śledzić procesy inicjujące połączenia wychodzące na pulpicie Linux. Najlepsze, co mogę wymyślić, to:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

Loguje to identyfikator UID / gid, który inicjuje połączenie, ale nie nazwa procesu / polecenia ani nawet pid. Gdybym mógł po prostu dostać pid, prawdopodobnie mógłbym wymyślić skrypt, który pobiera nazwę procesu, gdy dziennik jest zapisywany, ale wydaje się, że to nawet nie jest możliwe.

Idealnie chciałbym również rejestrować procesy, które akceptują połączenia przychodzące.

Jakieś pomysły, jak to możliwe z iptables [lub czymkolwiek innym] na Linux-ie?

Nack
źródło
Uważam (nie do końca pewny), że na to pytanie udzielono odpowiedzi na błąd serwera, sprawdź to.
niXar
Osobiście użyłbym sysdig do tej pracy.
Charles Duffy

Odpowiedzi:

7

Możesz napisać program do monitorowania / proc / net / tcp, którego dane wyjściowe wyglądają tak:

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

Następnie możesz powiązać otwarte porty z i-węzłami, które mogą być powiązane z procesami i deskryptorami plików, wykonując link read na deskryptorach plików wymienionych dla każdego procesu:

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

Zobacz tutaj, że i-węzeł 4847458 odpowiada pierwszemu gniazdu tcp z powyższej listy. Dane wyjściowe polecenia netstat -tapn weryfikują to dla mnie (i pamiętam, że 0x50 == 80):

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

Gdy program monitorujący zauważy zmianę w / proc / net / tcp, przeanalizuj dane i sprawdź, czy zmiana jest nowo otwartym gniazdem. Następnie możesz po prostu wyliczyć wszystkie deskryptory plików dla każdego procesu wymienionego w / proc, wykonując link read na każdym z nich, aby znaleźć pasujący i-węzeł. Gdy znajdziesz to, masz własny identyfikator, z którego możesz uzyskać wszystko, czego możesz chcieć, szczególnie jeśli masz rozliczanie procesów.

Jeśli nie potrzebujesz natychmiastowego powiadomienia, program monitorujący może użyć wolnej ankiety (być może okres 50 ms lub 100 ms, a nawet 1000 ms).

Ben Collins
źródło
2
Dziękujemy za udostępnienie opcji! Ale wymaganie odpytywania i odpytywania każdego otwartego deskryptora pliku za każdym razem nie jest bardzo niezawodne i bardzo nieefektywne. Nadal mam nadzieję, że ktoś znajdzie lepsze rozwiązanie lub wyjaśni, dlaczego nie jest to już częścią iptables i dlaczego --cmd-owner jest uważany za niemożliwy do naprawienia.
nealmcb
O ile jądro nie zmieni układu / proc lub jeśli nie zmieni się netstat i readlink lub ps (mało prawdopodobne), powiedziałbym, że jest to dość solidne. Jakiego rodzaju problemami z wydajnością się zajmujesz? Jeśli chcesz natychmiastowego przetwarzania, musisz napisać moduł jądra do użycia z iptables.
Ben Collins
Jeśli rejestruję odrzucone połączenia, gniazdo jest natychmiast niszczone przez jądro, więc mam bardzo małą szansę, aby zobaczyć je w / proc. Może tylko zmień REJECT na DROP, aby upłynął
limit
W tym scenariuszu nie pomaga to z powodu bardzo małego okna czasowego, ale jeśli chodzi o kruchość parsowania / proc, można również użyć „lsof -F -i” i uzyskać ładnie abstrakcyjny zrzut sieci dane. Można to również przefiltrować (powiedzmy, tylko na konkretnym porcie), a już wykonałeś za Ciebie mapowanie nazw plików / pid / użytkowników.
dannysauer,
9

Chcesz moduł dopasowania właściciela, który działa tylko w łańcuchu WYJŚCIE (a może PREROUTOWANIE ...?). Przeczytaj dokumenty, ale zadziała to mniej więcej tak:

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "

źródło
1
Czy komenda iptables log może ustawić i interpolować zmienną w ten sposób? Wydaje mi się, że to nie działa. Wygląda też na to, że opcja --cmd-owner została usunięta w jądrze> = 2.6.15. Jest to niefortunne, ponieważ wydaje się być przydatną opcją.
4
Tak, usunięto --cmd-owner: „naprawiono nie do naprawienia”
guettli,
1
Dzięki za informacje, @guettli. Na stronie permalink.gmane.org/... jest więcej szczegółów, które cytują więcej dziennika zmian: „[NETFILTER]: Usuń nadużycie tasklist_lock u właściciela ipt {, 6}; Oderwij dopasowanie cmd / sid / pid, ponieważ nie można go naprawić i stoi w nim sposób blokowania zmian w tasklist_lock. " Ale nadal chciałbym trochę więcej tła lub lepszych alternatyw.
nealmcb
5

Nie ma nic wspólnego z iptables ani logowaniem; ale tutaj jest „górny” interfejs, który odpytuje katalog / proc / i wyświetla przepustowość dla programu / pid:

http://sourceforge.net/projects/nethogs

„NetHogs to małe narzędzie„ net top ”. Zamiast rozbijać ruch według protokołu lub podsieci, jak większość narzędzi, grupuje przepustowość według procesów. NetHogs nie polega na ładowaniu specjalnego modułu jądra.”

Lokal
źródło
Odkryłem, że Nethogs daje niewiarygodne statystyki, ale na szczycie 2 (+ netatop) robi to dobrze.
Tobu,
1

Gdy zastanawiam się nad podobnym pytaniem, próbując ograniczyć prędkość Skype, znalazłem

$ netstat -p | grep <mycmdname>

jest dobrym sposobem na połączenie numeru portu z pid / cmd, ponieważ pid-owner / cmd-owner nie są już obsługiwane bezpośrednio w iptables; następnie musisz przeanalizować wynik, a następnie dodać regułę iptables zgodnie z portem; naturalnie będziesz potrzebować trochę kodu czyszczącego później / przy zamykaniu / ponownym uruchamianiu systemu itp .; zapisz numer portu w pliku do odwołania w czasie czyszczenia

w rzeczywistości dobrą odpowiedzią na pytanie o numery portów jest

$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

może być konieczne dostosowanie elementu grep tcp zgodnie z własnymi potrzebami

wtedy dla moich celów najłatwiej było dodać filtry tc u32 według numerów portów, wpisy w iptables według numerów portów podobne

znak
źródło