Jak mogę określić, który proces generuje ruch UDP w systemie Linux?

39

Moja maszyna nieustannie wysyła żądanie ruchu udp dns. co muszę wiedzieć to PID procesu generującego ten ruch.

Normalnym sposobem w połączeniu TCP jest użycie netstat / lsof i powiązanie procesu w pid.

Jest to UDP, połączenie jest stateles, więc kiedy dzwonię do netastat / lsof, widzę to tylko wtedy, gdy gniazdo UDP jest otwarte i wysyła ruch.

Próbowałem z lsof -i UDPiz nestat -anpue, ale nie mogę znaleźć wich proces robi ten wniosek, ponieważ trzeba zadzwonić lsof / netstat dokładnie kiedy ruch UDP jest Wysłano wiadomość, jeśli zgłoszę lsof / netstat przed / po datagram UDP jest Rozesłano IS nie można wyświetlić otwartego gniazda UDP.

Wywołanie netstat / lsof dokładnie wtedy, gdy wysłany jest pakiet 3/4 udp, jest NIEMOŻLIWE.

Jak rozpoznać niesławny proces? Sprawdziłem już ruch, aby spróbować zidentyfikować wysłany PID na podstawie zawartości pakietu, ale nie można go zidentyfikować na podstawie wpływu ruchu.

Czy ktoś może mi pomóc?

Jestem rootem na tym komputerze FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP Środa 7 lipca 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

wygwizdanie
źródło

Odpowiedzi:

48

Kontrola systemu Linux może pomóc. Przynajmniej zlokalizuje użytkowników i procesy wykonujące połączenia sieciowe datagramów. Pakiety UDP są datagramami.

Najpierw zainstaluj auditdplatformę na swojej platformie i upewnij się, że auditctl -lcoś zwraca, nawet jeśli mówi, że nie zdefiniowano żadnych reguł.

Następnie dodaj regułę, aby obejrzeć wywołanie systemowe socket()i oznacz ją, aby łatwo znaleźć później ( -k). Muszę założyć, że jesteś na architekturze 64-bitowej, ale można podstawić b32w miejsce b64, jeśli nie jesteś.

auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

Musisz wybrać strony socket(PF_INET, SOCK_DGRAM|X, Y)podręcznika i pliki nagłówkowe, aby to zbudować, ale to, co przechwytuje, to w zasadzie to wywołanie systemowe: gdzie trzeci parametr jest nieokreślony, ale często zerowy. PF_INETma wartość 2 i SOCK_DGRAM2. Używałby połączeń TCP, SOCK_STREAMktóre by się ustawiły a1=1. ( SOCK_DGRAMw drugim parametrze może być ORed przy pomocy SOCK_NONBLOCKlub SOCK_CLOEXEC, stąd &=porównanie). To -k SOCKETnasze słowo kluczowe, którego chcemy użyć przy późniejszym wyszukiwaniu ścieżek audytu. Może to być wszystko, ale lubię to upraszczać.

Odczekaj kilka chwil i przejrzyj ścieżki audytu. Opcjonalnie możesz wymusić kilka pakietów, wysyłając polecenie ping do hosta w sieci, co spowoduje wyszukiwanie DNS, które korzysta z UDP, co powinno wyzwolić nasz alert kontroli.

ausearch -i -ts today -k SOCKET

Pojawią się dane wyjściowe podobne do poniższej sekcji. Skracam to, aby podkreślić ważne części

type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET

Na powyższym wyjściu możemy zobaczyć, że pingpolecenie spowodowało otwarcie gniazda. Mógłbym wtedy uruchomić strace -p 14510proces, jeśli nadal był uruchomiony. ppid(Rodzic proces ID) jest również wymieniona w przypadku jest to skrypt, który ikra problem dziecko dużo.

Teraz, jeśli masz duży ruch UDP, nie będzie to wystarczająco dobre i będziesz musiał skorzystać z OProfile lub SystemTap , które są obecnie poza moją wiedzą.

To powinno pomóc zawęzić sytuację w ogólnym przypadku.

Kiedy skończysz, usuń reguły kontroli przy użyciu tej samej linii użyty do jego utworzenia, zastąpić tylko -az -d.

auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
zerolagtime
źródło
Spróbuję, ale myślę, że to właściwa odpowiedź.
boos,
To nie oznacza odbierania ruchu przez iptables, przynajmniej dla mnie.
2rs2ts
1
+1 za prostotę w porównaniu z metodą systemtap (która jest bardziej analityczna, ale wymaga pakietów
rozwijających
23

Możesz użyć netstat, ale potrzebujesz odpowiednich flag i działa to tylko wtedy, gdy proces wysyłający dane wciąż żyje. Nie znajdzie śladów czegoś, co na krótko ożyło, wysłało ruch UDP, a potem odeszło. Wymaga również lokalnych uprawnień roota. To mówi:

Oto zaczynam ncat na moim hoście lokalnym, wysyłając ruch UDP do portu 2345 na (nieistniejącej) maszynie 10.11.12.13:

[madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom

Oto niektóre dane wyjściowe tcpdump potwierdzające, że ruch się odbywa:

[root@risby ~]# tcpdump -n -n port 2345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192

Oto użyteczny bit , używając netstat z flagą -a (aby zobaczyć szczegóły portu) i flagą -p, aby zobaczyć szczegóły identyfikatora procesu. Jest to flaga -p, która wymaga uprawnień roota:

[root@risby ~]# netstat -apn|grep -w 2345
udp        0      0 192.168.3.11:57550          10.11.12.13:2345            ESTABLISHED 9152/ncat     

Jak widać, pid 9152 ma połączenie otwarte z portem 2345 na określonym hoście zdalnym. Netstat pomaga również uruchomić to przez ps i mówi mi, że nazwa procesu to ncat.

Mam nadzieję, że to się przyda.

MadHatter obsługuje Monikę
źródło
naprawdę miło zrobione! : thumbup:
ThorstenS,
2
Jest jednak pewien haczyk. Jeśli problem jest spowodowany przez skrypt powłoki odradzający podproces, który wyszukuje DNS i proces ten szybko kończy działanie, port źródłowy (57550 powyżej) cały czas się zmienia. W takim przypadku technika nie zadziała i będziesz musiał podjąć bardziej drastyczne kroki. Dodatkowo, netstat powinien był zrobić, grep -w 57550ponieważ wiele procesów może wyszukiwać DNS na tym samym serwerze. Twoja metoda ich nie rozróżnia.
zerolagtime
1
Zgadzam się z obydwoma twoimi zastrzeżeniami, zerolagtime (ale i tak dziękuję za miłe słowa, ThorstenS!).
MadHatter obsługuje Monikę
17

Miałem dokładnie ten sam problem i niestety auditdniewiele dla mnie zrobiłem.

Miałem ruch z niektórych moich serwerów w kierunku adresów DNS Google 8.8.8.8i 8.8.4.4. Teraz mój administrator sieci ma łagodny OCD i chciał wyczyścić cały niepotrzebny ruch, ponieważ mamy wewnętrzne pamięci podręczne DNS. Chciał wyłączyć port wychodzący 53 dla wszystkich oprócz serwerów pamięci podręcznej.

Więc po nieudanej próbie auditctlzagłębiam się systemtap. Wymyślam następujący skrypt:

# cat >> udp_detect_domain.stp <<EOF
probe udp.sendmsg {
  if ( dport == 53 && daddr == "8.8.8.8" ) {
    printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr)
  }
}
EOF

Następnie po prostu uruchom:

stap -v udp_detect_domain.stp

Oto wynik, który otrzymałem:

PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3506 (python) sent UDP to  8.8.8.8 53

Otóż ​​to! Po zmianie resolv.conftych PID nie wykrył zmian.


Mam nadzieję że to pomoże :)

Jakov Sosic
źródło
5

Oto opcja systemtap przy użyciu sond netfilter dostępnych w Stap verson 1.8 i nowszych. Zobacz także man probe::netfilter.ip.local_out.

# stap -e 'probe netfilter.ip.local_out {
  if (dport == 53) # or parametrize
      printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport)
}'
ping[24738] 192.168.1.10:53
ping[24738] 192.168.1.10:53
^C
fche
źródło
4

Chciałbym użyć net-sniffera, takiego jak tcpdump lub wireshark, aby wyświetlić żądania DNS. Treść zapytania może dać wyobrażenie o tym, który program je wydaje.

RedGrittyBrick
źródło
brak informacji w wąchanym ruchu, który już wyświetlam.
boos,
Brak informacji? Puste pakiety? Miałem na myśli to, że jeśli coś próbuje rozwiązać update.java.sun.com lub rss.cnn.com, możesz z tego wywnioskować.
RedGrittyBrick,
zapytanie dns szuka wewnętrznego serwera proxy. w tej chwili znalazłem, który jest proces, ale pytanie wciąż żyje dla ogólnego techniki rozwiązywania problemów
boos
lsof -i | awk '/ UDP /'
c4f4t0r
3

Należy pamiętać, że podczas korzystania z autitctl, na przykład nscd używa nieco innego parametru w wywołaniu systemowym gniazda podczas wykonywania zapytania DNS:

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

Aby upewnić się, że wychwytujesz te zapytania oprócz tych wymienionych powyżej, możesz dodać dodatkowy filtr o tej samej nazwie, jeśli chcesz:

auditctl -a exit,always -F arch=b64 -F a0=2  -F a1=2050 -S socket -k SOCKET

Tutaj 2050 jest bitową LUB SOCK_DGRAM (2) i SOCK_NONBLOCK (2048).

Następnie wyszukiwanie znajdzie oba filtry z tym samym kluczem SOCKET:

ausearch -i -ts today -k SOCKET

Znalazłem tutaj wartości szesnastkowe dla stałych gniazd: https://golang.org/pkg/syscall/#pkg-constants

Ponieważ nie mam punktów reputacji do skomentowania, dodałem to.

Silverfibre
źródło