樹莓派實現 “IP網路損傷儀”
【摘要】
樹莓派作為近年來興起的微型計算機裝置具備造價低、體積小、介面豐富使用靈活等特點越來越多的被大家認可。本次實踐本著邊玩邊學又能為專案產生效益的的原則,通過簡單的動手和嘗試便將樹莓派改造成”IP網路損傷儀”。
【關鍵詞】
樹莓派、IP網路損傷儀、netem、TC
一、 問題的提出:
隨著產品的多年發展和生命週期的更迭,在測試過程中我們發現越來越多的缺陷已經無法通過基本功能覆蓋、CI冒煙的方式發現。但由於軟體的複雜性當下依然有越來越多的異常場景、多種功能疊加、效能和其他非功能性產品缺陷洩露在外場。
我們也嘗試借用”Sprient IP網路損傷儀”來模擬外場一些傳輸異常場景來進行ST測試,並在傳輸可靠性相關的測試方面取得了不錯的效果。但Sprient 的裝置造價昂貴在公司對於維護專案投資縮緊不可能購置的情況下我們需要想其他的辦法來達到同樣的測試效果。
二、 解決思路:
採用樹莓派實現IP網路損傷儀,主要考慮並實現如下3個方面:
1.樹莓派的組網:
IP網路損傷儀需要能夠在不改變網路現有組網和IP地址規劃的情況下,簡單的串接的現有的測試網路中給測試人員帶來0使用成本。
2.樹莓派應實現的IP網路損傷需求:
我們在傳輸可靠性測試過程中需要模擬的惡劣傳輸因素包括:網路時延及時延抖動、報文丟棄、報文重放、報文篡改等等,以及這些因素的相互組合。
3.操作介面(本次實踐尚未完成):
簡化命令列操作,讓IP損傷儀在樹莓派上的構建通過指令碼自動構建,給使用者提供UI操作介面(這部門本次實踐暫未完成)
三、 實踐情況:
1.材料準備:
1>購置USB乙太網網絡卡X2:
圖1.1 USB乙太網卡
網絡卡採用綠聯USB轉RJ45網絡卡兩塊,網絡卡工作模式是100Mbps的,不測試轉發效能對於我來說是夠用的。價格便宜兩塊也就90來塊錢,關鍵它的優點是Linux下免驅,插上直接可用。
2>TF儲存卡一張:
不要省錢,要買高速卡,容量至少16G吧,我購買的是閃迪(SanDisk)class 10 64GB TF卡:
圖1.2 TF卡
3>樹莓派3 一個:
圖1.3 RaspberryPI
總體成本500+元,比Sprient 動不動幾十萬的裝置相比,成本很低了:)
2.應用組網方案設計:
樹莓派應用組網方案如下圖所示:
將樹莓派如上圖所示的組網串接到現有測試網路中,不更改現有測試網元的配置。
圖2.1 組網邏輯圖
圖2.2真實裝置圖
說明:
1 >由於公司禁用WIFI,樹莓派的WIFI模組暫不使用。
2>Eth0為樹莓派自帶乙太網介面,連線公司辦公網以便使用者對於樹莓派的登陸和配置。
3>Eth1、Eth2為新購置的USB 乙太網介面卡,將其配置到虛擬網橋中。
4>eNodeB為被測裝置。
3.樹莓派的改造:
新購置的樹莓派是一塊裸板,需要 一切從0開始安裝和配置,其過程大致如下文所示:
3.1下載和安裝作業系統安裝:
3.1.1下載Raspbian linux作業系統:
圖3.1 Raspbian linux作業系統下載
3.1.2將Raspbian linux操作燒錄到TF卡:
3.1.2樹莓派第一次啟動的設定:
至此樹莓派可以正常使用了。
3.2構建虛擬網橋:
上文提到了要將樹莓派串到現有的測試網路中且不更改現有測試網元任何配置,那麼就需要讓組網圖中所示的eth1、eth2走二層資料轉發,而Linux作業系統預設的網路介面卡是走三層資料轉發的。經過資料查閱得知Linux上實現二層資料轉發的方式是“虛擬網橋”。下面是讓 eth1、eth2加入虛擬網橋的方法:
3.2.1安裝bridge-utils擴充套件包:
建議使用apt-get方式自動進行軟體包的安裝:
apt-get install bridge-utils
3.2.2建立虛擬網橋:
執行如下命令建立虛擬網橋meter_bridge:
sudo brctl addbr meter_bridge
3.2.3將Eth1、Eth2加入虛擬網橋:
執行如下命令將eth1、eth2加入虛擬網橋 meter_bridge:
sudo brctl addif meter_bridge eth1
sudo brctl addif meter_bridge eth2
通過ifconfig命令確認meter_bridge網橋介面已經被新增。
3.2.4除錯:
此時可以將被測裝置和測試網路接到eth1、eth2。接上之後:
1>進行一下ping包確認網路連通性:
ping包大家都知道吧,此處略。
2>查詢虛擬網橋的配置和Mac地址表:
sudo brctl show 查詢網橋基本配置
從上圖中可以看到 meter_bridge網橋中目前添加了兩個物理埠eth1、eth2。bridge-utils支援STP生成樹協議,這個是用於檢測和解決二層乙太網環路的協議,bridge id(橋id)也是生成樹協議中的重要概念,有興趣的同學可以繼續查閱STP協議相關資料。
sudo brctl showmacs 查詢MAC地址表
這個就是樹莓派的Mac地址表了二層資料轉發都是基於它,其中:ageing timer代表 mac地址表條目的老化時間;port 學習到的埠;is local為True的兩個Mac地址是樹莓派 eth1,eth2兩塊USB網絡卡自己的MAC地址。正常資料轉發時樹莓派應該能夠將同一廣播域內的相互通訊網元裝置的MAC地址學習到MAC地址表中。
通過brctl –help 可以獲取bridge-utils其他有用的操作命令。bridge-utils 感覺是簡單而強大的,結合Linux原生的ifconfig、ip route等命令,甚至可以把樹莓派做成一臺三層交換機。
3.2.5網橋配置固化:
編寫Python指令碼固化網橋建立和網橋介面新增過程,並讓樹莓配開機自動執行:
python指令碼:
from subprocess import call, PIPE,Popen
import pexpect
class Shell:
@staticmethod
def excute_cmd(cmd):
err_code = call(cmd, shell=True, )
screen = ''
return err_code,screen
@staticmethod
def switch_usr(usr,psw):
proc = pexpect.spawn('su %s'%usr)
proc.expect('Password:')
proc.sendline('%s\n' % psw)
proc.interact()
class meter:
bridge_if = ['eth1', 'eth2']
bridge = 'meter_bridge'
def __init__(self):
pass
def cfg_net_bridge(self):
if not self.is_if_installed():
return
if not self.add_net_bridge():
return
if not self.add_if_to_bridge():
return
def add_net_bridge(self):
# try to delete old net bridge
Shell.excute_cmd('sudo ifconfig %s down' % meter.bridge)
Shell.excute_cmd('sudo brctl delbr %s' % meter.bridge)
err_code,screen = Shell.excute_cmd('sudo brctl addbr %s' % meter.bridge)
if 1 == err_code:
print('add net_bridge fail')
return False
return True
def add_if_to_bridge(self):
for net_if in meter.bridge_if:
err_code,screen = Shell.excute_cmd('sudo brctl addif %s %s' % (meter.bridge, net_if))
if 1 == err_code:
print('if %s add to %s is Fail ' % (net_if,meter.bridge))
def is_if_installed(self):
for net_if in meter.bridge_if:
err_code, screen = Shell.excute_cmd('ifconfig %s' % net_if)
if 1 == err_code:
print('bridge if:%s is not install!' % net_if)
return False
return True
if __name__ == '__main__':
meter().cfg_net_bridge()
將指令碼的執行命令寫入/etc/rc.local實現樹莓派自動自動配置網橋:
[email protected]:/etc $ cat rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
#cfg net bridge
python3.4 /home/pi/DamageMeter/Bridge.py &
exit 0
熟悉shell指令碼的同學可以用shell指令碼實現,此指令碼基於Python3.X,需要額外安裝直譯器。另外記得給rc.local可執行屬性,否則樹莓派在啟動過程中可能將無法執行該指令碼。
3.2.6其他:
3.3安裝TC&netem模組及使用除錯:
3.3.1TC&netem模組簡介:
netem 是Linux 2.6 及以上核心版本提供的一個網路模擬功能模組。該功能模組可以用來在效能良好的區域網中,模擬出複雜的網際網路傳輸效能,諸如低頻寬、傳輸延遲、丟包等等情況。使用 Linux 2.6 (或以上) 版本核心的很多發行版 Linux 都開啟了該核心功能,比如 Fedora、Ubuntu、Redhat、OpenSuse、CentOS、Debian 等等。 tc 是Linux系統中的一個工具,全名為 traffic control(流量控制)。tc 可以用來控制 netem 的工作模式,也就是說,如果想使用 netem ,需要至少兩個條件,一個是核心中的 netem 功能被包含,另一個是要有 tc 。
3.3.2TC&netem模組安裝?無需安裝
直接嘗試了一下,非常幸運 ,從樹莓派官網上下載的Raspbian Linux發行版本直接包含了TC&netem模組。那麼直接在樹莓派上簡單驗證一下基本功能好了。
3.3.3傳輸時延/時延抖動功能驗證
sudo tc qdisc add dev 介面 root netem delay 時延 抖動
上面是給網橋成員介面網絡卡新增單向時延和抖動的命令列介面基本形式,嘗試的結果如下:
新增時延前的Ping包:
可以看到新增時延前 ping包時延 不到1ms
在eth1上新增單向100ms時延,無抖動:
可以看到ping包往返時延變為了100ms。
在eth1上新增單向100ms時延,抖動20ms
如上圖所示,可以看到傳輸時延從85ms-115ms的跳變。
從上述的簡單驗證來看,樹莓派已經具備了夠著網路時延/抖動的能力
3.3.3傳輸報文丟棄功能驗證
sudo tc qdisc add dev 介面* root netem loss 丟包率%*
上面是給網橋成員介面網絡卡新增單向丟包的命令列介面基本形式,嘗試的結果如下:
……(ping過程略)
從上圖看到設定網橋成員介面eth1 10%丟包率後,ping包100個丟棄7個(7%),這裡說明一下,這個丟包率是針對整個物理介面的,而不是針對ping包資料的,由於整個物理介面中轉發的不僅僅只有ping包所以ping包結果是正常的。從上面的嘗試過程來看 樹莓派已經具備了報文丟棄的損傷功能。關於丟包還有更多的命令列引數,比如指示丟包的分佈模型,預設是採取均勻分佈,可選的引數還有泊松分佈、高斯分佈等等,這裡不一一嘗試了。
3.3.3報文重放功能驗證
sudo tc qdisc add dev 介面root netem duplicate 丟包率%*
上面是給網橋成員介面網絡卡新增單向重放的命令列介面基本形式,嘗試的結果如下:
如上圖,給網橋成員埠eth1增加 10%的報文重放。我們可以看到在ping包的過程中,出現了一些”DUP”(duplicate)字樣。表示重放的設定生效了。
3.3.3其他
上述只簡單的嘗試了,時延、丟包、抖動的損傷功能,TC&netem模組功能異常強大除此之外還能夠進行諸如:報文亂序、報文篡改,基於DiffSrv模型的Qos 等等,至此不再一一嘗試,大家有興趣請訪問:
https://wiki.linuxfoundation.org/networking/netem
獲取更多的資訊
四、後續實踐計劃:
1>實現基於web的UI操作介面,給使用的測試人員提供更好的使用體驗。
2>當前的IP損傷是基於物理埠的,後續嘗試基於特定IP資料流的網路損傷的實現。