---
# System prepended metadata

title: PXE Server setup

---

# PXE Server setup
預啟動執行環境（Preboot eXecution Environment，PXE，也被稱為預執行環境)提供了一種使用網路介面（Network Interface）啟動電腦的機制。這種機制讓電腦的啟動可以不依賴本地資料儲存裝置（如硬碟）或本地已安裝的作業系統。

PXE 伺服器必須要提供至少含有 DHCP 以及 TFTP :

DHCP 服務必須要能夠提供用戶端的網路參數之外，還得要告知用戶端 TFTP 所在的位置為何才行
TFTP 則是提供用戶端 boot loader 及 kernel file 下載點的重要服務
![](https://i.imgur.com/6T5BdlP.png)

**本次教學使用的方案為上圖中的DHCP+TFTP+NFS**


---

安裝套件
---
- sudo apt-get install -y tftpd-hpa isc-dhcp-server lftp openbsd-inetd nfs-kernel-server grub-efi-amd64 grub-efi-amd64-bin grub-efi-amd64-signed grub-imageboot grub-pc-bin grub2-splashimages shim shim-signed


---

DHCP 設定
---
首先編輯 /etc/dhcp/dhcpd.conf檔案，在下面配置 DHCP：

**for ipv4**
```typescript
ddns-update-style none;
default-lease-time 600;
max-lease-time 7200;
log-facility local7;

subnet 10.21.10.0 netmask 255.255.255.0 {
    range 10.21.10.200 10.21.10.250;
    option subnet-mask 255.255.255.0;
    option routers 10.21.10.254;
    option broadcast-address 10.21.10.255;
    filename "pxelinux.0";
    #UEFI
    #filename "uefi/syslinux.efi"; 
}
```

**For ipv6**

```typescript
 $ cd /etc/dhcp/
 $ sudo cp dhcpd.conf dhcpd6.conf
 $ touch /var/lib/dhcp/dhcpd6.leases
 $ sudo chmod 666 /var/lib/dhcp/dhcpd6.leases
 $ chown dhcpd:dhcpd /var/lib/dhcp/dhcpd6.leases
 $ sudo nano dhcpd6.conf
```
內容如下
```typescript
default-lease-time 600; 
max-lease-time 7200; 
log-facility local7; 
 
subnet6 2001:db8:0:1::/64 { 
             # Range for clients
             range6 2001:db8:0:1::129 2001:db8:0:1::254; 
             # Additional options 
             option dhcp6.name-servers fec0:0:0:1::1; 
             option dhcp6.domain-search "domain.example";
             filename "pxelinux.0";
             #UEFI
             option dhcp6.bootfile-url "tftp://[2001:db8:f00f:cafe::1]/uefi/syslinux.efi";
             # Prefix range for delegation to sub-routers 
             prefix6 2001:db8:0:100:: 2001:db8:0:f00:: /56; 
             # Example for a fixed host address (可加,可不加) 
             #host specialclient { 
                          #host-identifier    option dhcp6.client-id 00:01:00:01:4a:1f:ba:e3:60:b9:1f:01:23:45; 
                          #fixed-address6   2001:db8:0:1::127; 
             #} 
}
```
**指定DHCP作用之網路卡**
```typescript=
sudo vim /etc/default/isc-dhcp-server
```

```typescript
INTERFACES="eth0"
```
<font color=#0000FF>_"eth0"依照使用者網路卡名稱的不同會有不同的命名方式，請自行修改_</font>  
 <br><br/>
      
      

**建立ipv6 init file**
```typescript
$ sudo cp /etc/init.d/isc-dhcp-server /etc/init.d/isc-dhcp-server6
$ sudo sed -i s/isc-dhcp-server/isc-dhcp-server6/ /etc/init.d/isc-dhcp-server6
$ sudo sed -i s/dhcpd.conf/dhcpd6.conf/ /etc/init.d/isc-dhcp-server6
$ sudo sed -i s/dhcpd.pid/dhcpd6.pid/ /etc/init.d/isc-dhcp-server6
```

**完成後，重新啟動 DHCP 服務：**
```typescript
$ sudo service isc-dhcp-server restart
$ sudo service isc-dhcp-server6 restart

 * Stopping ISC DHCP server dhcpd [fail]
 * Starting ISC DHCP server dhcpd [ OK ]
```

**透過/var/lib/dhcp/dhcpd.leases驗證DHCP server是否正常運作
如有正常運作，將會看到DHCP server分派IP之列表**
```typescript
cat /var/lib/dhcp/dhcpd.leases
```
```typescript
lease 192.168.123.71 {
  starts 4 2021/06/10 02:13:39;
  ends 0 2021/06/20 02:13:39;
  cltt 4 2021/06/10 12:30:35;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet a4:ae:12:71:aa:6f;
  uid "\001\244\256\022q\252o";
  set vendor-class-identifier = "udhcp 1.21.1";
}
lease 192.168.123.69 {
  starts 4 2021/06/10 06:26:05;
  ends 0 2021/06/20 06:26:05;
  cltt 4 2021/06/10 12:01:23;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet 00:e0:4c:68:00:50;
  uid "\001\000\340Lh\000P";
  set vendor-class-identifier = "MSFT 5.0";
}
lease 192.168.123.63 {
  starts 4 2021/06/10 07:06:58;
  ends 0 2021/06/20 07:06:58;
  cltt 4 2021/06/10 10:06:26;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet e6:26:29:3f:52:0b;
  uid "\001\346&)?R\013";
  set vendor-class-identifier = "MSFT 5.0";
}
lease 192.168.123.66 {
  starts 4 2021/06/10 13:55:42;
  ends 0 2021/06/20 13:55:42;
  cltt 4 2021/06/10 15:13:38;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet a4:ae:12:71:aa:34;
  uid "\001\244\256\022q\2524";
  set vendor-class-identifier = "udhcp 1.21.1";
}
lease 192.168.123.73 {
  starts 4 2021/06/10 20:21:17;
  ends 0 2021/06/20 20:21:17;
  cltt 4 2021/06/10 20:21:17;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet a4:ae:12:6f:7b:b0;
  uid "\001\244\256\022o{\260";
  set vendor-class-identifier = "udhcp 1.21.1";
}

```



---

TFTP Server 設定
---
**編輯/etc/default/tftpd-hpa檔案：**
```typescript
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"
RUN_DAEMON="yes"
OPTIONS="-l -s /var/lib/tftpboot"
```

**接著設定 Boot 時啟動服務，以及重新啟動相關服務：**
```typescript
$ sudo update-rc.d tftpd-hpa defaults 
$ sudo service tftpd-hpa start
```


---

建立開機選單
---

>syslinux是一個功能強大的引導載入程式，而且兼容各種介質。它的目的是簡化首次安裝Linux的時間，並建立修護或其它特殊用途的啟動盤。它的安裝很簡單，一旦安裝syslinux好之後，sysLinux啟動盤就可以引導各種基於DOS的工具，以及MS-DOS/Windows或者任何其它作業系統。不僅支援採用BIOS結構的主機板，而且從6.0版也開始支援採用EFI結構的新型主機板。

>次教學選用syslinux作為PXE選單與引導載入程式
作為載入Linux與Windows的第一步

**完成後安裝 syslinux:**
```typescript
sudo apt-get -y install syslinux
```
**複製 syslinux 設定檔至/var/lib/tftpboot目錄中：**
for BIOS
```typescript
sudo cp /usr/lib/syslinux/menu.c32  /var/lib/tftpboot
sudo cp /usr/lib/syslinux/vesamenu.c32 /var/lib/tftpboot
sudo cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot
sudo cp /usr/lib/syslinux/memdisk /var/lib/tftpboot
sudo cp /usr/lib/syslinux/mboot.c32 /var/lib/tftpboot
sudo cp /usr/lib/syslinux/chain.c32 /var/lib/tftpboot
```
for UEFI 
```typescript=
mkdir /var/lib/tftpboot/uefi 
cp /var/lib/tftpboot/pxelinux.cfg var/lib/tftpboot/uefi/ -rf
sudo cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi /var/lib/tftpboot/uefi
sudo cp /usr/lib/syslinux/modules/efi64/ldlinux.e64 /var/lib/tftpboot/uefi
sudo cp /usr/lib/syslinux/modules/efi64/libcom32.c32 /var/lib/tftpboot/uefi
sudo cp /usr/lib/syslinux/modules/efi64/libutil.c32 /var/lib/tftpboot/uefi
sudo cp /usr/lib/syslinux/modules/efi64/vesamenu.c32 /var/lib/tftpboot/uefi
```


**建立/var/lib/tftpboot/pxelinux.cfg目錄：**
```typescript
$ sudo mkdir /var/lib/tftpboot/pxelinux.cfg
```

**接著編輯/var/lib/tftpboot/pxelinux.cfg/default檔案，設定開機選單，以下為簡單設定範例：**

```typescript
EFAULT vesamenu.c32
TIMEOUT 100
PROMPT 0
MENU INCLUDE pxelinux.cfg/pxe.conf
NOESCAPE 1

LABEL      localboot
MENU LABEL Boot from local disk
LOCALBOOT  0

LABEL Ubuntu 20.04 Desktop
MENU LABEL Install Ubuntu 20.04 Desktop
kernel ubuntu/20.04/casper/vmlinuz
append nfsroot=192.168.123.1:/var/lib/tftpboot/ubuntu/20.04 netboot=nfs ip=dhcp boot=casper initrd=ubuntu/20.04/casper/initrd systemd.mask=tmp.mount --

LABEL Ubuntu 20.10 Desktop
MENU LABEL Install Ubuntu 20.10 Desktop
kernel ubuntu/20.10/casper/vmlinuz
append nfsroot=192.168.123.1:/var/lib/tftpboot/ubuntu/20.10 netboot=nfs ip=dhcp boot=casper initrd=ubuntu/20.10/casper/initrd systemd.mask=tmp.mount --

LABEL      winpe
MENU LABEL Boot Windows PE from network
KERNEL     memdisk
INITRD     winpe.iso
APPEND     iso raw

ENDTEXT
```
**美化PXE開機選單，並存多個作業系統並且可以使用光棒選擇**
```typescript
sudo /var/lib/tftpboot/pxelinux.cfg/pxe.conf
```
```typescript
MENU TITLE PXE Server
NOESCAPE 1
ALLOWOPTIONS 1
PROMPT 0
MENU WIDTH 80
MENU ROWS 14
MENU TABMSGROW 24
MENU MARGIN 10
MENU COLOR border 30;44 #ffffffff #00000000 std
```
![](https://i.imgur.com/3x3R5Uc.png)


---

NFS Server 設定
---
```typescript
sudo nano /etc/exports
```
```typescript
/var/lib/tftpboot/ *(ro,async,no_root_squash,no_subtree_check)
```

>參數
    * rw：read-write，可讀寫的權限；
    * ro：read-only，唯讀的權限；
    * sync：資料同步寫入到記憶體與硬碟當中；
    * async：資料會先暫存於記憶體當中，而非直接寫入硬碟。
    * no_root_squash：
      登入 NFS 主機使用分享目錄的使用者如果是 root，對於分享的目錄具有 root 的權限。
      極不安全，不建議使用。
    * root_squash：
      登入 NFS 主機使用分享目錄的使用者如果是 root，權限將被壓縮成匿名使用者，
      通常他的 UID 與 GID 都會變成 nobody(nfsnobody) 那個系統帳號的身份；
    * all_squash：
      不論登入 NFS 的使用者身份為何，都會被壓縮成為匿名使用者，通常是 nobody(nfsnobody) 。
    * anonuid：
      anon 意指 anonymous (匿名者)，自訂匿名使用者的 UID。 
    * anongid：自訂匿名使用者的是變成 GID。


重啟nfs服務
```typescript
sudo /etc/init.d/nfs-kernel-server restart
```


---

新增啟動印象檔(Linux)
---

**以Ubuntu 20.10為範例**
```typescript
$ wget http://ubuntu.cs.nctu.edu.tw/ubuntu-release/20.10/ubuntu-20.10-desktop-amd64.iso
$ sudo mount ubuntu-20.10-desktop-amd64.iso /mnt
$ sudo mkdir /var/lib/tftpboot/ubuntu/
$ sudo mkdir /var/lib/tftpboot/ubuntu/20.10
$ sudo cp -r /mnt/.disk /var/lib/tftpboot/ubuntu/20.10
$ sudo cp -r /mnt/* /var/lib/tftpboot/ubuntu/20.10
```


---

新增啟動印象檔(Windows)
---
**透過PXE server安裝Windows的思路如下:**
1. 製作WinPE開機iso
2. 透過PXE載入WinPE
3. 從WinPE連線到網路磁碟
4. 進入網路磁碟內安裝Windows 7 or 10或是server...等

**製作WinPE開機iso**
```typescript
$ sudo apt-get install -y samba genisoimage wimtools cabextract
$ wget https://download.microsoft.com/download/8/E/9/8E9BBC64-E6F8-457C-9B8D-F6C9A16E6D6A/KB3AIK_EN.iso
$ sudo mount KB3AIK_EN.iso /mnt
$ sudo mkwinpeimg --iso --arch=amd64 --waik-dir=/mnt/ /var/lib/tftpboot/winpe.iso
$ sudo umount /mnt
```

**從PXE開機到WinPE後連線到網路磁碟**
```typescript
net use z: \\192.168.10.1\windows10
```

**進入網路磁碟內安裝Windows 7 or 10或是server...等**
```typescript
z:\setup.exe
```
![](https://i.imgur.com/Locm16E.png)
![](https://i.imgur.com/KE3YvNe.png)
![](https://i.imgur.com/hOLcF7u.png)
![](https://i.imgur.com/GsPlgNr.png)



