(黃獻德) Hsien-De Huang | E-Mail:TonTon (at) TWMAN.ORG | TonTon (痛痛)
Malware Analysis Network in Taiwan (MiT) | 惡意程式分析網在台灣 (抬丸郎)
Deep Learning (深度學習), Malware Analysis (惡意程式分析), Ontology (知識本體)
Android Reverse Engineering (Android 逆向工程), Type-2 Fuzzy Logic (第二型模糊邏輯)

ONE PIECE (海賊王)

ONE PIECE (海賊王)

2013年4月4日

DRBL Client 上的 KVM 如何做 Bridge

嗯 ~ 這邊主要是要解決建好 OpenNEbula 後,deploy vm 到某個 node 上執行的問題
一切都是接續這篇 ... 

應用 OpenNebula 3.8.3 管理 KVM 建置 IaaS Private Cloud 於 F102@ILT
(然後上面這篇一整個混亂 ... 所以不如先直接看下面的吧)
在 CentOS 6.4 x64 之 DRBL 環境下的 Clients 做 Bridge 再安裝 OpenNebula 4.2.0 管理 KVM 建置 IaaS Private Cloud

基本上做完上面的動作後,可以透過 Sun-Stone 上的 no_VNC 直接對 vm 連線,即使 vm 是被建在某一台 node 上;但是這樣就是一定要開網頁,如果可以直接用 pietty ssh 連過去,應該就更方便了 ! 所以我 Google 了很多資料 ... 但是卻都沒仔細解釋到底怎樣做 !


從上圖應該可以看出我現在問題是卡在 server 或是 node 以及 各自的 vm 都是可以對外連線,但找不到怎樣讓它可以從外面 ssh 進到 vm 裡 ~ 囧

答案是需使用 Bridge 才可從外部直接 ssh 到 DRBL 的 node 上的 vm

避免以後自己腦殘搞亂掉 ~ 記錄一下吧 ! 
對了 ! 想直接解決問題的直接看最下方的底紅字
======================================
===== 這邊都是我自己在 Debug 的過程記錄 =====

首先是建好後,因為是 DRBL 的關係,所以server 及每個 node 上用 Virt-Manager 都可以看到有一個 default 的 虛擬網路 (192.168.122.0/24)。


這時候把你要啟動的 VM 的網路選 default 


會發現 server 或 node 上都會多出一個 virbr0,而Gateway 當然就是它 192.168.122.1;同時也可以看到因應下方另外新增的 192.168.1.0/24 也多了一個 192.168.1.1 的 virbr1 來當另一組 Gateway 了




它是 NAT,所以基本上 server 或 node 上的 vm 都可以正常連外




如果自己新建一個 192.168.1.0/24,並且啟用 VM 後把 Gateway 改為 192.168.1.1 一樣也是可以連外的 !








在 該 VM 的 host上也可以 ping 的到跟可以 ssh 過去 ...


在 vm 上也可以看到 traceroute 一律都會先跑到該 host 的 192.168.1.1 (或 192.168.122.1) 再跑到 server 上 eth1 的 192.168.0.110 再出去


最後,就是問題所在了 .... 要怎樣才可以從外部直接 ssh 到某台 vm 呢 ? xDDD


目前只試了這句 ~ 然後答案當然是失敗 ! 囧


iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 500 -j DNAT --to 192.168.1.75:22


找到幾個文件驗證上述的腦殘測試,必需是使用 Bridge 才可以從外部ssh到node的 vm ....

RHEL 6 Virtual Networks and Network Bridges

於是我參考上面說明 ... 照著做 ....




但 ~~~~ 不知為啥 ..... 重開機後一樣都是 eth0 一直 bridge 不起來耶 ! xD

想了一下難道會是因為 DRBL ? 於是我用另外一台獨立安裝的 CentOS 6.3 測試



居然就成功了 !!!!!!!!!!!!!!! Orz ~ 所以我到底該怎麼辦啊 ? xD


再補一張設定完後網卡啟用的不同如下




原本想說讓它變成用 DHCP 取得 IP ... 還故意把 MAC 設一樣 ... 結果卡在這邊


後來找了 DRBL team 的 Jazz 大 ... 確認了下面幾件事

1. DRBL-virt: https://code.google.com/p/drbl-virt/,有解決過這個問題
2. 一切都是因為要讓 DRBL Client 可以 bridge 要 patch mkpxeinitrd
3. DRBL Client 網路的部份 是一開機就先設定了,所以不會去跑 network 相關的 init.d
4. DRBL Client 的 OS 是從網路來的,如果開機好後再 bridge ,因為DRBL Client 是透過 NFS 取得 所以一旦把網路斷線 它是連 /bin/bash 都會不見的,也就是會變殭屍;這也是為啥我前兩天傻傻的把好幾台 client 給玩到斷線的原因




