PXE (Preboot eXecution Environment) 主要讓系統可以透過網路開機並安裝作業系統(或是 LiveCD),在網卡上有一塊 ROM (Firmware) 裡面存放了一些基本的網路協定 如:Internet Protocol (IP), User Datagram Protocol (UDP), Dynamic Host Configuration Protocol (DHCP) 以及 Trivial File Transfer Protocol (TFTP) 透過這一些協定使得 PXE 可以進行網路的檔案進行存取,進一步安裝作業系統.
流程 : PXE 開機 -> 從 DHCPv4 或是 v6 獲得 IP -> 透過指定的 TFTP 服務去載入開機前導程式(在 DHCP 設定檔指定) -> 前導程式載入開機選單檔案 (檔案裡面有指定開機 Kernel 與 Ramdisk 的協定與路徑) -> 透過 NFS 或是 HTTP 安裝作業系統.
測試作業系統 CentOS 8 x86_64 (虛擬機),使用固定 Static IP .
- IPv4 : 192.6.1.1
- IPv6 : 3ffe:501:ffff:100::1
架設 PXE 所需服務需要使用固定 IPv4 / UPv6 (不能使用 link-local address) 位址.
這邊我設定為 IPv4 : 192.6.1.1 / IPv6 : 3ffe:501:ffff:100::1 ,我們可以透過修改 /etc/sysconfig/network-scripts/ifcfg-* (RHEL) 或是直接用 #NetworkManager ( https://benjr.tw/10728 ) 工具來設定.
[root@localhost ~]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:0C:29:F6:4D:73 inet addr:192.6.1.1 Bcast:192.8.1.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fef6:4d73/64 Scope:Link inet6 addr: 3ffe:501:ffff:100::1/64 Scope:Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1226688 errors:0 dropped:0 overruns:0 frame:0 TX packets:1392610 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:102208468 (97.4 MiB) TX bytes:7696863052 (7.1 GiB)
DHCP
安裝 dhcp server 套件.
[root@localhost ~]# dnf -y install dhcp-server
這邊我支援多種 client-arch-type ,詳細請參考 – https://benjr.tw/16194
- IPv4 PXE 有支援 Legacy 與 UEFI
簡單看一下什麼是 Extensible Firmware Interface (EFI) 的功能就類似傳統 BIOS ,他是 OS 與硬體之間溝通介面. 不過相較於傳統的 BIOS EFI 他的架構更模組化,功能更強大.EFI 的架構是由 Intel 提出的, 目前是交由 Unified EFI Forum 來管理.也就是我們現在所稱的 Unified Extensible Firmware Interface (UEFI)兩種模式.下面 DHCPv4 支援 0x00:0x00 (x86 BIOS) 與 0x00:0x07 (x64 UEFI) 兩種.
[root@localhost ~]# vi /etc/dhcp/dhcpd.conf #ddns-update-style interim; ddns-update-style none; ignore client-updates; authoritative; allow booting; allow bootp; option space PXE; option PXE.mtftp-ip code 1 = ip-address; option PXE.mtftp-cport code 2 = unsigned integer 16; option PXE.mtftp-sport code 3 = unsigned integer 16; option PXE.mtftp-tmout code 4 = unsigned integer 8; option PXE.mtftp-delay code 5 = unsigned integer 8; option arch code 93 = unsigned integer 16; subnet 192.6.1.0 netmask 255.255.255.0 { range 192.6.1.30 192.6.1.250; option routers 192.6.1.254; option subnet-mask 255.255.255.0; if option arch = 00:07 { next-server 192.6.1.1; filename "grubx64.efi"; } else if option arch=00:00 { next-server 192.6.1.1; filename "pxelinux.0"; } } [root@localhost ~]# systemctl enable dhcpd [root@localhost ~]# systemctl start dhcpd
iptabels (firewall) 預設會擋到 port 67 與 68 (客戶端主要使用 UDP port 68 而服務器端使用 UDP port 67) 測試時所以關閉防火牆 (或是開放這兩個埠來使用)
[root@localhost ~]# systemctl stop firewalld
- IPv6 PXE 只有支援 UEFI
[root@localhost ~]# vi /etc/dhcp/dhcpd6.conf # # DHCPv6 Server Configuration file. # see /usr/share/doc/dhcp*/dhcpd6.conf.example # see dhcpd.conf(5) man page # default-lease-time 2592000; preferred-lifetime 604800; option dhcp-renewal-time 3600; option dhcp-rebinding-time 7200; #option dhcp6.name-servers 3ffe:501:ffff:100:200:ff:fe00:3f3e; #option dhcp6.bootfile-url code 59 = string; #option dhcp6.domain-search "sit.com"; option dhcp6.info-refresh-time 21600; dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases"; option dhcp6.vendor-class code 16={integer 32,integer 16,string}; subnet6 3ffe:501:6666:100::/64 { range6 3ffe:501:6666:100::10 3ffe:501:6666:100::299; range6 3ffe:501:6666:100:: temporary; prefix6 3ffe:501:6666:100:: 3ffe:501:6666:111:: /64; option dhcp6.name-servers 3ffe:501:6666:100::1; if option dhcp6.client-arch-type = 00:07 { option dhcp6.bootfile-url "tftp://[3ffe:501:ffff:100::1]/grubx64.efi"; } } [root@localhost ~]# systemctl enable dhcpd6 [root@localhost ~]# systemctl start dhcpd6
ip6tabels (firewall) 預設會擋到 port 546 與 547 (客戶端主要使用 UDP port 546 而服務器端使用 UDP port 547) 測試時所以關閉防火牆 (或是開放這兩個埠來使用)
[root@localhost ~]# systemctl stop firewalld
TFTP
剛剛在 DHCPv4 , DHCPv6 皆有設定相對應的開機程式,當 PXE Client 得到 IP 之後就是透過 TFTP 的方式下載 PXE 前導程式與設定檔案.
tftp 預設支援 Ipv4 與 IPv6,如果你遇到 PXE 顯示 tftp 錯誤時,可以參考 tftp 常見的錯誤訊息 https://benjr.tw/94695
需安裝 tftp 所需套件.
[root@localhost ~]# dnf -y install tftp-server
設定檔位於 /usr/lib/systemd/system/tftp.service ,預設都已經支援 ipv4 與 ipv6 .
[root@localhost ~]# cat /usr/lib/systemd/system/tftp.service [Unit] Description=Tftp Server Requires=tftp.socket Documentation=man:in.tftpd [Service] ExecStart=/usr/sbin/in.tftpd -s /var/lib/tftpboot StandardInput=socket [Install] Also=tftp.socket [root@localhost ~]# systemctl enable tftp [root@localhost ~]# systemctl start tftp
剛設定 DHCP 裡面有指定兩個開機檔案 pxelinux.0 與 grubx64.efi ,需複製至 tftp 的根目錄 /var/lib/tftpboot/ .
- grubx64.efi – EFI PXE 會用到,在 CentOS 8 ISO 目錄 /EFI/BOOT/grubx64.efi
[root@localhost ~]# cp /run/media/root/EFI/BOOT/grubx64.efi /var/lib/tftpboot/
- pxelinux.0 – Legacy PXE 會用到,在 CentOS 8 系統目錄 /usr/share/syslinux/pxelinux.0
[root@localhost ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
PXE 前導程式所需的設定檔
- Legacy
PXE 由開機前導程式 pxelinux.0 啟動之後會去讀取 PXE 開機的設定檔 /tftpboot/linux-install/pxelinux.cfg/ 目錄下的檔案.系統會找是不是有跟他相對應的 1.UUID 2.MAC address 3.IP address 如果都沒有才從讀取 default 這個檔案. 通常我沒有要針對不同的系統設定不同的設定檔,所以通常直接編輯 /tftpboot/linux-install/pxelinux.cfg/default[root@localhost ~]# vi /var/lib/tftpboot/pxelinux.cfg/default default 0 timeout 30000000 prompt 1 display msgs/boot.msg # Local label 0 localboot 1 label cent8-1905-64 kernel cent8-1905-64/vmlinuz append initrd=cent8-1905-64/initrd.img inst.repo=nfs:192.6.1.1:/var/ftp/cent8-1905-64
PXE 開機時所看到的提示訊息存放在 /tftpboot/linux-install/msgs/boot.msg 檔案.
[root@localhost ~]# vi /tftpboot/linux-install/msgs/boot.msg 0a .-=-. .--. __ .' '. / " ) _ .' '. / .-. \ / .-'0c\0a ( \ / .-. \ / / \ \ / / 0c^0a \ `-` / \ `-' / \ `-` / `-.-` '.____.' `.____.' 07 Enter Function key of the Operation System you wish to install: 0. Local Machine 0fcent7-1810-64 08Directory 0f/var/ftp/cent7-1810-64 0eCentOS 8 0fcent8-1905-64 08Directory 0f/var/ftp/cent8-1905-64
- UEFI
UEFI PXE 開機前導程式為 grubx64.efi 啟動之後會去讀取 PXE 開機的 grub.cfg 設定檔 (不同的開機前導程式會搭配不同的設定檔).[root@localhost ~]# vi /var/lib/tftpboot/grub.cfg set default="1" function load_video { insmod efi_gop insmod efi_uga insmod video_bochs insmod video_cirrus insmod all_video } load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set timeout=60 ### END /etc/grub.d/00_header ### ### BEGIN /etc/grub.d/10_linux ### menuentry 'Install CentOS 8 1905-64' --class fedora --class gnu-linux --class gnu --class os { linuxefi /cent8-1905-64/vmlinuz inst.repo=nfs:192.6.1.1:/var/ftp/cent8-1905-64 initrdefi /cent8-1905-64/initrd.img }
- Secure Boot
檔案 shimx64.efi 是用在 Secure Boot , 檔案放在 DVD \BaseOS\Packages\shim-x64-15-15.el8_2.x86_64.rpm , 可以用 rpmcpio 與 cpio 解開.[root@localhost ~]# rpm2cpio shim-x64-15-15.el8_2.x86_64.rpm | cpio -idmv ./boot/efi/EFI/BOOT/BOOTX64.EFI ./boot/efi/EFI/BOOT/fbx64.efi ./boot/efi/EFI/centos/BOOTX64.CSV ./boot/efi/EFI/centos/mmx64.efi ./boot/efi/EFI/centos/shimx64-centos.efi ./boot/efi/EFI/centos/shimx64.efi 10261 blocks
[root@localhost ~]# file ./boot/efi/EFI/centos/shimx64-centos.efi ./boot/efi/EFI/centos/shimx64-centos.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows [root@localhost ~]# file ./boot/efi/EFI/centos/shimx64.efi ./boot/efi/EFI/centos/shimx64.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
設定跟 EFI 是一樣的,只需把檔案取代成 shimx64.efi ( ChatGPT : 適用於各種 Linux 發行版,如 Ubuntu , Debian , Fedora 等) 或是 shimx64-centos.efi ( ChatGPT : 專屬於 CentOS 的)
不過手邊沒系統可以測試,先記錄起來.
另外如需要額外做簽核給其他系統開機,需自行使用 MOK (還沒試過).
Note If you have installed a Red Hat Enterprise Linux Beta release, on systems having UEFI Secure Boot enabled, then add the Beta public key to the system’s Machine Owner Key (MOK) list.
下一步會將其中指定的開機 kernel 和 RAMDisk 檔案複製到 /tftpboot/linux-install/ 指定目錄下.
FTP , NFS , HTTP
後續的安裝則需要透過 FTP , NFS , HTTP 有提供此服務的 Linux 皆可以擔任此項工作.
下面範例安裝作業系統是透過 NFS 方式,檔案置於 /var/ftp .
[root@localhost ~]# vi /etc/exports /var/ftp *(ro,no_root_squash) [root@localhost ~]# systemctl start nfs-server [root@localhost ~]# systemctl enable nfs-server
並將 CentOS8 ISO 解開並複製到 NFS Root – /var/ftp/
[root@localhost ~]# mkdir /run/media/iso [root@localhost ~]# mount -o loop CentOS-8-x86_64-1905-dvd1.iso
[root@localhost ~]# mkdir /var/ftp/cent8-1905-64 [root@localhost ~]# cp -rf /run/media/iso/ /var/ftp/cent8-1905-64
需注意在 CentOS 8 ISO 根目錄,有兩個隱藏檔 (檔名為 . 開頭) .treeinfo 與 .discinfo 須確認有複製到 /var/ftp/cent8-1905-64/ 路徑,不然在安裝的時候會出現以下的錯誤訊息.
failed to set up installation source: check the repo url
剛剛 TFTP 開機前導程式的設定檔,有指定的開機 kernel (vmlinuz) 和 RAMDisk (initrd.img) 檔案需複製到 /tftpboot/linux-install/ 指定目錄下.
[root@localhost ~]# mkdir /tftpboot/linux-install/cent8-1905-64 [root@localhost ~]# cp -rf /var/ftp/cent8-1905-64/images/pxeboot/* /tftpboot/linux-install/cent8-1905-64/
PXE clients
這時候就可以透過 PXE ,從網路卡來開機.
如果您這邊指的Security Boot是BIOS底下的相關名稱的選項,我的實作經驗的確tftpboot底下的引導檔有關,不知道是否可以實踐同時實作shim.efi跟grubx64.efi的方法呢?
我記得Redhat官方提供的資料,底下有提到相關的敘述,先前實作CentOS8.1架設PXE Sever的時候,有實驗過這個部分。
不過我當時把防火牆等功能全部關掉,所以您提供的資訊很有用哦