La regla de IP no respeta la generación de paquetes ¿Cómo solucionarlo?

La regla de IP no respeta la generación de paquetes ¿Cómo solucionarlo?

Problema: La regla ip creada para enrutar el tráfico L4 hacia una interfaz específica no se respeta cuando los paquetes se generan con una dirección de origen diferente.

Descripción general Quiero generar paquetes con una dirección de origen diferente a la dirección del host. Para lograr esto, estoy usando el paquete Scapy de Python. Nota: mi objetivo es enviar para enviar tráfico DNS, sin embargo, no pude encontrar una solución simple que me permita falsificar la dirección de origen en las solicitudes de DNS, por lo que solo estoy generando un paquete UDP con la dirección src y dst en el puerto 53. Creo que esto todavía funciona ya que solo estoy probando L3 y L4, no el protocolo DNS real en este momento. Aquí está mi guión

#!/usr/bin/python3

# The following is designed to generate a packet with a different source address

import sys 
from scapy.all import *

def main():
    S = "10.0.26.122" # spoofed source IP address
    D = "10.0.26.123" # destination IP address
    SP = 53 # source port
    DP = 53 # destination port
    payload = "This is a fake message" # packet payload

    spoofed_packet = IP(src=S, dst=D) / UDP(sport=53, dport=53) / payload
    send(spoofed_packet)

#Entry point
main()

Antes de ejecutar el script, así es como se ve mi tabla de rutas:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.26.0       0.0.0.0         255.255.255.0   U     0      0        0 ens224
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

Aquí están las interfaces ip.

# ip -br a
lo               UNKNOWN        127.0.0.1/8
ens161           UP             10.0.29.122/24
ens192           UP             10.104.8.122/24
ens193           UP             10.0.27.122/24
ens224           UP             10.0.26.122/24
ens256           UP             10.0.21.122/24
virbr0           DOWN           192.168.122.1/24
virbr0-nic       DOWN
ip_vti0@NONE     DOWN

Cuando ejecuto el script, ./packet-gen.py "10.0.26.122" "10.0.26.123"funciona. Esto se debe a que todavía no he creado mi regla de IP/tabla de enrutamiento separada. Realizo un tcpdump en el host (10.0.26.122) y en el host del otro extremo (10.0.26.123) y veo que se envía el paquete UDP. También probé dig www.google.com @10.0.26.123y vi que se estaba realizando una solicitud de DNS real y obtuve una respuesta.

Ahora el problema. Quiero eliminar la entrada de ruta en la tabla principal y luego solo la ruta según el número de puerto. Para hacer esto ejecuto lo siguiente para eliminar primero la entrada de ruta a 10.0.26.0/24.

# ip route del 10.0.26.0/24 dev ens224
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

Se elimina la entrada. Si ejecuto mi script nuevamente, no funciona. La solicitud de excavación también falla. Esto es de esperarse ya que no hay una ruta L3 en la tabla de enrutamiento del núcleo principal.

Para enrutar en L4, primero creé una nueva tabla de rutas IP para enviar todo el tráfico a través de ens224:

# ip route add table 53 0.0.0.0/0 dev ens224

Luego creo una regla de IP para capturar cualquier tráfico usando el puerto 53 y envío mi tabla personalizada 53.

# ip rule add ipproto udp dport 53 lookup 53

También creé una regla sysctl especial para rp_filter y relajé demasiado las reglas estrictas de reenvío de ruta inversa.

# sysctl -w "net.ipv4.conf.ens224.rp_filter=2"

Para comprobar mi trabajo veo lo siguiente:

# ip route list table 53
default dev ens224 scope link
# ip rule list
0:      from all lookup local
32765:  from all ipproto udp dport 53 lookup 53
32766:  from all lookup main
32767:  from all lookup default
# ip route get 10.0.26.123 ipproto udp dport 53
10.0.26.123 dev ens224 table 53 src 10.0.26.122 uid 0
    cache
# ip route get 10.0.26.123
10.0.26.123 via 10.104.8.1 dev ens192 src 10.104.8.122 uid 0
    cache

El último comando muestra que, de forma predeterminada, si la comunicación no es dns, use la ruta predeterminada.

Para probar esto, primero intento hacer ping a 10.0.26.123. Falla lo que se esperaba. Ahora intento realizar una solicitud de excavación dig www.google.com @10.0.26.123y funciona. La solicitud de excavación alcanza la regla ip antes de ir a la tabla principal y se enruta adecuadamente. Veo que el tráfico llega al servicio con tcpdump (10.0.26.123) y proviene de mi host (10.0.26.122).

Ahora intento ejecutar mi script scapy nuevamente y nada. Incluso con la misma dirección de origen que el host, no hay nada en tcpdump en mi host o en el servidor. Intenté cambiar la dirección de origen, no hubo cambios, nada. Si vuelvo a agregar la ruta principal L3 para 10.0.26.0/24 en la tabla principal, el script scapy vuelve a funcionar. ¿Que me estoy perdiendo aqui? ¿Por qué mi tráfico generado no respeta los conjuntos de reglas de IP que creé?

Respuesta1

Scapy no utiliza el mecanismo de enrutamiento del sistema operativo, sino que utiliza su propia tabla de enrutamiento ( conf.routeobjeto), sincronizada desde la tabla de enrutamiento del sistema operativo cuando se inicia Scapy (o cada vez que conf.route.resync()se llama al método).

El mecanismo de enrutamiento de Scapy no admite el enrutamiento de origen, lo que explica el comportamiento que usted describe.

información relacionada