¿Cómo ver el tráfico de red solicitado por una aplicación específica?

Si tienes el teléfono rooteado, ve a por las herramientas de línea de comandos nethogs (para la monitorización en vivo) o iptables (para obtener estadísticas). El uso de VPN o aplicaciones basadas en las estadísticas de Android es la única solución posible sin raíz. O consulte esta respuesta para una solución basada en logcat/dumpsys.

En primer lugar, el seguimiento de un UID o PID de un flujo de red no es sencillo porque estos no son parámetros relacionados con la red, sino con el sistema operativo. Existen propuestas y proyectos abandonados.

Android asigna un UID único a cada aplicación instalada al igual que cada usuario humano en Linux tiene un UID. Así que podemos capturar los paquetes enviados por un UID específico a través de las interfaces de red para rastrear el uso.

TCPDUMP:

¿Ahora cómo podemos capturar el tráfico de red? La mayoría de los sniffers de red utilizan la familia libpcap de bibliotecas independientes del sistema para este propósito. Soporta BSD Packet Filter (BPF) para el filtrado de paquetes en el núcleo. Algunas utilidades populares que utilizan libpcap son tcpdump, nmap, tshark/wireshark, dumpcap, nethogs etc. Las utilidades de red de la aplicación Android y otras también hacen uso de tcpdump.

Sin embargo, la información del UID no se propaga a través del canal AF_PACKET/PF_PACKET que utiliza pcap en la capa 2 de OSI. Así que lo que podemos hacer aquí es hacer uso de los sockets de red (combinación de IP y puerto) que son creados y utilizados por una app. netstat -tup o ss -tup mostrarán todos los sockets de red con conexiones activas/establecidas. Ambas herramientas están disponibles en Android (o puedes conseguir un binario estático), ss es la más nueva. La información de socket vs. UID también se puede leer directamente desde /proc/net/{tcp,udp}. La aplicación Android Netstat Plus funciona según el mismo principio. Esto proporcionará la dirección local (socket) que está siendo utilizado por un proceso.

Una vez que sabemos qué sockets están siendo utilizados por una aplicación (UID), tcpdump -i wlan0 src <IP> and port <PORT> volcará todo el tráfico originado por ese proceso.
De manera similar, un socket remoto (si no está conectado por múltiples aplicaciones) también se puede utilizar para filtrar los resultados.

LIMITACIONES:

Sin embargo, hay algunos problemas con este enfoque:

  • Las aplicaciones Android suelen lanzar más de un proceso a la vez en paralelo, es decir, múltiples PIDs trabajando bajo el mismo UID. Así que tenemos que capturar el tráfico de todos los procesos.
  • Las aplicaciones siguen creando y eliminando sockets. Mantener un seguimiento de los sockets que cambian continuamente es casi imposible, especialmente cuando hay un gran número de aplicaciones que acceden a la red simultáneamente.
  • Hay – aunque rara – posibilidad de que los sockets locales sean compartidos por múltiples procesos en los sistemas operativos tipo UNIX. Los sockets remotos compartidos, como el UDP/53 que se utiliza para la resolución de DNS, no pueden ser rastreados por un solo proceso. Esto debilita aún más el enfoque.

NetHogs atraviesa procfs y hace frente a las limitaciones anteriores (aunque no siempre con mucho éxito):

IPTABLES:

Las deficiencias descritas anteriormente de una herramienta de Capa 2 se pueden mitigar utilizando iptables LOG o NFLOG. La Capa 2 está justo por encima de la Capa Física, es decir, es lo último que encuentran los paquetes antes de salir del dispositivo. Por eso, al estar en la Capa de Enlace de Datos y trabajar en un nivel inferior de la pila de la red, BPF es una especie de mecanismo de filtrado de paquetes sin estado en comparación con netfilter / iptables que trabaja en la Capa 3 de OSI (más cerca de los programas de espacio de usuario). Así que iptables también puede obtener información de la pila TCP/IP (Capa 4). Filtra los paquetes basados en los UIDs de sus creadores usando el módulo owner que interactúa con los sockets para encontrar la propiedad del paquete.

