netfilter: descartar paquetes que tengan opciones de IP

netfilter: descartar paquetes que tengan opciones de IP

Me gustaría agregar una regla para descartar un IPv4paquete que IP optionsiga al encabezado. Entiendo que IHLel campo (Longitud del encabezado de Internet) en el encabezado contiene la cantidad de palabras de 32 bits en el encabezado IPv4, incluidas las opciones. Entonces, tengo entendido que una regla debe obtener la longitud del paquete + opciones del IHLcampo y compararla con 20 (longitud del encabezado IPv4 sin opciones), y si es mayor que 20, descartar el paquete.

¿Existe un iptablesmódulo específico que permita inspeccionar IPel encabezado y evaluar (realizar operaciones aritméticas)?

Respuesta1

iptablesincluye el u32método de coincidencia que permite realizar algunas operaciones bit a bit (pero no aritméticas arbitrarias), comparaciones de rango y algunas direcciones indirectas similares a punteros en la carga útil del paquete para coincidir con las condiciones:

u32

U32 prueba si cantidades de hasta 4 bytes extraídas de un paquete tienen valores específicos. La especificación de qué extraer es lo suficientemente general como para encontrar datos en compensaciones determinadas de los encabezados o cargas útiles de TCP.

Tiene su propia gramática de sublenguaje y se deben examinar la gramática y los ejemplos del manual.

DIHes el tamaño del encabezado IP (en fragmentos de 32 bits en lugar de bytes) y es parte de los primeros 32 bits del encabezado (4 bits para la versión con valor 0x04 para IPv4 seguido de los 4 bits para el DIH) y, por lo tanto, si no hay opción, este tamaño debe ser el tamaño mínimo: 20 (bytes) / 4 (bytes por palabras de 32 bits), por lo que IHL = 5 (palabras de 32 bits). No manejaré casos no válidos donde el DIH < 5, la pila IPv4 ya debería haberse encargado de esto.

Esto se traduce en:

  • tomar el primer valor de 32 bits
  • enmascararlo para la parte del DIH
  • cambialo 24 bits
  • comparar la igualdad con 5 (invertir el resultado con !el partido)

Entonces, para descartar ese paquete entrante coniptables:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 >> 24 = 5' -j DROP

sin inversión (en su lugar, coincide con 6 o más):

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 >> 24 = 6:0xF' -j DROP

El manual tiene un ejemplo similar en el que se desplaza 24 bits y luego se multiplica por 4 (por lo que se desplaza solo 22 bits) para tener bytes y no palabras de 32 bits (porque los u32punteros utilizados posteriormente usan direcciones de 8 bits), para recuperar el inicio de la carga útil de la capa 4 y continuar para operaciones posteriores:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0"

El primer 0 significa leer los bytes 0-3, >>22 significa desplazar esos 22 bits a la derecha. Cambiar 24 bits daría el primer byte, por lo que solo 22 bits son cuatro veces más más algunos bits más. &3C luego elimina los dos bits adicionales a la derecha y los primeros cuatro bits del primer byte. Por ejemplo, si IHL=5, entonces el encabezado IP tiene 20 (4 x 5) bytes de longitud.
[...]

dando para el caso de OP:

iptables -A INPUT -m u32 ! --u32 '0 >> 22 & 0x3C = 20' -j DROP

sin inversión (y sin importarle el hecho de que el primer siguiente valor posible no es 21 sino 24 ni el valor máximo exacto siempre que el valor dado sea mayor):

iptables -A INPUT -m u32 --u32 '0 >> 22 & 0x3C = 21:0xFF' -j DROP

El primer método podría simplificarse en:

  • tomar el primer valor de 32 bits
  • enmascararlo para la parte del DIH
  • compare la igualdad con (5<<24), es decir, compare con 0x05000000 (ídem)

donación:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 = 0x05000000' -j DROP

o:

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 = 0x06000000:0x0F000000' -j DROP

o incluso:

  • tomar el primer valor de 32 bits
  • compare el valor con el rango entre 0x45000000 y 0x45FFFFFF para confirmar (IPv4siemprecomienza con 4 y se debe ignorar cualquier valor posterior a la parte del DIH) o entre 0x46000000 y 0x4FFFFFFF para no estar bien.

donación:

iptables -A INPUT -m u32 ! --u32 '0 = 0x45000000:0x45FFFFFF' -j DROP

o:

iptables -A INPUT -m u32 --u32 '0 = 0x46000000:0x4FFFFFFF' -j DROP

Elige tu elección.

información relacionada