regra de ip não respeita a geração de pacotes como consertar?

regra de ip não respeita a geração de pacotes como consertar?

Problema: A regra IP criada para rotear o tráfego L4 para fora de uma interface específica não é respeitada quando os pacotes são gerados com endereços de origem diferentes.

Visão geral Quero gerar pacotes com um endereço de origem diferente do endereço do host. Para fazer isso, estou usando o pacote Scapy do python. Nota: meu objetivo é enviar para enviar tráfego DNS, porém não consegui encontrar uma solução simples que me permitisse falsificar o endereço de origem nas solicitações DNS, então estou apenas gerando um pacote UDP com endereço src e dst na porta 53, acredito que isso ainda funciona, pois estou testando apenas L3 e L4, não o protocolo DNS real no momento. Aqui está meu roteiro

#!/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 executar o script, esta é a aparência da minha tabela de rotas:

# 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

Aqui estão as 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

Quando executo o script, ./packet-gen.py "10.0.26.122" "10.0.26.123"ele funciona. Isso ocorre porque ainda não construí minha regra de IP/tabela de roteamento separada. Eu executo um tcpdump no host (10.0.26.122) e no host extremo (10.0.26.123) e vejo o pacote UDP sendo enviado. Também testei dig www.google.com @10.0.26.123e vi uma solicitação de DNS real sendo executada e obtive uma resposta.

Agora o problema. Quero remover a entrada da rota na tabela principal e, em seguida, rotear apenas com base no número da porta. Para fazer isso, executo o seguinte para primeiro remover a entrada da rota para 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

A entrada é removida. Se eu executar meu script novamente, ele não funcionará. A solicitação dig também falha. Isto é esperado porque não há rota L3 na tabela de roteamento principal do kernel.

Para rotear em L4, primeiro criei uma nova tabela de rotas IP para enviar todo o tráfego via ens224:

# ip route add table 53 0.0.0.0/0 dev ens224

Em seguida, crio uma regra de IP para capturar qualquer tráfego usando a porta 53 e envio minha tabela personalizada 53.

# ip rule add ipproto udp dport 53 lookup 53

Eu também criei uma regra sysctl especial para rp_filter para afrouxar regras estritas de encaminhamento de caminho reverso

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

Para verificar meu trabalho, vejo o seguinte:

# 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

O último comando mostra que por padrão se a comunicação não for DNS, use a rota padrão.

Para testar isso, primeiro tento executar ping em 10.0.26.123. Ele falha, o que é esperado. Agora tento realizar uma solicitação dig dig www.google.com @10.0.26.123e funciona. A solicitação dig atinge a regra ip antes de ir para a tabela principal e é roteada adequadamente. Vejo o tráfego chegar ao serviço com tcpdump (10.0.26.123) e vindo do meu host (10.0.26.122).

Agora tento executar meu script scapy novamente e nada. Mesmo com o mesmo endereço de origem do host, nada no tcpdump no meu host ou no servidor. Tentei alterar o endereço de origem, sem alteração, nada. Se eu adicionar novamente a rota L3 principal para 10.0.26.0/24 na tabela principal, o script scapy funcionará novamente. O que estou perdendo aqui? Por que meu tráfego gerado não respeita os conjuntos de regras de IP que criei?

Responder1

O Scapy não usa o mecanismo de roteamento do SO, mas usa sua própria tabela de roteamento ( conf.routeobjeto), sincronizada a partir da tabela de roteamento do SO quando o Scapy é iniciado (ou sempre que conf.route.resync()o método é chamado).

O mecanismo de roteamento do Scapy não oferece suporte ao roteamento de origem, o que explica o comportamento que você descreve.

informação relacionada