Linux 原生內部虛擬網路(TAP):Isolated Network(內網連線)

既然我們可以利用 TAP 建立一個虛擬網路介面,來產生一組獨立網段的虛擬網路,那麼自然就可以產生其他的虛擬網路介面,形成其他網段的虛擬網路,以應付不同網路環境的需求。

利用 TAP 新增虛擬網路介面的方式與產生單一虛擬網路介面的方式都一模一樣,例如,再產生一個虛擬網路介面,且一併設定其 IP 位址:

$ sudo tunctl -b -u jeos

$ sudo ifconfig tap1 172.16.2.1 netmask 255.255.255.0 up

而由於 Host OS 已經存在一個虛擬網路介面(tap0),所以新增的虛擬網路介面,編號會依序遞增(如 tap1 ),設定之後的虛擬網路卡,一樣可以利用〝ifconfig tap1〞來查詢設定之後的資訊:

現在,Host OS 已經擁有兩張虛擬網路介面,其架構如下圖所示:

現在,我們擁有了兩個不同網路區段的內部網路,這就類似公司內部有兩個獨立的網路區段,分別提供給不同的部門或單位來使用,而除非有特殊的狀況或要求,一般來說,內部網路應該是可以互通有無的,而不會受到任何的限制。

利用 TAP 建立的虛擬網路介面所形成的網路區段,預設只能獨立運作,也就是說,不同虛擬網路區段之間是無法互相連線的,不過,就如上述所言,除非有特殊的狀況,不然理論上內部網路應該要可以相互溝通連線的,而就 TAP 所建立的虛擬網路介面來說,要讓內部不同網路區段(不同虛擬網路介面)的電腦可以相互連線,需要經過以下的處理:

  1. 啟動 Host OS 「IP Forward」的功能
  2. 設定 Host OS 與 Guest OS 的「Routing Table」
  3. 若有連結網際網路的需求,則需要再 Host OS 的防火牆,啟動 NAT 的功能

以下就針對上述三個步驟做說明。

※ 啟動「IP Forward」的功能

由於 Host OS 擁有多個虛擬網路介面,也就等同於存在多個虛擬的網路區段,而不同網段之間的封包要能夠相互溝通傳遞,就必須要打開(啟動)核心封包轉送(ip forward)的功能,這樣,不同網路區段的封包才能相互傳遞。

要打開 Host OS 上「IP Forward」的功能,需要修改「/etc/sysctl.conf」檔案內的設定值,利用任合一套編輯器,來開啟此檔案,如:

$ sudo geidit /etc/sysctl.conf

以上圖為例,將游標移動到第 26 行的位置,並將原本註解的符號給刪除,存檔後退編輯介面:

不過,這樣還沒有實際啟動封包轉送的功能,因為我們修改過的設定檔,並沒有實際載入到系統內,因此需要重新啟動電腦,或者利用以下的方式來讓重新啟動網路組態,以套用異動後的設定檔:

$ sudo /etc/init.d/networking restart

這樣才有真正啟動核心封包轉送的功能。

※ 設定「Routing Table」