### Adding support of KVM physical network sharing bridge
#### 1. patching /usr/bin/mkpxeinitrd-net
#### reference : drbl-virt 0.1.3 (http://code.google.com/p/drbl-virt)
#### http://trac.nchc.org.tw/grid/export/248/drbl-virt/sbin/drbl_bridge_kvm_patch
mv /usr/bin/mkpxeinitrd-net /usr/bin/mkpxeinitrd-net.dpkg
chmod a+x /usr/bin/mkpxeinitrd-net
wget -q http://ezilla-nchc.sf.net/d-i/squeeze/mkpxeinitrd-net -O /usr/bin/mkpxeinitrd-net

#### 2. patching /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init
mv /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.dpkg
wget -q http://ezilla-nchc.sf.net/d-i/squeeze/linuxrc-or-init -O /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init
chmod a+x /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init

#### 3. patch /opt/drbl/setup/files/misc/init.drbl
mv /usr/share/drbl/setup/files/misc/init.drbl /usr/share/drbl/setup/files/misc/init.drbl.dpkg
wget -q http://ezilla-nchc.sf.net/d-i/squeeze/init.drbl -O /usr/share/drbl/setup/files/misc/init.drbl
chmod a+x /opt/drbl/setup/files/misc/init.drbl

#### 4. patch /opt/drbl/sbin/ocs-live-netcfg
mv /opt/drbl/sbin/ocs-live-netcfg /opt/drbl/sbin/ocs-live-netcfg.dpkg
wget -q http://ezilla-nchc.sf.net/d-i/squeeze/ocs-live-netcfg -O /opt/drbl/sbin/ocs-live-netcfg
chmod a+x /opt/drbl/sbin/ocs-live-netcfg




以為是很簡單的把檔案給換掉就可以了 ! 結論是 .... 當然是失敗了 !


因為 Jazz 大說因為 DRBL 有改版,所以不能直接用 mv 把檔案換掉,要用 patch ... 



# diff -uBb mkpxeinitrd-net mkpxeinitrd-net.drbl-virt > mkpxeinitrd-net.patch
# cat mkpxeinitrd-net.patch | patch -p1 mkpxeinitrd-net.dpkg
patching file mkpxeinitrd-net.dpkg



因為用 diff 後我還是不知道怎樣 patch 啊 ! 只好手動一行行比對改 ...




因為直接覆那四個檔案,重新下 drblsrv -i 都會出現上面的錯誤 .... 

然後 client 就開不了機了 ! 說找不到網路卡 ....



後來一直反覆的改來改去 .... 也不知道到底改了什麼 .... 突然就變下面這樣


好像是有順利把 br0 給啟用了啊 !



看訊息應該是跟 DRBL 官網上這個 FAQ 一樣問題才對 ....
用戶端的電腦出現 "FATAL ERROR: Failed to mount root filesystem!!!" 請問如何解決?


1. server那台的/etc/hosts少了這台client的hostname,這個很少會發生,除非您自己改了那個檔案。請確認/etc/hosts這個檔案,如果真的少了client的hostname,請加上去。 
2. server那台電腦中您有設定防火牆或是使用TCPwrapper,以至於client被拒絕掉。請修改您的防火牆規則或是/etc/hosts.allow以及/etc/hosts.deny,不要把client的電腦擋掉。 
3. 你的網段中同時有第二個以上的dhcp server存在,這是最常見的問題來源,請將兩個dhcp server切割開來。


耗了我兩天春假 ..... 嘆 ..... 收收款款ㄟ回家好了 ! 嘆 ....

補充說明一下 ~ 使用 " drbl-2.3.12-drbl1.noarch.rpm " 下 drblsrv -i 時
若這步驟選 3 會發生下面的圖,選 4 就正常


*****************************************************.
如果找到新版的程式,嘗試升級某些需要的程式...
*****************************************************.
準備用戶端電腦用的核心,在儲藏庫中尋找可用的核心...
可用的核心有:
1: kernel-2.6.32-358.2.1.el6.x86_64.rpm (in updates repository)
2: kernel-2.6.32-358.0.1.el6.x86_64.rpm (in updates repository)
3: kernel-2.6.32-358.el6.x86_64.rpm (in release repository)
4: kernel_2.6.32-358.2.1.el6.x86_64 x86_64 (from this DRBL server)
你要選擇哪個核心給用戶端電腦使用? 如果您已經更新過系統,建議選擇updates中的,如果沒有更新過,建議選擇release中的.
[3] 3
你選擇 3




準備用戶端電腦用的核心,在儲藏庫中尋找可用的核心...
只有一個核心符合你設定的條件:  kernel_2.6.32-358.2.1.el6.x86_64 x86_64 (from this DRBL server), use it.
選定的核心為: kernel_2.6.32-358.2.1.el6.x86_64





=================================================
其實弄到這邊已經一整個打算放棄了 ... 但想了一下還是決定再來最後一次 !
==================================================


