¿Cómo puedo identificar qué proceso está haciendo tráfico UDP en Linux?

39

Mi máquina realiza continuamente solicitudes de tráfico udp dns. lo que necesito saber es el PID del proceso que genera este tráfico.

La forma normal en la conexión TCP es usar netstat / lsof y obtener el proceso asociado en el pid.

En UDP, la conexión es de estado, por lo tanto, cuando llamo a netastat / lsof, puedo verlo solo si el socket UDP está abierto y está enviando tráfico.

He intentado con lsof -i UDPy con nestat -anpue, pero no puedo encontrar qué proceso está haciendo esa solicitud porque necesito llamar a lsof / netstat exactamente cuando se envía el tráfico udp, si llamo a lsof / netstat antes / después de que se envíe el datagrama udp es imposible ver el socket UDP abierto.

Llame a netstat / lsof exactamente cuando se envíe el paquete 3/4 udp es IMPOSIBLE.

¿Cómo puedo identificar el infame proceso? Ya he inspeccionado el tráfico para tratar de identificar el PID enviado del contenido del paquete, pero no es posible identificarlo desde el contenido del tráfico.

Alguien puede ayudarme ?

Soy root en esta máquina FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64 # 1 SMP mié 7 de julio 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

abucheos
fuente

Respuestas:

48

La auditoría de Linux puede ayudar. Al menos localizará a los usuarios y procesos que realizan conexiones de red de datagramas. Los paquetes UDP son datagramas.

Primero, instale el auditdmarco en su plataforma y asegúrese de que auditctl -ldevuelva algo, incluso si dice que no hay reglas definidas.

Luego, agregue una regla para ver la llamada del sistema socket()y etiquétela para encontrarla más tarde ( -k). Necesito suponer que está en una arquitectura de 64 bits, pero puede sustituirla b32en lugar de la b64que no está.

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

Tiene que elegir entre las páginas man y los archivos de encabezado para construir esto, pero lo que captura es esencialmente esta llamada al sistema: socket(PF_INET, SOCK_DGRAM|X, Y)donde el tercer parámetro no está especificado pero con frecuencia es cero. PF_INETes 2 y SOCK_DGRAMes 2. Se usarían conexiones TCP SOCK_STREAMque establecerían a1=1. ( SOCK_DGRAMen el segundo parámetro se puede ORar con SOCK_NONBLOCKo SOCK_CLOEXEC, de ahí la &=comparación). Esta -k SOCKETes nuestra palabra clave que queremos usar al buscar pistas de auditoría más adelante. Puede ser cualquier cosa, pero me gusta que sea simple.

Deje pasar unos momentos y revise las pistas de auditoría. Opcionalmente, puede forzar un par de paquetes haciendo ping a un host en la red, lo que provocará una búsqueda de DNS, que utiliza UDP, que debería disparar nuestra alerta de auditoría.

ausearch -i -ts today -k SOCKET

Y aparecerá una salida similar a la siguiente sección. Lo estoy abreviando para resaltar las partes importantes

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

En el resultado anterior, podemos ver que el pingcomando provocó que se abriera el socket. Entonces podría ejecutar strace -p 14510el proceso, si todavía se estaba ejecutando. El ppid(ID de proceso principal) también aparece en caso de que sea un script que genera mucho el problema secundario.

Ahora, si tiene mucho tráfico UDP, esto no será lo suficientemente bueno y tendrá que recurrir a OProfile o SystemTap , que actualmente están más allá de mi experiencia.

Esto debería ayudar a reducir las cosas en el caso general.

Cuando haya terminado, elimine la regla de auditoría utilizando la misma línea que usó para crearla, solo sustitúyala -apor -d.

auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
zerolagtime
fuente
Lo intentaré, pero creo que es la respuesta correcta.
abucheos el
Esto no está captando el tráfico que cae iptables, al menos para mí.
2rs2ts
1
+1 por la simplicidad en comparación con el método systemtap (que es más analítico, pero necesita paquetes de desarrollo del núcleo)
basos
23

