CentOS 8 – Security PXE Boot

參考文件 – https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/performing_an_advanced_rhel_installation/preparing-for-a-network-install_installing-rhel-as-an-experienced-user

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 ( http://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

這邊我支援多種 client-arch-type ,詳細請參考 – http://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 常見的錯誤訊息 http://benjr.tw/94695

需安裝 tftp 所需套件.

[root@localhost ~]# yum install tftp-server tftp

設定檔位於 /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/ .

  1. grubx64.efi (另外一個 shim.efi 用在 Secure Boot) – EFI PXE 會用到,在 CentOS 8 ISO 目錄 /EFI/BOOT/grubx64.efi
    [root@localhost ~]# cp /run/media/root/EFI/BOOT/grubx64.efi /var/lib/tftpboot/
    
  2. 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 /tftpboot/linux-install/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 
    }
    

下一步會將其中指定的開機 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 ,從網路卡來開機.

沒有解決問題,試試搜尋本站其他內容

One thought on “CentOS 8 – Security PXE Boot

  1. 如果您這邊指的Security Boot是BIOS底下的相關名稱的選項,我的實作經驗的確tftpboot底下的引導檔有關,不知道是否可以實踐同時實作shim.efi跟grubx64.efi的方法呢?
    我記得Redhat官方提供的資料,底下有提到相關的敘述,先前實作CentOS8.1架設PXE Sever的時候,有實驗過這個部分。
    不過我當時把防火牆等功能全部關掉,所以您提供的資訊很有用哦

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料