2017年5月30日 星期二

透過 pxe 網路開機載入開機光碟

很久以前就想玩 pxe 網路開機; 最近想要攻佔不歸我管的 windows 電腦教室, 才開始認真學。 做壞事克服逆境真是進步的最佳動力啊! 這篇 (中文) 很詳盡; 不過如果區網內已有一個 dhcp 伺服器, 而且不能關掉, 那該怎麼辦呢? 把自己的 dhcp 服務設定成 proxy 就可以了。 本文主要參考 這篇 manski.net 的英文文章, 因為它採用 dnsmasq, 讓設定變得很簡單, 而且文章本身也寫得簡單明瞭。 最後, 本文也說明如何透過 pxe 啟動特定幾張 live cd。 搜尋 「pxe 光碟」 時, 會看到很多 「透過 pxe 啟動 linux 安裝光碟」 類型的文章; 但如果只是想要網路開機, 並沒有要安裝呢? 這是本文的重點。

如許多文件所說, dnsmasq 把網路開機所需要的服務通通包進去, 只要一個設定檔就完成, 跟古代人比起來, 現在超幸福的。 本文曾在實體環境測試成功: D-Link DIR 300 分享器、 Lenovo x220i 筆電作為 pxe 伺服器、 Asus eeepc 900HA 作為客戶端。 你也可以考慮架一部 proxmox 虛擬環境 來作實驗。 為了避免 dnsmasq 跟原來的網路設定起衝突 我最早其實是切了一個分割、 安裝 精簡版 ubuntu, 然後用 kvm 虛擬機啟動單一分割 的方式, 搭配 手工精簡版的 qemu-kvm 虛擬區域網路 來做實驗的。

  1. 安裝套件: apt-get install dnsmasq pxelinux syslinux memtest86+。 另外, 我會建議取消自動啟動 dnsmasq 服務: update-rc.d dnsmasq disable 這樣的話, 每次重開機時必須手動啟動: systemctl start dnsmasq, 稍微麻煩一點, 但比較不會出錯。 特別是在筆電或開機隨身碟上, 每次開機時, 網路環境可能都不一樣, dnsmasq 的設定可能會跟新的網路環境衝突。
  2. 抓回並在根目錄解壓縮: tar -C / -xzf tftpboot.tgz 這個檔案的內容基本上是一堆 symlinks。
  3. /var/lib/tftpboot/pxelinux.cfg 目錄下的 symlinks 最後結果如右圖。 注意: memtest86+ 不可以有附檔名。 否則 開機時螢幕會亂掉
  4. 把 (可能比上面壓縮檔內更新版的) 範例設定檔 抓回去, 放在 /var/lib/tftpboot/pxelinux.cfg/default 。 pxelinux 的設定檔基本上跟 extlinux 的設定檔 長得很像。
  5. 把 /etc/dnsmasq.conf 改名或搬到別處備份起來。 改用以下內容取代:
    log-dhcp
    
    # 如果區網已有 dhcp 伺服器
    dhcp-range=192.168.12.0,proxy
    log-facility=/var/log/dnsmasq.log
    
    # 如果我是區網唯一的 dhcp 伺服器
    #dhcp-range=192.168.12.75,192.168.12.180,255.255.255.0,12h
    #dhcp-option=3,192.168.12.254
    #dhcp-option=6,8.8.8.8
    
    pxe-service=x86PC,"Network Boot",pxelinux
    dhcp-boot=pxelinux.0
    enable-tftp
    tftp-root=/var/lib/tftpboot
    
    # 如果需要根據 mac address 鎖定 IP
    dhcp-host=ff:ff:ff:ff:ff:ff,192.168.12.146
    
    
    黃色部分請改成你的區網範圍。 如果區網內沒有其他 dhcp 伺服器, 那麼就改用下面那三句設定。
  6. 重新啟動 dnsmasq: systemctl restart dnsmasq

就這樣, 完成了! 現在進入另一部電腦的 BIOS, 啟用網路開機 (pxe boot)。 請圖片搜尋 "bios pxe" 參考別人類似的設定畫面。 然後用網路線接上同一部分享器、 重開機。 應該會看到 "configuring ..." 之類的訊息, 隔十秒左右出現開機選單背景圖及四個選項 (memtest、 ttylinx、 HBCD、 SystemRescueCD), 最後進入藍底白字的 memtest 畫面, 完成了第一次架設網路開機服務的測試, 好想親一下網路線! 請參考 manski.net 文末的 gif 動態插圖。 如果失敗, 請見本文最後面補充說明。

