橋接兩個 Tap 接口

橋接兩個 Tap 接口

我是個菜鳥,這是我第一次嘗試內核網路。我正在嘗試在兩個介面之間創建一座橋tap,並嘗試發送流量。它更像是實驗,而不是為了任何特定目的。

$ brctl showstp br0
br0
bridge id      8000.46846e0c0ff9
designated root    8000.46846e0c0ff9
root port         0            path cost          0
max age          20.00         bridge max age        20.00
hello time        2.00         bridge hello time      2.00
forward delay        15.00         bridge forward delay      15.00
ageing time         300.00
hello timer           1.98         tcn timer          0.00
topology change timer     0.00         gc timer         115.04
flags          


tap1 (1)
port id        8001            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8001            forward delay timer   10.34
designated cost       0            hold timer         0.98
flags          

tap2 (2)
port id        8002            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8002            forward delay timer    0.00
designated cost       0            hold timer         0.98
flags          

我已經創建了橋樑 br0tap1tap2添加了兩者。我有一個程式將 ARP 封包注入tap1使用libpcap. Wireshark 正確顯示進入的資料包tap1。但是,沒有資料包出現在 處tap2。我嘗試在 ebtables 中添加以下規則:

sudo ebtables -I INPUT --log --log-level debug

日誌中沒有顯示任何資料包。我將不勝感激任何意見。

編輯:新增更多資訊。注入假包確實是應用。我的目的是完全用軟體且無需虛擬機器來模擬封包如何透過 Linux 核心堆疊轉送。我沒有創建任何新的網路命名空間。也許這就是問題所在?

我只有兩個進程。 「讀取」進程有一個開啟的檔案描述符tap2,並且不斷嘗試從中讀取。寫入進程開啟一個檔案描述符tap1並等待使用者提示發送 ARP 查詢。 ARP 查詢具有隨機來源 IP 位址。來源MAC位址設定為 的MAC位址tap1。這是 tcpdump 的輸出:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap1, link-type EN10MB (Ethernet), capture size 262144 bytes
^[[A07:19:57.752990 ARP, Request who-has google-public-dns-a.google.com tell 0.0.248.17, length 28
    0x0000:  ffff ffff ffff ba9c 0589 16ad 0806 0001
    0x0010:  0800 0604 0001 ba9c 0589 16ad 0000 f811
    0x0020:  0000 0000 0000 0808 0808

我已經配置了tap1並且tap2沒有IP位址。這可能是問題所在嗎?

brctl addbr br0
ip tuntap add name tap1 mode tap
ip tuntap add name tap2 mode tap
brctl addif br0 tap1
brctl addif br0 tap2
ifconfig tap1 0.0.0.0 up
ifconfig tap2 0.0.0.0 up
ifconfig br0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
ip link set br0 up
ip link set tap1 up
ip link set tap2 up

根據答案,我檢查了將各種應用程式附加到tap2.我注意到這一點:當沒有應用程式使用tap1or時tap2,兩個介面都沒有設定 LOWER_UP 標誌。

4: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500

當我啟動應用程式時,LOWER_UP 標誌被設定:

4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff

很抱歉這篇文章太長了,我只是希望有足夠的資訊來理解這個問題。

答案1

以防萬一,因為你說你是個菜鳥:tun(第 3 層)或 tap(第 2 層)介面是應用程式的網路介面端點,應用程式可以從此網路介面讀取和寫入封包。您創建的內容ip tuntap add ...或過時的內容tunctl持久名稱對於此類端點,您通常仍會運行該應用程序,並且除非您運行該應用程序,否則它不會執行任何操作。

由於應用程式與網路介面互動是設計問題,因此無需使用第三方應用程式「注入」資料包,除非您指的是「注入」我所描述的這種正常互動。

另外,如果您想嘗試網絡,我建議您使用網路命名空間veth對。基本上,您可以在計算機上設定許多虛擬計算機,這些計算機可以模擬網路上真實計算機之間的通訊。

因此,如果您想這樣做,並且不想使用自己的應用程式建立和接收資料包,則不需要 tun/tap 介面。

也就是說,我只是測試了您的設置,略有不同,因為您沒有說明您使用什麼來“注入”數據包:我使用了兩個socats 來創建分接端點tap0atap1a,然後我橋接它們,並在中使用了另外兩個socats兩個不同的命名空間為我創建正確的資料包。它們需要位於不同的命名空間中,因為本地資料包將始終通過環回傳遞lo

正如預期的那樣,橋接分路設備運作得很好。

所以我認為問題出在您注入的資料包中:錯誤的乙太網路位址,或沒有廣播。tcpdump -xx ...當您注入 ARP 封包時,請使用輸出編輯您的問題。

或者您可能想建立網路命名空間並橋接兩個 veth 對的兩個端點?這樣就簡單多了。

編輯

ARP 封包看起來不錯。似乎沒有連接到 的應用程式tap2。如果這樣做ip link,您不應該看到 的LOWER_UP標誌tap2。猜測:網橋偵測到裝置僅部分啟動,因此不會向該連接埠發送資料包。

tap嘗試用that替換它連接到它的應用程序,例如

sudo socat TUN:10.0.2.2/24,tun-name=tapx,tun-type=tap,iff-up - | hexdump -C

(該10.0.2.2/24位址不會執行任何操作,但socat如果您不指定位址,則該位址將無法運作),並在另一個終端中

sudo ip link set tapx master br0

(替換brctl addif),然後多次注入資料包,看看是否在第一個視窗中得到十六進位轉儲。也要檢查LOWER_UPip link show dev tapx.

順便說一句,ifconfig已經brctl過時了。使用ipandbridge代替。

不為網橋連接埠分配 IP 位址並不重要,因為網橋連接埠沒有 IP 位址(如果他們在被橋奴役之前被分配了一些,他們就會被忽略)。參見例如這裡

答案2

我為此苦苦掙扎,並認為我已經找到了解決方案。或者,至少,更好地了解正在發生的事情。

重要的是要記住,將資料包傳送到接收端(“RX”)的 Tap 介面的唯一方法是將該資料包寫入套接字描述符由打開水龍頭的進程創建(通過open("/dev/net/tun",...)ioctl)。一次只有一個進程可以擁有該檔案描述符。如果一個 Tap 設備已打開,並且另一個進程嘗試重新開啟另一個同名的 Tap 設備,則該系統呼叫將失敗。

因此,當您有任何其他進程(例如wireshark)時,打開原始套接字然後綁定tap0,它只能寫入流量出去系統的(從核心的角度)。也就是說,wireshark 應該會增加TX的計數器tap0,並且只有RX封包會被轉送到橋接介面。

您可以檢查每個計數器,例如:

#!/bin/bash
for if in tap{0,1}; do
    stats=/sys/class/net/$if/statistics/
    rx=$(cat $stats/rx_packets)
    tx=$(cat $stats/tx_packets)
    echo "$if: rx=$rx, tx=$tx"
done

輸出如下:

tap0: rx=0, tx=6
tap1: rx=0, tx=5

因此,根據您的具體情況,我懷疑問題出在這裡:

我有一個使用 libpcap注入ARP資料包的程式。 tap1Wireshark 正確顯示進入的資料包tap1。但是,沒有資料包出現在 處tap2

如何將 ARP 封包注入到 tap1 中?我假設wireshark沒有呼叫fd = open("/dev/net/tun", ...)and ioctl(fd, TUNSETIFF, ...),因此發送的資料包將是TX,因此不會橋接。

tap0您將需要打開將資料包寫入 的文件描述符的程序,tap0以使這些資料包在 上轉發br0並顯示在 上tap1

相關內容