前言
在之前的工作中,我尝试使用了Pxe网启方式进入PE,然后完成全自动化的操作系统的安装及访问共享等操作,现在把实现思路记下来,以备不时之需。
环境介绍
服务器操作系统: Ubuntu 22.04 LTSC
所需软件包: isc-kea-dhcp4-server
ntp
tftpd-hpa
nginx
samba
iPXE
另外需要两个虚拟机,启动方式分别为 pcbios
和 uefi
,用以模拟和测试绝大部分电脑的启动方式
查看软件详细说明
isc-kea-dhcp4-server
用于dhcp下发ip地址,告知客户端从哪一台服务器上启动,并通过客户端的RFC标识符(RFC4578)决定给客户端下发什么文件,进行什么样的操作。
ntp
用于同步各客户端的时间,在下发ip地址时会告知局域网内存在NTP服务器,同步所有客户端时间至与服务器相同,方便各客户端进行时间调整。
tftpd-hpa
用于客户端通过tftp协议下载启动文件,但因tftp速度较慢(即使在局域网环境下),不适合下发大型镜像,在本案例中仅用于下发iPXE启动固件及选项菜单,不再持有其他镜像文件
nginx
用于客户端通过http下载一些资源,在本案例中主要为图片及其他菜单等,同样可用来下发一些中小型镜像及展示服务器主页,不再过多介绍。
samba
用于在不同客户端内共享资料,也用于中心化分发软件包和更新项目,用于客户端更新自身资料等。
iPXE
主要用于支持一些老电脑原生不支持的高级功能,iPXE会在启动的第一时间被加载,然后读取服务器上的菜单或高级选项等,做进一步的分流/调整,也可以导入部分文件到系统内部等。
1.在此之前
本文章假定你清楚UEFI
以及BIOS
的区别,以及网络启动的基本概念,如果你不清楚,请先阅读这一部分,以完全了解两者有何不同,方便更清楚地了解我们在做什么。
1.1 UEFI引导和BIOS引导
我想你可能知道BIOS是什么,不就是基本输入输出操作系统
嘛(Basic Input Output System),但我们这里讲到的 BIOS 不同于你所理解的,这里的BIOS是指硬件系统的引导方式或类型,它使用经典的BIOS底层执行引导,通常伴随黑色背景的引导屏幕,以及不断闪烁的字符,操作系统以这种方式引导时速度较慢,且它不支持一些较为现代化的硬盘分区格式。
那么,UEFI是什么?你可能会问, UEFI是一个相对现代化的系统引导解决方案,在一些较新或最新的主板中,你进入“BIOS”,会看到一个相对华丽的图形UI而不是文字界面,那也是UEFI的一部分,UEFI允许使用新的功能和特性,它更安全也更现代化。
通常,在主板的启动设置页面内,BIOS引导方式会作为兼容性选项提供,名称条目一般均包含CSM
(Compatibility Support Module 兼容性支持模块),启用它才可以让主板使用BIOS引导方式,我们不推荐使用这种引导方式,在本文章中同样作为“兼容性选项”进行配置,用于兼容较老的硬件。
2.准备软件包
本来我是想从操作系统安装开始写,不过相信大家都会,就跳过这一步,首先准备工具链,进行所需软件包的安装
2.1.iPXE
默认情况下,由于客户端平台的不统一性,不同的主板对于网络启动的支持不尽相同,所以我们需要给各个需要启动的客户端设置一个“起跑线”,以让接下来的步骤能够成功完成,要做到这点,我们就要用到一个对各个平台兼容最强也是网络启动元老级别的固件程序,iPXE,它可以兼容几乎所有市面上的主板,完美实现我们所需要的一个标准起跑线。
标准情况下,官方提供了一个官方发布版的iPXE固件程序,可用于UEFI和BIOS引导,名称分别为:ipxe.efi
和 undionly.kpxe
,但如果你在本实例中使用了官方发布的版本,你可能会陷入无尽的启动死循环中,例如下图以及这个文档所示