再來, 到 ttylinux Hiren's Boot CD (救援用 windows xp 光碟) 抓回 iso 檔, 放到 /var/lib/tftpboot/os/ 底下, 並且確認一下 /var/lib/tftpboot/pxelinux.cfg/default 設定檔的路徑正確。 不需要重啟 dnsmasq, 只要重開 client 電腦, 就可以進入這兩張 live cd。 這裡採用 syslinux/pxelinux 的 memdisk 當作 kernel, 把 live cd 當成 initrd 。 不過這方法 只適用於 windows 的 live cd 跟 「僅需要 kernel 跟 initrd 而不需要 root file system」 的 linux live cd。 透過老舊的 (實體/虛擬) 網路啟動 HBCD, 至少要有 1G (768MB 可開, 有警告訊息) 的記憶體跟三五分鐘的耐心。

但是 ttylinux 不太實用啊。 下一個目標是 SystemRescueCD 。 在 os/ 底下建立空目錄, 並且把 iso 檔以 loopback 的方式掛載起來:

mkdir -p /var/lib/tftpboot/os/SystemRescueCD
mount .../systemrescuecd-x86-4.9.6.iso /var/lib/tftpboot/os/SystemRescueCD

再用 ifconfig 查看一下你的 pxe server 被分配到的 ip 是多少, 並且到 /var/lib/tftpboot/pxelinux.cfg/default 裡面修改 netboot=tftp:... 的 ip。 重開 (至少 1G 記憶體的) client 電腦、 選擇進入 SystemRescueCD、 看到下載 sysrcd.dat 的進度不斷地歸零、 有自信地放著它不管, 5 到 10 分鐘後就開機完成了! 以上參考 sysrcd 的 pxe 開機文件。 對, sysrcd 本身就可以當做 pxe server; 但是我想改設定檔卻找不到, 而且也完全不會用 gentoo, 最後還是改用 ubuntu 當 pxe server 比較簡單。

從這個例子可以看出: 其他的 linux livecd 也是要像這樣根據每張光碟不同的載入方式來個別設定, 才能透過網路開機。 [2017/9/3 用 debian 的 live-boot 套件所製作出來的 live CD, 也可以從網路用 pxe 開機!]

* * * * *

補充說明:

  1. 也可以從網路載入 kernel 跟 initrd, 但第三步則在本機 (pxe client) 的硬碟裡找 root, 這樣速度就快多了 。 以 grml linux (或其他 debain live 製作出來的開機光碟) 為例, 在設定檔內可以寫成類似這樣:
    label grml-local
            menu label grml from lvm /dev/mapper/eeepc-pool of local drive
            kernel /os/grml/boot/grml32small/vmlinuz
            append initrd=/os/grml/boot/grml32small/initrd.img boot=live live-media=/dev/mapper/eeepc-pool live-media-path=/grml
    
  2. 如果 client 開機時遇到 tftp connection timed out (http://ipxe.org/4c106035) 根據 ipxe 官網文件 這個問答, 這有可能是因為它沒拿到 dhcp lease。 我把 pxe 伺服器的 dnsmasq 停掉, 再重開一次 (先 stop, 再 start, 不是直接 restart), 就成功了, 不太懂發生了什麼事。
  3. 採用 proxy dhcp server 的 pxe 開機流程請參考 規格書 的 2.2.3 節的圖 2.4 及 簡要文字說明
  4. 關於載入 SystemRescueCD 的 sysrcd.dat 要很久的問題, 有試著按照 這個建議 在 initram.igz 裡面的 init 的兩處 /bin/busybox tftp 後面加上 -b 65536 並且按照 這篇 重新打包 initram.igz, 但是結果沒太大不同, 一樣要等很久。 安裝 nginx 並且把 netboot= 改成 http 也並沒有比較快。
  5. 在 manski.net 的原文裡, 他在 dnsmasq.conf 裡面 加上 port=0 以便取消 dns 功能, 並且採用配套措施: 在 /etc/default/dnsmasq 裡加上 DNSMASQ_EXCEPT=lo 才不會讓本機查不到 dns。 我覺得 dns 服務放著讓它跑好像也沒什麼不好, 而且設定比較簡單。

* * * * *

我的網路速度很慢, 看來不太適合集體同時開機。 不過還是有些很實用的場景。 比方說如果有個別的電腦壞掉了, 可以從伺服器派送一個 grml linux 或 SystemRescueCD 之類的救援版小型 linux, 連隨身碟都不必, 就可以再把它救回來。 又例如想要複製硬碟 (做類似 clonzilla 或 ghost 的服務) 也可以叫所有客戶端先透過 pxe 啟動一個很小的 linux, 再 用 udpcast 平行快速配送 的方式取得大的映像檔。 此外, 學會 pxe 的基本運作之後, 再要學 DRBL/LTSP/clonezilla/fog 應該就會比較進入狀況吧。

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。