Come posso identificare quale processo sta effettuando il traffico UDP su Linux?


39

La mia macchina effettua continuamente richieste di traffico udp dns. quello che devo sapere è il PID del processo che genera questo traffico.

Il modo normale nella connessione TCP è usare netstat / lsof e ottenere il processo associato al pid.

È UDP che la connessione è stateles, quindi quando chiamo netastat / lsof posso vederlo solo se il socket UDP è aperto e sta inviando traffico.

Ho provato con lsof -i UDPe con nestat -anpue, ma non riesco a trovare quale processo stia facendo quella richiesta perché devo chiamare lsof / netstat esattamente quando viene inviato il traffico udp, se chiamo lsof / netstat prima / dopo l'invio del datagramma udp è impossibile visualizzare il socket UDP aperto.

Chiamare netstat / lsof esattamente quando viene inviato il pacchetto 3/4 udp è IMPOSSIBILE.

Come posso identificare il famigerato processo? Ho già ispezionato il traffico per cercare di identificare il PID inviato dal contenuto del pacchetto, ma non è possibile identificarlo dal contesto del traffico.

Qualcuno può aiutarmi ?

Sono root su questa macchina FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP mer 7 lug 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

Risposte:


48

Il controllo di Linux può aiutare. Individuerà almeno utenti e processi che effettuano connessioni di rete di datagrammi. I pacchetti UDP sono datagrammi.

Innanzitutto, installa il auditdframework sulla tua piattaforma e assicurati che auditctl -lrestituisca qualcosa, anche se dice che non sono definite regole.

Quindi, aggiungi una regola per guardare la chiamata di sistema socket()e taggala per una facile ricerca in seguito ( -k). Devo presumere che tu abbia un'architettura a 64 bit, ma puoi sostituirlo b32al posto del b64se non lo sei.

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

Devi compilare pagine man e file header per creare questo, ma ciò che cattura è essenzialmente questa chiamata di sistema:, socket(PF_INET, SOCK_DGRAM|X, Y)dove il terzo parametro non è specificato ma spesso zero. PF_INETè 2 ed SOCK_DGRAMè 2. Verranno utilizzate le connessioni TCP SOCK_STREAMche verrebbero impostate a1=1. ( SOCK_DGRAMnel secondo parametro può essere ORed con SOCK_NONBLOCKo SOCK_CLOEXEC, quindi il &=confronto.) -k SOCKETÈ la nostra parola chiave che vogliamo usare quando cerchiamo audit trail in un secondo momento. Può essere qualsiasi cosa, ma mi piace mantenerlo semplice.

Lascia passare qualche momento e rivedi le piste di controllo. Facoltativamente, è possibile forzare un paio di pacchetti eseguendo il ping di un host in rete, il che provocherà una ricerca DNS, che utilizza UDP, che dovrebbe far scattare il nostro avviso di controllo.

ausearch -i -ts today -k SOCKET

Verrà visualizzato un output simile alla sezione seguente. Lo sto abbreviando per evidenziare le parti importanti

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

Nell'output sopra, possiamo vedere che il pingcomando ha causato l'apertura del socket. Potrei quindi eseguire strace -p 14510il processo, se fosse ancora in esecuzione. L' ppidID processo principale è anche elencato nel caso in cui sia uno script che genera molto il problema figlio.

Ora, se hai molto traffico UDP, questo non sarà abbastanza buono e dovrai ricorrere a OProfile o SystemTap , entrambi attualmente al di fuori della mia esperienza.

Ciò dovrebbe aiutare a restringere le cose nel caso generale.

Al termine, rimuovere la regola di controllo utilizzando la stessa riga utilizzata per crearla, sostituirla solo -acon -d.

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

lo proverò, ma penso sia la risposta giusta.
fischi

Questo non sta raccogliendo traffico che viene lasciato cadere da iptables, almeno per me.
ore 2

1
+1 per la semplicità rispetto al metodo systemtap (che è più analitico, ma necessita di pacchetti di sviluppo del kernel)
basos

23

Puoi usare netstat, ma hai bisogno dei flag giusti, e funziona solo se il processo che sta inviando i dati è ancora attivo. Non troverà le tracce di qualcosa che è venuto brevemente alla vita, ha inviato il traffico UDP, quindi è andato via. Richiede anche i privilegi di root locali. Detto ciò:

Qui sto iniziando un ncat sul mio host locale, inviando il traffico UDP alla porta 2345 su una macchina (inesistente) 10.11.12.13:

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

Ecco alcuni output di tcpdump che dimostrano che il traffico sta andando:

[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

Ecco il bit utile , usando netstat con il flag -a (per vedere i dettagli della porta) e il flag -p per vedere i dettagli dell'ID processo. È il flag -p che richiede i privilegi di root:

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

Come puoi vedere, pid 9152 ha il dito come avere una connessione aperta alla porta 2345 sull'host remoto specificato. Netstat aiuta anche a gestirlo e mi dice che il nome del processo è ncat.

Speriamo che sia di qualche utilità.


davvero bello fatto! : thumbup:
ThorstenS

2
C'è un problema però. Se il problema è causato da uno script di shell che genera un sottoprocesso che esegue la ricerca DNS e che il processo termina rapidamente, la porta di origine (57550 sopra) cambierà continuamente. In questo caso, la tecnica non funzionerà e dovrai prendere misure più drastiche. Inoltre, il tuo netstat avrebbe dovuto eseguire una procedura grep -w 57550perché più processi potrebbero eseguire ricerche DNS sullo stesso server. Il tuo metodo non li distinguerebbe.
zerolagtime

1
Sono d'accordo con entrambe le tue obiezioni, zerolagtime (ma grazie comunque per le tue gentili parole, ThorstenS!).
MadHatter supporta Monica il

17

Ho avuto esattamente lo stesso problema e sfortunatamente auditdnon ho fatto molto per me.

Ho ricevuto traffico da alcuni dei miei server verso indirizzi DNS di Google 8.8.8.8e 8.8.4.4. Ora, il mio amministratore di rete ha un lieve disturbo ossessivo compulsivo e voleva ripulire tutto il traffico non necessario poiché abbiamo le nostre cache DNS interne. Voleva disabilitare la porta 53 in uscita per tutti tranne quei server cache.

Quindi, dopo aver fallito auditctl, scavo systemtap. Mi viene in mente il seguente script:

# 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

Quindi esegui semplicemente:

stap -v udp_detect_domain.stp

Questo è l'output che ho ottenuto:

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

Questo è tutto! Dopo aver cambiatoresolv.conf quei PID, non sono stati rilevati i cambiamenti.


Spero che sia di aiuto :)


5

Ecco un'opzione systemtap, usando le sonde netfilter disponibili in stap verso 1.8 e successive. Vedi anche 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

4

Vorrei utilizzare uno sniffer di rete come tcpdump o WireShark per visualizzare le richieste DNS. Il contenuto della query può dare un'idea di quale programma li sta emettendo.


nessuna informazione nel traffico ha annusato ho appena visto.
fischi

Nessuna informazione? Pacchetti vuoti? Quello che volevo dire era che se qualcosa sta tentando di risolvere updates.java.sun.com o rss.cnn.com potresti dedurre utilmente qualcosa da esso.
RedGrittyBrick,

query DNS alla ricerca del proxy interno. in questo momento ho scoperto quale processo è, ma la domanda è ancora viva per una tecnica generale di risoluzione dei problemi
fischi

lsof -i | awk '/ UDP /'
c4f4t0r,

3

Tenere presente che quando si utilizza autitctl, ad esempio nscd utilizza un parametro leggermente diverso nella chiamata del sistema socket, quando si esegue una query DNS:

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

Quindi, per essere sicuro di catturare quelle query oltre a quelle menzionate sopra, puoi aggiungere un filtro aggiuntivo, con lo stesso nome se vuoi:

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

Qui 2050 è un OR bit a bit di SOCK_DGRAM (2) e SOCK_NONBLOCK (2048).

Quindi la ricerca troverà entrambi quei filtri con la stessa chiave SOCKET:

ausearch -i -ts today -k SOCKET

I valori esadecimali per le costanti socket che ho trovato qui: https://golang.org/pkg/syscall/#pkg-constants

Dato che non ho punti reputazione da commentare, ho aggiunto questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.