前两天跟一个碰到聊天时提到了UEFI,我说一下我现在的理解,不知道对不对。
严格的UEFI,应该是一个完整的信任链。主板上的UEFI代码启动后,无论它通过何种途径、介质(硬盘、光盘、U盘、PXE等等)获取到下一段要执行的代码(如bootloader或者某操作系统的内核),都要求这段代码是签名受信的,而这段代码再加载并引导下一段代码时也需要验证签名,如此下,严格意义上,到操作系统里,操作系统要加载运行的任何程序(驱动、应用程序等)也都必须要有签名,如此形成一个完整的信任链。
但是从实际实施的情况看,这条链越往后越难进行强制的签名验证,因为越往后,东西就越多,你不太可能限制用户能跑哪些软件(当然在某些受限环境下是可以的,比如对安全要求很高的企业、政府部门等)。
那么,既然是一个信任链,就得有个开端。主板一般可以直接引导bootloader或者直接引导操作系统内核。而bootloader或者操作系统内核的签名需要提前内置到主板上,因此,大家要么各自去找主板厂商签名,要么有一个中介,这个中介去找各主板厂商签名,然后所有的操作系统厂商可以找这个中介签名就好了。而微软因为跟主板厂商合作比较多,绝大多数UEFI的主板都已经内置了微软的证书,所以微软就顺理成章的成了这个中介,而且大家也是比较认可的,目前我没有听说过其他好使的“中介”。
接下来,就是大家找微软签名了。这里,像grub团队是不太可能找微软来签名的(或者微软不会给grub签名),因为grub不太可能保证它只引导有签名的内核(否则信任链到这里就断了),因为grub作为一个目标是通用的bootloader,要做限制的话,那就很麻烦了。但是操作系统厂商(比如redhat、ubuntu)可以自己编译一个grub的修改版,这个grub仅能引导有可信签名的内核,然后这个grub实例就可以去找微软(或者其他中介)签名。
当然,微软对这类bootloader签名时是否会放水、会放多少水,我不清楚,我没有实际去调研过。不过从我听到的信息来看,其实这一块管的不那么严。可能现在有被签过名的而且比较通用的grub,如果有人知道详情的话不妨分享一下信息。
扯远了。回到这个问题上来,那么我对这里PXE的场景的理解是:
主板(UEFI)的PXE代码 --> 获取next file
这里,以往我们的next file都是pxelinux,而pxelinux没有被签名的版本,因此严格的UEFI会拒绝执行这个pxelinux。因此,这里next file换成一个有签名的grub,这样UEFI就会交出控制权,引导这个grub了。
如果是这样的话,请问,这里ubuntu或者redhat提供的grub能否引导别的任意(无签名的)内核?能否chainload (无签名的)pxelinux?如果可以的话,那么我们不妨可以第一条next file为grub.efi,然后这个grub再chainload pxelinux,接下来就一样了。我个人觉得syslinux比grub更灵活一些,可以玩的东西很多。
比如我最近正在酝酿的一个功能(好吧,关于pxe我有好多想法,但N多年过去了都没有做),在一些场合下,PXE客户端启动后可以停下来,管理员可以在web页面里查看所有的PXE客户端,并在网页里控制每一台机器启动什么内容。比如,我在公司要批量装10台新服务器,我把他们都上架插线开机从PXE启动了,但是我没有kvm设备,接显示器也不方便(比如我现在的公司里的小机房里kvm就坏了),于是不方便选启动菜单,我就可以在另外一台电脑上开web页面来为每台机器设置启动参数。实现方法其实挺简单的,客户机启动后,获取一个菜单,而这个菜单没有实际的启动项,就是等1秒然后重新加载一次菜单。而服务器上就可以记录下来有这个主机(mac地址),并且管理员打开管理页面时就能看到这个主机,然后为这个主机配置启动参数,主机下一次刷新菜单时就得到实际的启动参数从而启动了。进一步,有些操作系统的安装也支持远程安装,比如
debian,这样PXE的管理后台网页上甚至可以跟踪操作系统安装的过程和进度了。