iptables escribe en el registro del kernel que puede ser leído usando dmesg o logcat. El UID de una aplicación puede ser obtenido usando alguna aplicación o leído desde /data/system/packages.list o pm list packages -U.

# iptables -I OUTPUT -m owner --uid-owner <UID> -j LOG --log-level 7 --log-prefix 'SNIFFER: ' --log-uid# dmesg -w | grep SNIFFER

La salida puede ser guardada en un archivo y formateada usando herramientas como grep, awk, printf etc. Network Log -aunque muy anticuado- funciona de manera similar. AFWall+ es un cortafuegos basado en iptables que puede registrar / notificar la actividad de red de una aplicación cuando ésta se bloquea.

La única desventaja de este enfoque es que no se puede utilizar para olfatear el tráfico de un proceso cuando hay varios procesos que se ejecutan con el mismo UID. iptables No puede capturar paquetes basados en PIDs. Decidieron no usar iptables con procesos porque el proceso se inicia antes de ser bloqueado/esnifado, y el programa podría fácilmente generar un proceso hijo con un nuevo PID que no sería bloqueado/esnifado. Además, los PIDs se crean y destruyen tan rápido como los sockets. Así que siempre hay espacio para que el tráfico se filtre.

QTAGUID:

owner el módulo no funcionará para el tráfico entrante o reenviado porque los paquetes IP no llevan información de propiedad. Para medir el uso de la red entrante/saliente por aplicación, Android parcheó el kernel para incluir el módulo qtaguid. Podemos leer las estadísticas de /proc/net/xt_qtaguid/stats. Con algunas secuencias de comandos de shell obtener el uso de datos en vivo desde el reinicio:

Sin embargo, en Android 9+, qtaguid está siendo reemplazado con BPF extendido (que también está previsto para reemplazar netfilter marco en el kernel de Linux). Relacionado: ¿Qué proceso es el responsable de capturar el uso de datos?

IPTABLES + TCPDUMP:

Una alternativa es poner el tráfico saliente de una app en un grupo NFLOG y posteriormente tcpdump captura los paquetes de ese grupo:

# iptables -I OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30# tcpdump -i nflog:30

Esto es para asegurar que nos acercamos a la capa física al olfatear el tráfico saliente. Pero todavía puede dar falsos positivos, por ejemplo, si los paquetes se caen / se pierden en las tablas de enrutamiento. Por eso los sniffers trabajan en la capa 2 de OSI. O incluso mejor es observar desde el exterior, por ejemplo, utilizando un servidor proxy / VPN o en un PC conectado o en el router. Pero esto no capturará el tráfico por UID/PID.

Otras opciones:

  • Utilice herramientas de diagnóstico como strace para rastrear syscalls relacionados con la actividad de red de un proceso. force_bind y tracedump también funcionan con el mismo principio. El subsistema de auditoría del kernel de Linux se puede utilizar para lo mismo.
  • Utilizar el clasificador de red cgroup con iptables NETFILTER_XT_MATCH_CGROUP para olfatear el tráfico de cierto(s) proceso(s).
  • Utilizar Network Namespaces para aislar procesos y leer el uso de datos por interfaz. nstrace funciona con el mismo principio.
  • Si la intención es enteramente bloquear el tráfico originado por ciertos procesos, SELinux y seccomp pueden ser usados para restringir la capacidad de los procesos de crear sockets definiendo restricted policies y suppressing syscalls respectivamente.

La mayoría de estas opciones no son directamente viables para Android y requieren configuraciones avanzadas.

APIs de Android (OPCIONES NO ROOT):

Algunas aplicaciones como NetGuard utilizan la API VpnService de Android para bloquear el tráfico en la capa 3 (interfaz TUN). La app puede «notificar cuando una aplicación accede a internet». La captura y el seguimiento por aplicación (1, 2) es posible utilizando la API VPN, ya que Android hace uso de UIDs y SOcket_MARKs (1, 2) para controlar el tráfico en la política de enrutamiento de la red (RPDB), justo antes de salir del dispositivo.

Algunas aplicaciones como NetLive hacen uso de NetworkStatsManager, pero se retrasa en el uso en tiempo real y «no se actualiza con la suficiente rapidez», está «pensada para proporcionar datos históricos».