为了解除这个死循环,我们可以通过两种不同的方式。
- 自行编译iPXE固件
- 通过DHCP服务器识别判断
在我的测试中,通过DHCP服务器识别判断会偶尔出现不准确或者配置文件压根就没用的情况,所以我选择自行编译一份新的iPXE固件,使其无论是什么情况下均跳转到指定的入口,而不是自动从服务器上拉取,避免出现死循环。
编译iPXE固件
编译这个固件的方式相对来说很简单,根据官方文档所示,我们只需要做到以下几点
- 克隆官方仓库
- 修改编译选项
- 执行编译
很简单,接下来一步步进行,首先执行以下命令,克隆官方仓库。
然后,创建一份自定义的配置文件,用于编译出我们自己的一个版本。
接下来,将配置文件修改成大概下面的样子,
最后,执行编译,打包出分别应用于UEFI和BIOS的固件包。
OK,如果一切顺利的话,我们就会在bin目录下得到undionly.kpxe文件和ipxe.efi文件,保留好它们,待会儿用。
2.2.tftpd-hpa
如上所说,tftp服务器用于下发启动时的各种文件,上一步编译得到的文件同样需要在这里用到,先安装它
然后,修改下它的默认配置和文件存储目录,在这个文档中,我们假定tftp存储目录为 /mnt/boot/tftp,配置文件默认在/etc/default/tftpd-hpa
,可参考的文档:WIKI
然后,重载服务,并设置为开机启动
2.3.ntp
NTP提供了局域网内的时间同步服务,它并不重要,但很方便,我们不需要对它做过多的配置,简单安装即可。
它的配置文件路径是/etc/ntp.conf,我们不需要做什么修改,安装好了就行。
2.4.isc-kea-dhcp4-server
终于到了重头戏,dhcp服务器提供了一切功能的基础,它负责下发IP地址给接口下的所有客户端,也负责决定客户端会以什么固件启动,在之前,我会选用isc-dhcp-server
,但它现在已经停止开发,isc团队给了一个新的选择,isc-kea-dhcp4-sever,用于更好地管理和控制。
首先,Ubuntu的默认软件安装源并不包括isc-kea-dhcp4-server这个软件包,我们需要使用到官方发布源,来自于cloud smithm,以下是安装脚本。
在之后,我们就可以执行安装isc-kea-dhcp4-server,由于我们不需要任何其他的功能以及IPV6的支持,所以在这里就不安装团队提供的其他附加安装包,仅使用ipv4的dhcp服务器即可。它的配置文件默认路径为/etc/kea/kea-dhcp4.conf
根据官方文档,它同样支持各种配置和骚操作,但默认配置文件有很多无用配置项,我们删除它,并重新创建一份配置文件。
配置文件主要是JSON格式,但支持注释,以下是我们需要填写的字段,以及字段的相应解释,你同样可以复制一份直接使用,同样,你也可以参考官方文档
配置项中的具体项目,请参考以下文档
- https://kea.readthedocs.io/en/kea-2.6.0/arm/dhcp4-srv.html#interface-configuration
- https://kea.readthedocs.io/en/kea-2.6.0/arm/dhcp4-srv.html#setting-fixed-fields-in-classification
- https://kea.readthedocs.io/en/kea-2.6.0/arm/dhcp4-srv.html#standard-dhcpv4-options
- https://tools.ietf.org/html/rfc4578#section-2.1
在之后,我们需要给配置文件中所指定的网卡一个IP地址,作为基准网关地址,在以上配置文件中,地址为10.1.0.1
,另外,记得将该地址排除在地址池之外,以免分配冲突,Ubuntu中使用netplan
作为网卡配置工具,配置文件为/etc/netplan/00-installer-config.yaml
(默认情况下),修改网卡对应的IP地址,在这个配置文件中是 ens37
,
配置完成后,应用到网卡
然后重启对应服务,使配置文件生效
最难的部分已经完成了,接下来继续我们的操作
3.文件环境部署
还记得我们在第二部分第一小节编译的两个iPXE文件以及TFTP文件存储路径吗?将两个iPXE文件放到TFTP的存储路径下,同时,在TFTP存储目录下新建一个文件,名称为nextboot
,名称与你在编译部分的demo.ipxe
文件中chain后面的名称相同,用于iPXE固件加载这个文件。
在完成创建后,我们需要修改它,让其显示一个基本菜单,用于测试BIOS及UEFI启动是否正常。
展开配置文件内容
然后保存它,开启一个虚拟机测试是否正常。


好好好