1. DRBL 重新安裝:rpm -Uvh drbl-2.3.12-drbl1.noarch.rpm
2. 下載一些已修正過的檔案:
# wget -q http://ezilla-nchc.sf.net/d-i/squeeze/mkpxeinitrd-net -O /usr/bin/mkpxeinitrd-net.drbl-virt
# wget -q http://ezilla-nchc.sf.net/d-i/squeeze/linuxrc-or-init -O /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.drbl-virt
# wget -q http://ezilla-nchc.sf.net/d-i/squeeze/init.drbl -O /usr/share/drbl/setup/files/misc/init.drbl.drbl-virt
# wget -q http://ezilla-nchc.sf.net/d-i/squeeze/ocs-live-netcfg -O /usr/share/drbl/sbin/ocs-live-netcfg.drbl-virt



安裝好 DRBL 的 rpm 檔接著進行 drblsrv -i,可以發現幾個檔案都跑出來了 !




# diff -u /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.drbl-virt > /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.patch
# cat /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.patch


# diff -u /usr/bin/mkpxeinitrd-net /usr/bin/mkpxeinitrd-net.drbl-virt > /usr/bin/mkpxeinitrd-net.patch
# cat /usr/bin/mkpxeinitrd-net.patch



# diff -u /usr/share/drbl/setup/files/misc/init.drbl /usr/share/drbl/setup/files/misc/init.drbl.drbl-virt > /usr/share/drbl/setup/files/misc/init.drbl.patch
# cat /usr/share/drbl/setup/files/misc/init.drbl.patch

 

結果搞半天,是我自己鬼打牆 ... Jazz 大都說版本太新不能直接 diff 跟 patch 了 ... 
我還惡搞,所以到這邊整個靜下心來重弄 ... 記得先 cp 一個備用哩


===== 以上這邊都是我自己在 Debug 的過程記錄 =====
=======================================
===========以下才是真正的快速解決方法 ========

1. /usr/bin/mkpxeinitrd-net
找到下面這行,且新增最後那個紅字 brctl
include_bin_prog_from_server="sleep lspci insmod modprobe rmmod lsmod pkill strings mount umount mount.nfs umount.nfs brctl"

找到 # Deal with firmwares! 在上面新增
# modified by drbl-virt
cp -a --parents kernel/net/802/stp.ko $initrd/lib/modules/$kernel_ver/
cp -a --parents kernel/net/bridge/bridge.ko $initrd/lib/modules/$kernel_ver/

2.  /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init 
找到 # IF the netdevices is not assign in /etc/netdev.conf 在上面加上
# modified by drbl-virt
brctl addbr br0
brctl addif br0 eth0
ifconfig eth0 0.0.0.0
ifconfig br0 0.0.0.0

3.  /usr/share/drbl/setup/files/misc/init.drbl
找到 # find my IP address
-NETDEVICES="$(LC_ALL=C cat /proc/net/dev | awk -F: '/eth.:|tr.:|p.p.:/{print $1}')"
+NETDEVICES="$(LC_ALL=C cat /proc/net/dev | awk -F: '/eth.:|tr.:|br.:|p.p.:/{print $1}')"
意思就是在 NETDEVICES 那行
在 p.p 前面加入 br.:

最後用 diff -u 比對一下



# diff -u /usr/bin/mkpxeinitrd-net.jazz /usr/bin/mkpxeinitrd-net > /usr/bin/mkpxeinitrd-net.drbl.jazz-patch


# diff -u /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.jazz /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init > /usr/lib/mkpxeinitrd-net/initrd-skel/linuxrc-or-init.drbl.jazz-patch


# diff -u /usr/share/drbl/setup/files/misc/init.drbl.jazz /usr/share/drbl/setup/files/misc/init.drbl > /usr/share/drbl/setup/files/misc/init.drbl.jazz-patch

最後就是再跑一次 drblsrv -i,可以看到 mkpxeinitrd 重新生成 Client 端網路開機需要的 initrd.img


還有再跑一次 drblpush -i


結果是什麼 ????  各位觀眾 ...... 嘿嘿嘿 ....

2014/07/13 補充 .... DRBL Server 端要用兩張網卡 ... 所以 inet 請用 eth0 然後做成 bridge 的 br0 (192.168.0.0/24) ... 至於 ineternet 則請使用 eth1 ... 切記 clients 請都只插一張網卡 eth0 ... 這樣才可以在 server 端用 iptables 來直接連現到 client 上的 VM ... 看不懂的再問吧 !


 

成功了啊 !!! DRBL 的 Client 可以 Bridge 啊 !
無比感謝 Jazz 大不厭煩的指點一直鬼打牆的我 ! Orz ~ 跪謝 ....

春假放了快一週 ... 這問題簡直把我搞瘋了啊 !
最後補上一張外部直接 ssh 到 vm 的圖啊 !



DRBL Mailling list:
https://groups.google.com/forum/?hl=zh-TW%E3%80%82&fromgroups=#!topic/drbl/FLnTTQq3atA