Puede usar netstat, pero necesita los indicadores correctos, y solo funciona si el proceso que envía los datos aún está activo. No encontrará los rastros de algo que cobró vida brevemente, envió tráfico UDP y luego desapareció. También requiere privilegios de raíz local. Eso dijo:

Aquí estoy comenzando un ncat en mi host local, enviando tráfico UDP al puerto 2345 en una máquina (inexistente) 10.11.12.13:

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

Aquí hay algunos resultados de tcpdump que prueban que el tráfico va:

[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

Aquí está el bit útil , usando netstat con el indicador -a (para ver los detalles del puerto) y el indicador -p para ver los detalles del ID del proceso. Es la bandera -p que requiere privilegios de root:

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

Como puede ver, el pid 9152 tiene una conexión abierta al puerto 2345 en el host remoto especificado. Netstat también lo ejecuta útilmente a través de ps y me dice que el nombre del proceso es ncat.

Esperemos que sea de alguna utilidad.

MadHatter apoya a Monica
fuente
muy bien hecho! : thumbup:
ThorstenS
2
Sin embargo, hay una trampa. Si el problema es causado por un script de shell que genera un subproceso que realiza la búsqueda de DNS y ese proceso se cierra rápidamente, entonces el puerto de origen (57550 arriba) cambiará todo el tiempo. En este caso, la técnica no funcionará y tendrá que tomar medidas más drásticas. Además, su netstat debería haber hecho un grep -w 57550porque múltiples procesos podrían estar haciendo búsquedas DNS en el mismo servidor. Su método no los distinguiría.
zerolagtime
1
Estoy de acuerdo con sus dos objeciones, zerolagtime (¡pero gracias por sus amables palabras de todos modos, ThorstenS!).
MadHatter apoya a Monica el
17

Tuve exactamente el mismo problema y desafortunadamente auditdno hizo mucho por mí.

Tenía tráfico de algunos de mis servidores que se dirigía a las direcciones DNS de Google, 8.8.8.8y 8.8.4.4. Ahora, mi administrador de red tiene un TOC leve y quería limpiar todo el tráfico innecesario ya que tenemos nuestros cachés DNS internos. Quería deshabilitar el puerto de salida 53 para todos excepto los servidores de caché.

Entonces, después de fallar con auditctl, cavo en systemtap. Se me ocurre el siguiente 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

Luego simplemente ejecuta:

stap -v udp_detect_domain.stp

Este es el resultado que obtuve:

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

¡Eso es! Después de cambiar resolv.confesos PID no recogí los cambios.


Espero que esto ayude :)

Jakov Sosic
fuente
5

Aquí hay una opción de systemtap, usando las sondas netfilter disponibles en stap verson 1.8 y posteriores. Ver también 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
fuente
4

Usaría un sniffer de red como tcpdump o wireshark para ver las solicitudes de DNS. El contenido de la consulta puede dar una idea de qué programa los emite.

RedGrittyBrick
fuente
ninguna información en el tráfico olfateó que ya solo veo.
abucheos
¿Sin información? Paquetes vacíos? Lo que quise decir es que, si algo intenta resolver updates.java.sun.com o rss.cnn.com, podría inferir algo útil de él.
RedGrittyBrick
consulta dns buscando el proxy interno. en este momento encontré cuál es el proceso, pero la pregunta sigue viva para una técnica general de resolución de problemas
abucheos del
lsof -i | awk '/ UDP /'
c4f4t0r
3

Tenga en cuenta que cuando se usa autitctl, nscd, por ejemplo, usa un parámetro ligeramente diferente en la llamada del sistema de socket, al hacer una consulta DNS:

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

Por lo tanto, para asegurarse de capturar esas consultas además de las que se mencionaron anteriormente, puede agregar un filtro adicional, con el mismo nombre si lo desea:

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

Aquí 2050 es un OR bit a bit de SOCK_DGRAM (2) y SOCK_NONBLOCK (2048).

Luego, la búsqueda encontrará ambos filtros con la misma clave SOCKET:

ausearch -i -ts today -k SOCKET

Los valores hexadecimales para las constantes de socket que encontré aquí: https://golang.org/pkg/syscall/#pkg-constants

Como no tengo puntos de reputación que comentar, agregué esto.

Silverfibre
fuente