stringtranslate.com

Filtro de paquetes Berkeley

El filtro de paquetes Berkeley ( BPF ; también filtro de paquetes BSD , BPF clásico o cBPF ) es un filtro de paquetes y derivación de red que permite capturar y filtrar paquetes de red informática a nivel del sistema operativo . Proporciona una interfaz sin formato para las capas de enlace de datos , lo que permite enviar y recibir paquetes sin procesar de la capa de enlace, [1] y permite que un proceso de espacio de usuario proporcione un programa de filtro que especifica qué paquetes desea recibir. Por ejemplo, es posible que un proceso tcpdump desee recibir solo paquetes que inicien una conexión TCP. BPF devuelve sólo paquetes que pasan el filtro que proporciona el proceso. Esto evita copiar paquetes no deseados del kernel del sistema operativo al proceso, lo que mejora enormemente el rendimiento. El programa de filtro tiene la forma de instrucciones para una máquina virtual , que se interpretan o se compilan en código de máquina mediante un mecanismo justo a tiempo (JIT) y se ejecutan en el kernel.

BPF es utilizado por programas que necesitan, entre otras cosas, analizar el tráfico de la red. Si el controlador de la interfaz de red admite el modo promiscuo , permite que la interfaz se ponga en ese modo para que se puedan recibir todos los paquetes de la red , incluso aquellos destinados a otros hosts.

El mecanismo de filtrado BPF está disponible en la mayoría de los sistemas operativos tipo Unix . A veces, BPF se utiliza para referirse solo al mecanismo de filtrado, en lugar de a toda la interfaz. Algunos sistemas, como Linux y Tru64 UNIX , proporcionan una interfaz sin formato para la capa de enlace de datos distinta de la interfaz sin formato BPF, pero utilizan los mecanismos de filtrado BPF para esa interfaz sin formato.

El kernel de Linux proporciona una versión extendida del mecanismo de filtrado BPF, llamado eBPF , que utiliza un mecanismo JIT y que se utiliza para el filtrado de paquetes, así como para otros fines en el kernel. eBPF también está disponible para Microsoft Windows . [2]

Historia

El artículo original fue escrito por Steven McCanne y Van Jacobson en 1992 mientras estaban en el Laboratorio Lawrence Berkeley . [1] [3]

Interfaz de enlace de datos sin procesar

BPF proporciona pseudodispositivos que pueden vincularse a una interfaz de red; las lecturas desde el dispositivo leerán buffers llenos de paquetes recibidos en la interfaz de red, y las escrituras en el dispositivo inyectarán paquetes en la interfaz de red.

En 2007, Robert Watson y Christian Peron agregaron extensiones de búfer de copia cero a la implementación de BPF en el sistema operativo FreeBSD , [4] permitiendo la captura de paquetes del kernel en el controlador de interrupciones del controlador del dispositivo para escribir directamente en la memoria del proceso del usuario para evitar el requisito. para dos copias de todos los paquetes de datos recibidos a través del dispositivo BPF. Si bien una copia permanece en la ruta de recepción para los procesos del usuario, esto preserva la independencia de los diferentes consumidores de dispositivos BPF, además de permitir el empaquetado de encabezados en el búfer BPF en lugar de copiar los datos completos del paquete. [5]

Filtración

Las capacidades de filtrado de BPF se implementan como un intérprete de un lenguaje de máquina para la máquina virtual BPF , una máquina de 32 bits con instrucciones de longitud fija, un acumulador y un registro de índice . Los programas en ese lenguaje pueden recuperar datos del paquete, realizar operaciones aritméticas con los datos del paquete y comparar los resultados con constantes o con datos en el paquete o bits de prueba en los resultados, aceptando o rechazando el paquete según los resultados de esos. pruebas.

BPF a menudo se extiende "sobrecargando" las instrucciones load (ld) y store (str).

Las implementaciones tradicionales de BPF tipo Unix se pueden utilizar en el espacio de usuario, a pesar de estar escritas para el espacio del kernel. Esto se logra utilizando condiciones de preprocesador .

