ip 规则不尊重数据包生成如何修复?

ip 规则不尊重数据包生成如何修复?

问题: 当使用不同源地址生成数据包时,不会遵守为将 L4 流量路由出特定接口而构建的 ip 规则。

概述 我想生成源地址与主机地址不同的数据包。为了实现这一点,我使用 python 的包 Scapy。注意:我的目标是发送 DNS 流量,但是我无法找到一个简单的解决方案来欺骗 DNS 请求中的源地址,因此我只是在端口 53 处生成带有 src 和 dst 地址的 UDP 数据包,相信这仍然有效,因为我目前只测试 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 规则/单独的路由表。我在主机 (10.0.26.122) 和远端主机 (10.0.26.123) 上执行 tcpdump,并且看到正在发送的 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

该条目被删除。如果我再次运行我的脚本,它就不起作用。挖掘请求也失败。这是预期的,因为主内核路由表中没有 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

我还为 rp_filter 创建了一个特殊的 sysctl 规则,过于放松严格的反向路径转发规则

# 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,则使用默认路由。

为了测试这一点,我首先尝试 ping 10.0.26.123。它失败了,这是预期的。现在我尝试执行挖掘请求dig www.google.com @10.0.26.123,并且它有效。 dig 请求在进入主表之前符合 ip 规则并被适当路由。我看到流量通过 tcpdump (10.0.26.123) 到达服务,并且来自我的主机 (10.0.26.122)。

现在我尝试再次运行我的 scapy 脚本,但什么也没发生。即使与主机具有相同的源地址,我的主机或服务器上的 tcpdump 中也没有任何内容。我尝试更改源地址,没有更改,什么也没有。如果我在主表中添加回 10.0.26.0/24 的主 L3 路由,scapy 脚本将再次运行。我在这里缺少什么?为什么我生成的流量不遵守我创建的 IP 规则集?

答案1

Scapy 不使用操作系统路由机制,而是使用自己的路由表(对象),在 Scapy 启动时(或每当调用方法时)conf.route从操作系统路由表同步。conf.route.resync()

Scapy 的路由机制不支持源路由,这解释了您所描述的行为。

相关内容