Filtro de paquetes Berkeley

Interfaz para las capas de enlace de datos en un sistema tipo Unix
Filtro de paquetes Berkeley
Desarrollador(es)Steven McCanne, Van Jacobson
Lanzamiento inicial19 de diciembre de 1992 ; hace 31 años ( 19 de diciembre de 1992 )
Sistema operativoMúltiple

El filtro de paquetes Berkeley ( BPF ; también filtro de paquetes BSD , BPF clásico o cBPF ) es un filtro de paquetes y toma de red que permite capturar y filtrar paquetes de red informática a nivel de sistema operativo . Proporciona una interfaz sin procesar 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 especifique qué paquetes desea recibir. Por ejemplo, un proceso tcpdump puede querer recibir solo paquetes que inicien una conexión TCP. BPF devuelve solo paquetes que pasan el filtro que proporciona el proceso. Esto evita copiar paquetes no deseados del núcleo 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 compilan en código de máquina mediante un mecanismo justo a tiempo (JIT) y se ejecutan en el núcleo.

BPF es utilizado por programas que necesitan, entre otras cosas, analizar el tráfico de red. Si el controlador de la interfaz de red admite el modo promiscuo , permite poner la interfaz 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 únicamente al mecanismo de filtrado, en lugar de a la interfaz completa. Algunos sistemas, como Linux y Tru64 UNIX , proporcionan una interfaz sin procesar a la capa de enlace de datos distinta de la interfaz sin procesar BPF, pero utilizan los mecanismos de filtrado BPF para esa interfaz sin procesar.

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]

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 añadieron extensiones de búfer de copia cero a la implementación de BPF en el sistema operativo FreeBSD [4] , lo que permite que la captura de paquetes del núcleo en el controlador de interrupciones del controlador del dispositivo escriba directamente en la memoria del proceso del usuario para evitar el requisito de dos copias para todos los datos de paquetes 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 del dispositivo BPF, además de permitir el empaquetado de encabezados en el búfer BPF en lugar de copiar los datos de paquetes completos. [5]

Filtración

Las capacidades de filtrado de BPF se implementan como un intérprete para 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 obtener datos del paquete, realizar operaciones aritméticas con los datos del paquete y comparar los resultados con constantes o con datos del paquete o bits de prueba en los resultados, aceptando o rechazando el paquete en función de los resultados de esas pruebas.

BPF a menudo se amplía "sobrecargando" las instrucciones de carga (ld) y almacenamiento (str).

Las implementaciones tradicionales de BPF similares a Unix se pueden utilizar en el espacio de usuario, a pesar de estar escritas para el espacio del núcleo. Esto se logra mediante condiciones de preprocesador .

Extensiones y optimizaciones

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

Algunas plataformas, incluidas FreeBSD , NetBSD y WinPcap , utilizan un compilador JIT (just-in-time ) para convertir las instrucciones BPF en código nativo con el fin de mejorar el rendimiento. Linux incluye un compilador JIT BPF 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 sockets en el kernel de Linux y en el mecanismo de captura de paquetes WinPcap y Npcap .

Implementaciones

Se proporciona un intérprete de 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 de modo kernel para ese mecanismo de filtrado, los paquetes se pueden filtrar en modo de 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 aquellos que se filtrarán, se copian desde el kernel al espacio de usuario. Ese intérprete también se puede utilizar al leer un archivo que contiene paquetes capturados utilizando pcap.

Otro intérprete en modo usuario es uBPF , que admite JIT y eBPF (sin cBPF). Su código se ha reutilizado para proporcionar compatibilidad con 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 uBPF en Rust, es utilizado por la plataforma de cadena de bloques 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] El BPF clásico y el eBPF 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 la herramienta del kernel de Linux bpf_asm(cBPF), bpfc(cBPF) y el ubpfensamblador (eBPF). El bpftoolcomando también puede actuar como un desensamblador para ambas versiones 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 los lenguajes de alto nivel. LLVM agregó compatibilidad con eBPF en 2014, y GCC lo hizo 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 del kernel de Linux o el compilador JIT para extraer datos de otros procesos del kernel. [11] Una función de refuerzo JIT en el kernel mitiga esta vulnerabilidad. [12]

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

BPFE

Desde la versión 3.18, el núcleo Linux incluye una máquina virtual BPF extendida con diez registros de 64 bits, denominada eBPF . Se puede utilizar para fines no relacionados con la red, como para adjuntar programas eBPF a varios puntos de seguimiento . [14] [15] [16] Desde la versión 3.19 del núcleo, los filtros eBPF se pueden adjuntar a sockets , [17] [18] y, desde la versión 4.1 del núcleo, 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 núcleo Linux ejecuta solo eBPF y el bytecode cBPF cargado se traduce de forma transparente a una representación eBPF en el núcleo antes de la ejecución del programa. [21] Todo el bytecode se verifica antes de la ejecución 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 tiempos de ejecución limitados ahora están permitidos en núcleos más recientes. [22]

Véase 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 extiende para Windows". The Register . 2021-05-11. Archivado desde el original el 2021-05-11.
  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. ^ "bpf(4) Filtro de paquetes Berkeley". FreeBSD . 15 de junio de 2010.
  5. ^ Watson, Robert NM; Peron, Christian SJ (9 de marzo de 2007). "BPF de copia cero" (PDF) .
  6. ^ "generic-ebpf/generic-ebpf". 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 BPF". biot.com .
  10. ^ "Sumerjase en BPF: una lista de material de lectura". qmonnet.github.io .
  11. ^ "Lectura de memoria privilegiada con un canal lateral". Equipo de Project Zero en Google . 3 de enero de 2018. Consultado el 20 de enero de 2018 .
  12. ^ "bpf: introduce 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 una supuesta puerta trasera de alto nivel de la NSA oculta durante una década". The Register . 23 de febrero de 2022 . Consultado el 24 de febrero de 2022 .
  14. ^ "Linux kernel 3.18, Sección 1.3. bpf() syscall for eBFP virtual machine programs". 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 llamadas al sistema BPF, versión 14". LWN.net . Consultado el 19 de enero de 2015 .
  16. ^ Jonathan Corbet (2 de julio de 2014). "Extendiendo el BPF extendido". LWN.net . Consultado el 19 de enero de 2015 .
  17. ^ "Núcleo 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). «Attaching eBPF programs to sockets» (Cómo adjuntar programas eBPF a sockets). LWN.net . Consultado el 13 de febrero de 2015 .
  19. ^ "Linux kernel 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". cilium.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: introduce bucles delimitados". git.kernel.org . 19 de junio de 2019 . Consultado el 19 de agosto de 2022 .

Lectura adicional

  • 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) .
  • bpf(4) –  Manual de interfaces del kernel de FreeBSD : un ejemplo de BPF convencional
  • bpfc, un compilador de Berkeley Packet Filter, desensamblador JIT de BPF para Linux (parte de netsniff-ng)
  • Documentación de BPF para el kernel de Linux
  • Documentación de filtros de Linux, tanto para formatos de bytecode cBPF como eBPF
Obtenido de "https://es.wikipedia.org/w/index.php?title=Filtro_de_paquetes_Berkeley&oldid=1232558196"