Extensiones y optimizaciones.

Algunos proyectos utilizan conjuntos de instrucciones BPF o técnicas de ejecución diferentes a las originales.

Algunas plataformas, incluidas FreeBSD , NetBSD y WinPcap , utilizan un compilador justo a tiempo (JIT) para convertir instrucciones BPF en código nativo con el fin de mejorar el rendimiento. Linux incluye un compilador BPF JIT que está deshabilitado de forma predeterminada.

Los intérpretes en modo kernel para ese mismo lenguaje de máquina virtual se utilizan en mecanismos de capa de enlace de datos sin procesar en otros sistemas operativos, como Tru64 Unix , y para filtros de socket en el kernel de Linux y en el mecanismo de captura de paquetes WinPcap y Npcap .

Implementaciones

Se proporciona un intérprete en modo de usuario para BPF con la implementación libpcap/WinPcap/Npcap de la API pcap , de modo que, al capturar paquetes en sistemas sin soporte en modo kernel para ese mecanismo de filtrado, los paquetes se pueden filtrar en modo usuario; El código que utiliza la API pcap funcionará en ambos tipos de sistemas, aunque, en sistemas donde el filtrado se realiza en modo de usuario, todos los paquetes, incluidos los que se filtrarán, se copian del kernel al espacio del usuario. Ese intérprete también se puede utilizar al leer un archivo que contiene paquetes capturados con pcap.

Otro intérprete en modo de usuario es uBPF , que admite JIT y eBPF (sin cBPF). Su código se ha reutilizado para proporcionar soporte para eBPF en sistemas que no son Linux. [6] El eBPF de Microsoft en Windows se basa en uBPF y el verificador formal PREVAIL. [7] rBPF , una reescritura de Rust de uBPF, es utilizado por la plataforma blockchain Solana como motor de ejecución. [8]

Programación

El BPF clásico generalmente lo emite un programa a partir de alguna regla textual de muy alto nivel que describe el patrón que debe coincidir. Una de esas representaciones se encuentra en libpcap . [9] BPF y eBPF clásicos también se pueden escribir directamente como código de máquina o utilizando un lenguaje ensamblador para una representación textual. Los ensambladores notables incluyen bpf_asmla herramienta del kernel de Linux (cBPF), bpfc(cBPF) y el ubpfensamblador (eBPF). El bpftoolcomando también puede actuar como desensamblador para ambos tipos de BPF. Los lenguajes ensambladores no son necesariamente compatibles entre sí.

El código de bytes eBPF se ha convertido recientemente en un objetivo de lenguajes de nivel superior. LLVM agregó soporte para eBPF en 2014 y GCC lo siguió en 2019. Ambos kits de herramientas permiten compilar C y otros lenguajes compatibles en eBPF. También se puede compilar un subconjunto de P4 en eBPF utilizando BCC, un kit de compilación basado en LLVM. [10]

Seguridad

El ataque Spectre podría aprovechar el intérprete eBPF o el compilador JIT del kernel de Linux para extraer datos de otros procesos del kernel. [11] Una característica de refuerzo JIT en el kernel mitiga esta vulnerabilidad. [12]

El grupo chino de seguridad informática Pangu Lab dijo que la NSA utilizó BPF para ocultar las comunicaciones de red como parte de una compleja puerta trasera de Linux . [13]

eBPF

Desde la versión 3.18, el kernel de Linux incluye una máquina virtual BPF extendida con diez registros de 64 bits, denominada eBPF . Se puede utilizar para fines ajenos a la creación de redes, como por ejemplo para adjuntar programas eBPF a varios puntos de seguimiento . [14] [15] [16] Desde la versión 3.19 del kernel, los filtros eBPF se pueden conectar a sockets , [17] [18] y, desde la versión 4.1 del kernel, a clasificadores de control de tráfico para la ruta de datos de red de entrada y salida. [19] [20] La versión original y obsoleta ha sido renombrada retroactivamente a BPF clásico ( cBPF ). Hoy en día, el kernel de Linux ejecuta solo eBPF y el código de bytes cBPF cargado se traduce de forma transparente a una representación de eBPF en el kernel antes de la ejecución del programa. [21] Todo el código de bytes se verifica antes de ejecutarlo para evitar ataques de denegación de servicio. Hasta Linux 5.3, el verificador prohibía el uso de bucles para evitar tiempos de ejecución potencialmente ilimitados; Los bucles con tiempo de ejecución limitado ahora están permitidos en kernels más recientes. [22]

Ver también

Referencias

  1. ^ ab McCanne, Steven; Jacobson, Van (19 de diciembre de 1992). "El filtro de paquetes BSD: una nueva arquitectura para la captura de paquetes a nivel de usuario" (PDF) .
  2. ^ "Microsoft adopta la superherramienta eBPF del kernel de Linux y la amplía para Windows". El registro . 2021-05-11. Archivado desde el original el 11 de mayo de 2021.
  3. ^ McCanne, Steven; Jacobson, Van (enero de 1993). "El filtro de paquetes BSD: una nueva arquitectura para la captura de paquetes a nivel de usuario". USENIX .
  4. ^ "Filtro de paquetes bpf (4) Berkeley". FreeBSD . 2010-06-15.
  5. ^ Watson, Robert NM; Perón, Christian SJ (9 de marzo de 2007). "BPF de copia cero" (PDF) .
  6. ^ "ebpf genérico / ebpf genérico". GitHub . 28 de abril de 2022.
  7. ^ "microsoft/ebpf-for-windows: implementación de eBPF que se ejecuta sobre Windows". GitHub . Microsoft. 11 de mayo de 2021.
  8. ^ "Descripción general | Documentos de Solana".
  9. ^ "Sintaxis de BPF". biot.com .
  10. ^ "Sumérgete en BPF: una lista de material de lectura". qmonnet.github.io .
  11. ^ "Lectura de memoria privilegiada con canal lateral". Equipo de Proyecto Cero en Google . 3 de enero de 2018 . Consultado el 20 de enero de 2018 .
  12. ^ "bpf: introduzca la configuración BPF_JIT_ALWAYS_ON". git.kernel.org . Archivado desde el original el 19 de octubre de 2020 . Consultado el 20 de septiembre de 2021 .
  13. ^ "Anatomía de la supuesta puerta trasera de la NSA oculta en una década de primer nivel". El registro . 23 de febrero de 2022 . Consultado el 24 de febrero de 2022 .
  14. ^ "Linux kernel 3.18, Sección 1.3. Llamada al sistema bpf() para programas de máquinas virtuales eBFP". kernelnewbies.org . 7 de diciembre de 2014 . Consultado el 6 de septiembre de 2019 .
  15. ^ Jonathan Corbet (24 de septiembre de 2014). "La API de llamada al sistema BPF, versión 14". LWN.net . Consultado el 19 de enero de 2015 .
  16. ^ Jonathan Corbet (2 de julio de 2014). "Ampliación de BPF extendido". LWN.net . Consultado el 19 de enero de 2015 .
  17. ^ "Kernel de Linux 3.19, Sección 11. Redes". kernelnewbies.org . 8 de febrero de 2015 . Consultado el 13 de febrero de 2015 .
  18. ^ Jonathan Corbet (10 de diciembre de 2014). "Conexión de programas eBPF a sockets". LWN.net . Consultado el 13 de febrero de 2015 .
  19. ^ "Núcleo de Linux 4.1, Sección 11. Redes". kernelnewbies.org . 21 de junio de 2015 . Consultado el 17 de octubre de 2015 .
  20. ^ "Guía de referencia de BPF y XDP". cilio.readthedocs.io . 24 de abril de 2017 . Consultado el 23 de abril de 2018 .
  21. ^ "Guía de referencia de BPF y XDP: documentación de Cilium 1.6.5". docs.cilium.io . Consultado el 18 de diciembre de 2019 .
  22. ^ "bpf: introducir bucles acotados". git.kernel.org . 19 de junio de 2019 . Consultado el 19 de agosto de 2022 .

Otras lecturas

enlaces externos