机器(物理或虚拟)是否可以接受和处理来自已知设备的具有不同 IP 地址的 UDP 数据包?

机器(物理或虚拟)是否可以接受和处理来自已知设备的具有不同 IP 地址的 UDP 数据包?

首先,感谢您阅读下一个问题。

我有脚本,(ipUDP欺骗工具),这是 Ruby 中的客户端/服务器脚本(在初始化时,您可以选择参数 1 作为服务器,参数 0 作为客户端...例如“sudo ruby​​ sandbox.rb 1”初始化服务器)将创建并发送/接收使用 UDP 协议的 RAW 数据包,这些数据包具有不同的 IP 地址(不同的源地址和不同的目标地址)。

我在本地测试了这个脚本,它可以正常工作。客户端向服务器发送 UDP 数据包(其 IP 地址目标不同于服务器地址)。服务器接收数据包并将其发送回客户端(其 IP 地址目标不同于客户端)。客户端收到了数据包。=)(注意!在 .rb 脚本中我执行:

@socket.setsockopt(套接字::SOL_SOCKET,套接字::SO_BINDTODEVICE,'lo')

但是,如果我在两台机器之间进行测试(在本例中是在两台运行 Ubuntu 的虚拟机之间,使用 VirtualBox),它不起作用 :(

两个虚拟机都通过网络连接到 NAT 适配器(用于访问外部网络)和仅主机适配器,配置如下:

IPv4 Address: 192.169.56.1
IPvV4 Mask: 255.255.255.0
and the DHCP Server:
  Server Address:192.168.56.100
  Server Mask: 255.255.255.0
  Lower addr: 192.168.56.101
  Upper addr: 192.168.56.254

因此我们有以下配置:

VM1:
eth2      Link encap:Ethernet  HWaddr 08:00:27:49:ed:67
          inet addr:192.168.56.101  Bcast:192.168.56.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe49:ed67/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:218 errors:0 dropped:0 overruns:0 frame:0
          TX packets:119 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:39517 (39.5 KB)  TX bytes:18680 (18.6 KB)

VM2:
eth2      Link encap:Ethernet  HWaddr 08:00:27:af:b7:49
          inet addr:192.168.56.102  Bcast:192.168.56.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:feaf:b749/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:168 errors:0 dropped:0 overruns:0 frame:0
          TX packets:131 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:29459 (29.4 KB)  TX bytes:19725 (19.7 KB)

所以我做的第一件事就是更改 ruby​​ 脚本:

@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BINDTODEVICE, 'eth2')

接下来我(我不知道这是否正确)在两个虚拟机上检查并将 IP 路由表更改为如下形式:

>>route --s
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
10.0.2.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
192.168.56.0    0.0.0.0         255.255.255.0   U     1      0        0 eth2

>>sudo route del default eth0
>>sudo route add default gw 192.168.56.1 eth2

>>route --s
0.0.0.0         192.168.56.1    0.0.0.0         UG    0      0        0 eth2
10.0.2.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
192.168.56.0    0.0.0.0         255.255.255.0   U     1      0        0 eth2

在本例中我将网关定义为 192.168.56.1

在阅读了大量有关 IP 欺骗/iptables/arptables 等的博客之后..我编写了一个脚本(并应用于两个虚拟机)来更改一些变量、参数和规则,以便我的虚拟机接受来自未知 IP 地址的包,如下所示:

#Changing /proc/sys/net/ variables

 echo 1 > /proc/sys/net/ipv4/ip_forward
 echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
 echo 1 > /proc/sys/net/ipv4/ip_dynaddr

 echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
 echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
 echo 0 > /proc/sys/net/ipv4/conf/all/arp_filter
 echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
 echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
 echo 1 > /proc/sys/net/ipv4/conf/all/arp_notify
 echo 1 > /proc/sys/net/ipv4/conf/all/arp_accept
 echo 0 > /proc/sys/net/ipv4/conf/all/bootp_relay
 echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

 echo 1 > /proc/sys/net/ipv4/conf/eth2/forwarding
 echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter
 echo 0 > /proc/sys/net/ipv4/conf/eth2/arp_filter
 echo 0 > /proc/sys/net/ipv4/conf/eth2/arp_announce
 echo 0 > /proc/sys/net/ipv4/conf/eth2/arp_ignore
 echo 1 > /proc/sys/net/ipv4/conf/eth2/arp_notify
 echo 1 > /proc/sys/net/ipv4/conf/eth2/arp_accept
 echo 0 > /proc/sys/net/ipv4/conf/eth2/bootp_relay
 echo 1 > /proc/sys/net/ipv4/conf/eth2/log_martians

sudo echo 1 > /proc/sys/net/ipv4/conf/default/forwarding
sudo echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
sudo echo 0 > /proc/sys/net/ipv4/conf/default/arp_filter
sudo echo 0 > /proc/sys/net/ipv4/conf/default/arp_announce
sudo echo 0 > /proc/sys/net/ipv4/conf/default/arp_ignore
sudo echo 1 > /proc/sys/net/ipv4/conf/default/arp_notify
sudo echo 1 > /proc/sys/net/ipv4/conf/default/arp_accept
sudo echo 0 > /proc/sys/net/ipv4/conf/default/bootp_relay
sudo echo 1 > /proc/sys/net/ipv4/conf/default/log_martians

#Ip tables
 iptables -L -n -v

#Cleaning/Zeros/Flushing IP Tables:
 iptables -t filter -F
 iptables -t filter -X
 iptables -t nat -F
 iptables -t nat -X
 iptables -t mangle -F
 iptables -t mangle -X

 iptables -t filter -Z INPUT
 iptables -t filter -Z OUTPUT
 iptables -t filter -Z FORWARD
 iptables -t nat -Z PREROUTING
 iptables -t nat -Z POSTROUTING
 iptables -t nat -Z OUTPUT
 iptables -t mangle -Z INPUT
 iptables -t mangle -Z OUTPUT
 iptables -t mangle -Z FORWARD

#Setting Policies
#Table filter
 iptables -t filter -P INPUT ACCEPT
 iptables -t filter -P OUTPUT ACCEPT
 iptables -t filter -P FORWARD DROP
#Table nat
 iptables -t nat -P PREROUTING ACCEPT
 iptables -t nat -P OUTPUT ACCEPT
 iptables -t nat -P POSTROUTING ACCEPT
#Table mangle
 iptables -t mangle -P PREROUTING ACCEPT
 iptables -t mangle -P POSTROUTING ACCEPT
 iptables -t mangle -P OUTPUT ACCEPT

#Chain's rules

#before routing
 iptables -t raw -A PREROUTING -i eth2 -p udp -j ACCEPT
 iptables -t mangle -A PREROUTING -i eth2 -p udp  -j ACCEPT
 iptables -t nat -A PREROUTING -p udp -i eth2 -j ACCEPT

#after routing decision
iptables -t mangle -A INPUT -p udp  -j ACCEPT
iptables -A INPUT -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp -i eth2 -j ACCEPT
iptables -A INPUT -j ACCEPT

#IT SHOULD BE IN LOCAL PROCESS IN THIS MOMENT!#

#OUTPUT
iptables -t raw -A OUTPUT -p udp -o eth2 -j ACCEPT
iptables -t mangle -A OUTPUT -p udp -o eth2 -j ACCEPT
iptables -t nat -A OUTPUT -p udp -o eth2 -j ACCEPT
iptables -A OUTPUT -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p udp -o eth2 -j ACCEPT
iptables -t mangle -A POSTROUTING -p udp -o eth2 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth2 -j ACCEPT

#DEBUGGING (to see in /var/log/kern.log)
modprobe ipt_LOG
iptables -t raw -A PREROUTING -p udp -j LOG --log-prefix "FW:RAW-PREROUTING->>>"
iptables -t nat -A PREROUTING -p udp -j LOG --log-prefix "FW:NAT-PREROUTING->>>"
iptables -A INPUT -p udp -j LOG --log-prefix "FW:INPUT>>>"
iptables -A OUTPUT -p udp -j LOG --log-prefix "FW:OUTPUT>>>"
iptables -t mangle -A POSTROUTING -p udp -j LOG --log-prefix "FW:MANGLE-POST:ROUTING->>>"
iptables -t raw -A OUTPUT -p udp -j LOG --log-prefix "FW:RAW-OUTPUT->>>"
iptables -t nat -A POSTROUTING -p udp -j LOG --log-prefix "FW:NAT-POST:ROUTING->>>"

#End

我根据 Netfilter 和 General Networking 中的数据包流创建了此规则流程图

分析后内核日志,我看到包从客户端发送到服务器,但没有一个包到达服务器。

服务器(kernel.log):

<Empty>

客户端(kernel.log):

Feb 22 17:40:29 rnode1-VirtualBox kernel: [16884.120010] FW:RAW-OUTPUT->>>IN= OUT=eth2 SRC=192.168.33.120 DST=192.168.33.121 LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF P$
Feb 22 17:40:29 rnode1-VirtualBox kernel: [16884.120026] FW:MANGLE-POST:ROUTING->>>IN= OUT=eth2 SRC=192.168.33.120 DST=192.168.33.121 LEN=44 TOS=0x00 PREC=0x00 TTL=64 $

然后我用WireShark查看设备中的 UDP 数据包流(eth2)我看到客户端发送了一个 ARP 请求(询问这个 IP 是谁的?),服务器没有回复。

因此,我阅读了更多信息,并在两台虚拟机上执行了以下命令:

ifconfig eth2 promisc
ifconfig eth2 -arp

但它不起作用...:(

所以,

> Am I doing something wrong and really stupid? 
> Or 
> Am I missing something around? 
> Or 
> Is VirtualBox's DHCP server (on Host-only adapter) blocking the packets? 
> Or 
> Is the problem before iptables? 
> Or
> What I'm trying to do is impossible?

在此先致以最诚挚的谢意,如果有人能帮我解决这个小问题我将不胜感激。

贡萨洛

答案1

尝试将这些虚拟机上的“主机专用适配器”更改为“内部网络”。主机专用适配器仅允许虚拟机与 VirtualBox 主机系统本身通信,而“内部网络”允许虚拟机与虚拟机之间的通信。

相关内容