[英]Mininet script sending traffic from virtual machine's IP instead of host machines'
在 python3/mininet 腳本中,我有一個經過測試的有效主機及其 IP 地址字典。 對於每個鍵 - 通過迭代dictOfAllHostsAndIPs.keys()
- 我在每個模擬主機的終端上執行一個腳本
host.cmd(os.system( "python3 ./traffic_generator.py %s" % <my_args>))
這個腳本將隨機數據包發送到從模擬網絡上的 IP 列表中隨機選擇的 IP 地址 - 它使用 echo 非常隨機地生成流量,將一些數據通過管道傳輸到 netcat,然后將其分發到通常不使用的端口上:
os.system("echo -n '%s'" % data_string + " | nc %s 1299" % str(random_ip))
)
我的問題是,當我在網絡上的每個交換機上啟動數據包嗅探器(主要是tshark )時,在 TCP 幀數據的結果日志中,我在第一行看到它們都來自我的 VM 的 IP (192.168.119.133)而不是主機(10.0.0.XX),並且在以太網/源代碼行中,我總是獲得VM本身而不是虛擬機的MAC地址。
# frame# /time(epoch) / source ip → dest ip / ports: src → dest
> 8 0.063202633 192.168.119.133 → 10.0.0.1 TCP 74 40370 → 1299
> Ethernet II, Src: VMware_34:8e:de (00:0c:29:34:8e:de), Dst:
> VMware_fa:1a:ac (00:50:56:fa:1a:ac)
> Destination: VMware_fa:1a:ac (00:50:56:fa:1a:ac)
> Address: VMware_fa:1a:ac (00:50:56:fa:1a:ac)
>
> Source: VMware_34:8e:de (00:0c:29:34:8e:de)
> Address: VMware_34:8e:de (00:0c:29:34:8e:de)
我在日志中看到的幀的源部分中唯一發生變化的是 VM 發送數據包的端口,該端口始終介於 35000 和 49999(或者可能是 50k 之類)之間。 (請參閱上面日志的第一行, ports: src
)
我最初假設正在使用的每個端口都專門用於從不同的模擬主機發送流量,但它們太多了,而且它們不會保持不變,因此顯然不是這種情況。
沒有立即意識到這一點(其他一切看起來仍然正常:數據包目的地和我需要檢查我的研究項目的所有其他參數),然后我實現了我的代碼的模塊化、線程重構。 所以現在我查看我的程序不同版本的日志,它們都有相同的問題,無論我如何運行流量生成腳本(舊版本)或流量生成器對象的實例化(新版本),所以這個問題是不依賴於我的腳本結構的這一方面。
我多次檢查並擺弄我的電話,四次檢查我迭代的列表(然后是字典,然后再次列出),以便讓各個機器運行流量生成代碼, for hosts in list(net.get(hosts)): host.cmd(<action>)
最新版本是這樣的:
listOfTGs = []
### Create a list of threads for parallel execution
listOfThreads = []
for host in dictOfAllHostsAndIPs.keys():
### Create a trafficGenerator object on the mininet machine, then call commands on host
listOfTGs.append(tg.TrafficGenerator(durationFromArgument, host.name, callable_ips_list, net))
for tg_instance in listOfTGs:
listOfThreads.append(tg_instance.threadedExecution())
print(listOfThreads)
for th in listOfThreads:
th.start()
我可以確認(在經過 maaaany 基於打印的仔細調試時間之后),生成流量的操作與所有其他操作一樣,對每個模擬主機並行執行一次,每個主機的正確標識在標准輸出中可見。 而且,我在嗅探數據包時獲得的 IP 是 VM 本身之一,而不是應該出現的主機之一。 在其他研究人員的論文中,我看到他們在嗅探分析中正確地使用了它,所以這不僅僅是“迷你網以這種方式做的事情”(為了確定,我進行了調查)。
TL;DR:我的問題是,被發送的數據包的來源是我在其上啟動 mininet 模擬的 VM 本身,而不是被模擬的主機,我稱之為流量生成過程的主機。
我想我看到了源代碼中發生了什么,但我還沒有運行框架來確認它。
看起來 mininet 為每個節點都設置了NAT 規則:
self.cmd( 'iptables -I FORWARD',
'-i', self.localIntf, '-d', self.subnet, '-j DROP' )
self.cmd( 'iptables -A FORWARD',
'-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
self.cmd( 'iptables -A FORWARD',
'-o', self.localIntf, '-d', self.subnet, '-j ACCEPT' )
self.cmd( 'iptables -t nat -A POSTROUTING',
'-s', self.subnet, "'!'", '-d', self.subnet,
'-j MASQUERADE' )
# Instruct the kernel to perform forwarding
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
所以基本上,如果流量的目的地在節點子網之外,則應用 NAT (MASQUAERADE) 規則。 假設這也發生在根網絡命名空間中,那么所有出站流量都經過 NAT(即:采用最后一跳的 IP)。
iptables -t nat -L
查看您的根命名空間 NAT 規則。 如果您看到 MASQUERADE 條目,那么這就是您遇到問題的 NAT 規則ip netns list
看到各個命名空間。 我相信他們應該只是被標記為數字。ip netns exec $NETNSNAME iptables -t nat -L
。 遵守更多的 NAT 規則。除了 NAT 規則之外,問題的另一個可能來源是 mininet 不是從節點的網絡命名空間執行命令,而是從根命名空間執行命令。 這也應該很容易測試。
ip netns list
看到各個命名空間。 我相信他們應該只是被標記為數字。ip netns exec $NETNSNAME ip addr show
。 觀察 IP 地址。ip netns exec $NETNSNAME bash -c "echo -n $DATASTRING | nc $RANDOMIP 1299"
其中您已經擁有 DATASTRING 和 RANDOMIP 的 BASH 變量放。如果您觀察到的流量仍然具有 VM 的 src IP,則可能是 NAT 規則導致了問題。 如果它有節點的 IP,那么 mininets 沒有在正確的命名空間中執行命令。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.