接著利用以下的指令,來啟動兩台虛擬電腦(這邊一樣使用 tBala Live CD,檔案下載點請參考:http://tbala.net/joomla/):

$ kvm -m 256 -net nic -net tap,ifname=tap0,script=no,downscript=no -cdrom DSL-tBala10.iso -boot d &

$ kvm -m 256 -net nic -net tap,ifname=tap1,script=no,downscript=no -cdrom DSL-tBala10.iso -boot d &

其中,要注意的地方在於「ifname」這個參數的使用,由上方的命令,可以知道這兩台虛擬電腦,分別指定了不同的虛擬網路介面,而現在要模擬的情境,就是要讓兩個不同網路區段的內部網路,可以相互連線。

虛擬電腦開啟進入桌面之後,直接開啟桌面上的終端機,在虛擬電腦上分別輸入以下指令:

$ ifconfig eth0 172.16.1.2 netmask 255.255.255.0 up(使用 tap0)

$ ifconfig eth0 172.16.2.2 netmask 255.255.255.0 up(使用 tap1)

此指令的作用是為了幫虛擬電腦手動設定 IP 位址與子網路遮罩,這樣虛擬電腦的網路功能才會有作用。

而不同網路區段內的電腦(虛擬電腦)可否相互連線,路由表(Routing Table)的設定可是佔了非常重要的角色,因為這決定了網路封包要傳送的目的與窗口,若路由表的資訊不足,或是錯誤,則網路封包將無法順利傳送,而最終的結果,就是網路無法連線。

依照上面的網路架構圖,可以知道在 Host OS 內部存在了兩張利用 TAP 所建立的虛擬網路介面(卡),而在虛擬網路介面的後方,則是代表了兩個不同的網路區段,可想而知,這兩張虛擬網路介面,就是個別聯繫這兩個網路區段的〝窗口〞, 在建立虛擬網路介面(卡)之後,Host OS 的路由表如下圖所示:

其中,「tap0」與「tap1」則是我們建立的虛擬網路介面(卡),其後端的網路區段分別為「172.16.1.0」與「172.16.2.0」,而「eth0」則是 Host OS 本身的實體網路卡。

現在,我們要讓「172.16.1.0」與「172.16.2.0」這兩個網路區段內的電腦可以相互溝通,那麼,就需要在 Host OS 的路由表內做點設定,其設定的指令如下:

$ sudo route add -net 172.16.1.0/24 gw 172.16.1.1 dev tap0

$ sudo route add -net 172.16.2.0/24 gw 172.16.2.1 dev tap1

參數

說明

route add

route 是設定路由表指令,參數 add 則是要在路由表內增加資訊

-net

此參數主要是指定要設定的網路區段與子網路遮罩(netmask),可用簡化的方式表達,如 172.16.1.0/24

gw

指定欲作用網路區段的預設閘道(gateway)

dev

指定欲作用網路區段的網路介面(卡)

以上的指令,就是要在 Host OS 的路由表內新增兩筆資訊,讓 Host OS 接收到來自虛擬電腦內部連線的封包時,可以清楚的知道要將封包送往哪裡,而異動後的路由表如下圖所示:

不過,可不是這樣設定之後,內部網路的封包就可以暢通無阻,不只是 Host OS 要設定路由表,Guest OS(虛擬電腦)也需要設定自己的路由表,這樣網路封包才能順利傳遞,這邊也請依照以下指令,在虛擬電腦的終端機內輸入:

$ route add default gw 172.16.1.1 eth0(使用 tap0 的虛擬電腦)

$ route add default gw 172.16.2.1 eth0(使用 tap1 的虛擬電腦)

這樣設定完成之後,整個內部網路(虛擬網路)才能真正相互溝通,傳遞訊息。

※ 啟動「NAT」

然而,雖然「tap0」與「tap1」這兩個虛擬網路介面(卡)所架構的網路區段已經可以相互溝通,但是卻是無法與外界溝通,也就是無法連結到網際網路,而說穿了,其實原因就是內部(虛擬)網路是私有的網路區段,所以並無法實際連結到網際網路,因此,在 Host OS 上面,我們必須利用 iptables 來啟動 NAT 的功能,這樣才能讓 172.16.1.0 與 172.16.2.0 網路區段的封包可以送到到網際網路,設定方式如下(在 Host OS 的終端機內設定):

$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 172.16.1.0/24 -j MASQUERADE

$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 172.16.2.0/24 -j MASQUERADE

再來利用以下指令來查看設定結果:

$ sudo iptable -t nat -L -n

防火牆設定完成之後,所有內部(虛擬)網路的虛擬電腦,就都可以連結到網際網路了。

※ MAC Address 的迷思

在操過的過程中,眼尖的讀者可能會發現一件事,那就是上述兩台虛擬電腦網路卡的 MAC Address 怎麼會一模一樣呢?

是的,您沒看過,這兩台虛擬電腦網路卡的 MAC Address 的確都一模一樣,一樣都是「52:54:00:12:34:56」,這實在是因為使用 TAP 所產生的虛擬網路介面(卡)的虛擬電腦,預設就是使用這一組 MAC Address ,而雖然在大部分的情況下,虛擬電腦是可以正常運作而不受影響,但是就資訊安全的角度來說,這可是不允許發生的狀況,另外,相同的 MAC Address 也會影響到系統的網定度,因為很容易會發生網路不穩的情形,所以為了系統的穩定與資訊安全的考量,在一開始啟動虛擬電腦的時候,就可以手動只定一組 MAC Address 給虛擬電腦使用,指令如下:

$ kvm -m 256 -net nic,macaddr=52:54:00:11:11:11 -net tap,ifname=tap0,script=no,downscript=no -cdrom DSL-tBala10.iso -boot d &

藉由這樣所啟動的虛擬電腦,其網路卡所使用的 MAC Address 就會是我們手動指定的數值了: