IP-Regel beachtet Paketgenerierung nicht. Wie kann ich das beheben?

IP-Regel beachtet Paketgenerierung nicht. Wie kann ich das beheben?

Problem: IP-Regeln zum Weiterleiten von L4-Verkehr über eine bestimmte Schnittstelle werden nicht beachtet, wenn Pakete mit unterschiedlichen Quelladressen generiert werden.

Überblick Ich möchte Pakete mit einer anderen Quelladresse als der Adresse des Hosts generieren. Dazu verwende ich das Python-Paket Scapy. Hinweis: Mein Ziel ist es, DNS-Verkehr zu senden, ich konnte jedoch keine einfache Lösung finden, mit der ich die Quelladresse in DNS-Anfragen fälschen konnte. Daher generiere ich einfach ein UDP-Paket mit Quell- und Zieladresse an Port 53. Ich glaube, das funktioniert immer noch, da ich derzeit nur L3 und L4 teste und nicht das eigentliche DNS-Protokoll. Hier ist mein Skript

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

So sieht meine Routentabelle vor dem Ausführen des Skripts aus:

# 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

Hier sind die IP-Schnittstellen

# 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

Wenn ich das Skript mit ausführe, ./packet-gen.py "10.0.26.122" "10.0.26.123"funktioniert es. Das liegt daran, dass ich meine IP-Regel/separate Routing-Tabelle noch nicht erstellt habe. Ich führe einen TCPdump auf dem Host (10.0.26.122) und auf dem Host am anderen Ende (10.0.26.123) aus und sehe, wie das UDP-Paket gesendet wird. Ich habe es auch mit getestet dig www.google.com @10.0.26.123und sehe, wie eine tatsächliche DNS-Anfrage ausgeführt wird und ich bekomme eine Antwort.

Nun zum Problem. Ich möchte den Routeneintrag in der Haupttabelle entfernen und dann nur noch basierend auf der Portnummer routen. Dazu führe ich Folgendes aus, um zuerst den Routeneintrag zu 10.0.26.0/24 zu entfernen.

# 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

Der Eintrag wird entfernt. Wenn ich mein Skript erneut ausführe, funktioniert es nicht. Die Dig-Anforderung schlägt ebenfalls fehl. Dies ist zu erwarten, da in der Haupt-Routingtabelle des Kernels keine L3-Route vorhanden ist.

Zum Routing auf L4 habe ich zunächst eine neue IP-Routingtabelle erstellt, um den gesamten Datenverkehr über ens224 zu senden:

# ip route add table 53 0.0.0.0/0 dev ens224

Dann erstelle ich eine IP-Regel, um den gesamten Datenverkehr über Port 53 zu erfassen, und sende meine benutzerdefinierte Tabelle 53.

# ip rule add ipproto udp dport 53 lookup 53

Ich habe auch eine spezielle Sysctl-Regel für rp_filter erstellt, um die strengen Reverse-Path-Forwarding-Regeln zu lockern

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

Wenn ich meine Arbeit überprüfe, sehe ich Folgendes:

# 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

Der letzte Befehl zeigt, dass standardmäßig die Standardroute verwendet wird, wenn die Kommunikation nicht über DNS erfolgt.

Um dies zu testen, versuche ich zunächst, 10.0.26.123 anzupingen. Das schlägt erwartungsgemäß fehl. Jetzt versuche ich, eine Dig-Anfrage zu stellen dig www.google.com @10.0.26.123, und es funktioniert. Die Dig-Anfrage trifft die IP-Regel, bevor sie an die Haupttabelle geht, und wird entsprechend weitergeleitet. Ich sehe, dass der Datenverkehr den Dienst mit tcpdump (10.0.26.123) erreicht und von meinem Host (10.0.26.122) kommt.

Jetzt versuche ich, mein Scapy-Skript erneut auszuführen, und nichts. Selbst mit derselben Quelladresse wie der Host wird im TCPdump auf meinem Host oder dem Server nichts angezeigt. Ich habe versucht, die Quelladresse zu ändern, keine Änderung, nichts. Wenn ich die Haupt-L3-Route für 10.0.26.0/24 wieder in die Haupttabelle einfüge, funktioniert das Scapy-Skript wieder. Was übersehe ich hier? Warum beachtet mein generierter Datenverkehr die von mir erstellten IP-Regelsätze nicht?

Antwort1

Scapy verwendet nicht den Routing-Mechanismus des Betriebssystems, sondern nutzt stattdessen seine eigene Routing-Tabelle ( conf.routeObjekt), die beim Start von Scapy (oder bei jedem conf.route.resync()Aufruf der Methode) mit der Routing-Tabelle des Betriebssystems synchronisiert wird.

Der Routing-Mechanismus von Scapy unterstützt kein Source-Routing, was das von Ihnen beschriebene Verhalten erklärt.

verwandte Informationen