Правило IP не учитывает генерацию пакетов, как исправить?

Правило IP не учитывает генерацию пакетов, как исправить?

Проблема: IP-правило, созданное для маршрутизации трафика L4 через определенный интерфейс, не соблюдается, если пакеты генерируются с другим адресом источника.

Обзор Я хочу сгенерировать пакеты с исходным адресом, отличным от адреса хоста. Для этого я использую пакет Scapy из Python. Примечание: моя цель — отправлять и отправлять трафик DNS, однако я не смог найти простого решения, которое позволило бы мне подделывать исходный адрес в запросах DNS, поэтому я просто генерирую пакет UDP с адресом src и dst на порту 53, полагаю, это все еще работает, поскольку я тестирую только L3 и L4, а не фактический протокол DNS на данный момент. Вот мой скрипт

#!/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()

Перед запуском скрипта моя таблица маршрутизации выглядит так:

# 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

Вот 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

Когда я запускаю скрипт с помощью , ./packet-gen.py "10.0.26.122" "10.0.26.123"он работает. Это потому, что я еще не построил свое правило ip / отдельную таблицу маршрутизации. Я выполняю tcpdump на хосте (10.0.26.122) и на дальнем хосте (10.0.26.123) и вижу, что отправляется пакет UDP. Я также протестировал с помощью dig www.google.com @10.0.26.123и вижу, что выполняется реальный запрос DNS и получен ответ.

Теперь проблема. Я хочу удалить запись маршрута в основной таблице, а затем только маршрут на основе номера порта. Для этого я запускаю следующее, чтобы сначала удалить запись маршрута на 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

Запись удалена. Если я снова запущу свой скрипт, он не сработает. Запрос dig также не сработает. Это ожидаемо, так как в основной таблице маршрутизации ядра нет маршрута L3.

Для маршрутизации на L4 я сначала создал новую таблицу маршрутизации IP для отправки всего трафика через ens224:

# ip route add table 53 0.0.0.0/0 dev ens224

Затем я создаю IP-правило для захвата любого трафика, использующего порт 53, и отправляю свою пользовательскую таблицу 53.

# ip rule add ipproto udp dport 53 lookup 53

Я также создал специальное правило sysctl для rp_filter, чтобы ослабить строгие правила переадресации обратного пути.

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

Для проверки своей работы я вижу следующее:

# 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

Последняя команда показывает, что по умолчанию, если связь не DNS, используется маршрут по умолчанию.

Чтобы проверить это, я сначала пытаюсь пинговать 10.0.26.123. Он терпит неудачу, что и ожидалось. Теперь я пытаюсь выполнить запрос dig dig www.google.com @10.0.26.123, и он работает. Запрос dig попадает в правило ip перед тем, как перейти в основную таблицу, и маршрутизируется соответствующим образом. Я вижу, что трафик достигает службы с помощью tcpdump (10.0.26.123) и исходит с моего хоста (10.0.26.122).

Теперь я снова пробую запустить свой скрипт scapy, и ничего. Даже с тем же исходным адресом, что и у хоста, ничего в tcpdump на моем хосте или сервере. Я пробовал изменить исходный адрес, никаких изменений, ничего. Если я добавлю обратно основной маршрут L3 для 10.0.26.0/24 в основную таблицу, скрипт scapy снова заработает. Что я здесь упускаю? Почему мой сгенерированный трафик не будет учитывать созданные мной наборы правил ip?

решение1

Scapy не использует механизм маршрутизации ОС, а использует собственную таблицу маршрутизации ( conf.routeобъект), синхронизированную с таблицей маршрутизации ОС при запуске Scapy (или при вызове conf.route.resync()метода).

Механизм маршрутизации Scapy не поддерживает исходную маршрутизацию, что объясняет описанное вами поведение.

Связанный контент