密码学¶
iPXE 支持 HTTPS 协议,允许你加密与 Web 服务器之间的所有通信,并验证服务器的身份。要启用 HTTPS 协议支持,必须启用 DOWNLOAD_PROTO_HTTPS 构建配置选项。
iPXE 支持代码签名,允许你验证 iPXE 下载的文件的真实性和完整性。要启用代码签名支持,必须启用 IMAGE_TRUST_CMD 构建配置选项,并在嵌入式脚本中使用 imgtrust 命令。
iPXE 支持文件解密,允许你解密 iPXE 下载的加密文件。要启用文件解密支持,必须启用 IMAGE_CRYPT_CMD 构建配置选项。
支持的配置¶
| 协议版本 | TLSv1.0 TLSv1.1 TLSv1.2 |
|---|---|
| 公钥算法 | RSA ECDSA |
| 密钥交换算法 | RSA DHE ECDHE |
| 分组密码算法 | AES-128-GCM AES-256-GCM AES-128-CBC AES-256-CBC |
| 散列算法 | MD5 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512 SHA-512/224 SHA-512/256 |
| 命名曲线 | X25519 P-256 P-384 |
支持的密码套件完整列表如下:
- TLS_RSA_WITH_AES_128_CBC_SHA
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_CBC_SHA256
- TLS_RSA_WITH_AES_256_CBC_SHA256
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
- TLS_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
受信任的根证书¶
在默认配置下,iPXE 只信任一个根证书:"iPXE root CA" 证书。这个根证书用于对标准的 Mozilla 公共 CA 证书列表进行交叉签名。
因此在默认配置下,iPXE 会自动信任与 Firefox 浏览器相同的一组证书。
如果你希望对信任链有更多的控制,可以用以下命令生成自己的私有根证书 ca.crt:
openssl req -x509 -newkey rsa:2048 -out ca.crt -keyout ca.key -days 1000
构建 iPXE 时,你可以使用 TRUST=... 构建参数修改受信任的根证书列表。例如,信任你的私有根证书 ca.crt:
make bin/ipxe.iso TRUST=ca.crt
这会生成一个信任你的私有根证书 ca.crt 的定制版 iPXE 二进制文件 ipxe.iso。
你可以指定多个要信任的根证书。例如:
make bin/ipxe.iso TRUST=/path/to/ca1.crt,/path/to/ca2.crt
证书必须是 PEM 格式。

完整的根证书通常太大,无法嵌入 iPXE 二进制文件中,因此默认只包含其 SHA-256 指纹。如果你使用默认的 "iPXE root CA" 证书,iPXE 会在需要时自动从 http://ca.ipxe.org/ca.crt(或从 crosscert 设置指定的镜像)下载完整的根证书。
如果你使用私有根证书,则必须通过以下方式之一让 iPXE 能够获取该证书:搭建自己的 crosscert 服务器;把根证书包含在所有提交给 iPXE 的证书链中(如下文所述);或者显式地把完整的根证书嵌入到 iPXE 二进制文件中。

签发证书¶
你可以使用私有根证书 ca.crt 签发会被 iPXE 信任的证书。为此,你必须创建一个最小的私有 CA 基础设施:
echo 01 > ca.srl
touch ca.idx
mkdir signed
你还必须创建一个最小的 CA 配置文件 ca.cnf,内容如下:
[ ca ]
default_ca = ca_default
[ ca_default ]
certificate = ca.crt
private_key = ca.key
serial = ca.srl
database = ca.idx
new_certs_dir = signed
default_md = default
policy = policy_anything
preserve = yes
default_days = 90
unique_subject = no
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional
[ cross ]
basicConstraints = critical,CA:true
keyUsage = critical,cRLSign,keyCertSign
[ codesigning ]
keyUsage = digitalSignature
extendedKeyUsage = codeSigning
现在你就可以生成新的服务器证书 server.crt 和对应的私钥 server.key 了:
openssl req -newkey rsa -keyout server.key -out server.req
openssl ca -config ca.cnf -in server.req -out server.crt
这会创建一个由你的私有根证书签名的服务器证书 server.crt。你还可以选择创建一个包含 server.crt 和你的私有根证书 ca.crt 的完整证书链:
cat server.crt ca.crt > server-full.crt
交叉签名证书¶
你可以使用私有 CA 基础设施对现有的公共 CA 根证书进行交叉签名。例如,对 StartCom 根证书进行交叉签名:
openssl ca -config ca.cnf -extensions cross -notext -preserveDN -ss_cert startcom.crt -out startcom-cross.crt
这会创建一个交叉签名的证书 startcom-cross.crt。这样你就可以把信任从你的私有根证书扩展到由 startcom.crt 签名的证书,而无需直接把 startcom.crt 列为 iPXE 受信任的根证书。
代码签名¶
你可以使用代码签名证书对二进制文件进行签名,使其被 iPXE 信任。用于代码签名的证书必须包含 digitalSignature 密钥用法扩展和 codeSigning 扩展密钥用法扩展。你可以用以下命令生成新的代码签名证书 codesign.crt 和对应的私钥 codesign.key:
openssl req -newkey rsa -keyout codesign.key -out codesign.req
openssl ca -config ca.cnf -extensions codesigning -in codesign.req -out codesign.crt
现在就可以用这个证书对二进制文件签名,使其被 iPXE 信任。例如,对二进制文件 vmlinuz 签名:
openssl cms -sign -binary -noattr -in vmlinuz \
-signer codesign.crt -inkey codesign.key -certfile ca.crt \
-outform DER -out vmlinuz.sig
这会创建签名文件 vmlinuz.sig,你可以配合 imgverify 命令来验证二进制文件 vmlinuz。例如,假设你想用嵌入式脚本通过不可信的网络下载 vmlinuz:
#!ipxe
imgtrust --permanent
dhcp
kernel http://${next-server}/boot/vmlinuz
imgverify vmlinuz http://${next-server}/boot/vmlinuz.sig
boot vmlinuz
这个嵌入式脚本只有在下载的 vmlinuz 能够通过签名文件 vmlinuz.sig 成功验证时才会引导,否则会拒绝引导。
嵌入式证书¶
构建 iPXE 时,你可以使用 CERT=... 构建参数嵌入一个或多个完整的证书。例如:
make bin/ipxe.iso CERT=cert1.crt,cert2.crt

嵌入式证书不会被自动信任;你需要使用 TRUST=... 构建参数显式指定任何受信任的根证书。例如:
make bin/ipxe.iso CERT=ca.crt TRUST=ca.crt
注意,嵌入式证书通常相当大,只有在无法从其他来源获取证书时(例如通过配置 crosscert 服务器)才应该嵌入证书。
外部提供的证书¶
iPXE 会自动获取固件平台提供的任何证书。例如,在 UEFI 平台上运行时,iPXE 会自动获取存储在 UEFI TlsCaCertificate 变量中的所有证书。
这些外部提供的证书默认会被信任。总体效果是:iPXE 会自动获取并信任固件平台所信任的任何证书。如果你是使用 UEFI HTTPS 引导来下载 iPXE 的,那么你就能自动使用 iPXE 从同一个 HTTPS 服务器下载文件。
你可以使用 certstat 命令查看任何外部提供的证书。
默认行为是信任外部提供的证书,除非你使用了自定义的受信任根证书。你可以使用 TRUST_EXT=... 构建参数显式控制是否信任外部提供的证书。例如:
# 使用默认根证书,不信任外部证书
make bin/ipxe.iso TRUST_EXT=0
# 使用自定义根证书,同时信任外部证书
make bin/ipxe.iso TRUST=ca.crt TRUST_EXT=1
客户端证书¶
你可以用以下命令生成客户端证书 client.crt 和对应的私钥 client.key:
openssl req -newkey rsa -keyout client.key -out client.req
openssl ca -config ca.cnf -in client.req -out client.crt
构建 iPXE 时,你可以使用 CERT=... 和 PRIVKEY=... 构建参数嵌入这个客户端证书(及对应的私钥)。例如:
make bin/ipxe.iso CERT=client.crt PRIVKEY=client.key
这会生成一个包含你的客户端证书(及对应私钥)的定制版 iPXE 二进制文件。然后你就可以配置 Web 服务器,要求使用这个客户端证书进行身份验证。
证书和私钥都必须是 PEM 格式。

注意,私钥以未加密的形式存储在 iPXE 二进制文件中。因此你应当把 iPXE 二进制文件视为机密信息。
使用客户端证书会给每个 HTTPS 连接带来明显的延迟(约一秒)。
文件解密¶
你可以使用客户端证书加密文件,然后在 iPXE 中解密。例如,加密二进制文件 vmlinuz:
openssl cms -encrypt -binary -aes-256-gcm -recip client.crt \
-in vmlinuz -outform DER -out vmlinuz.cms
./contrib/crypto/cmsdetach vmlinuz.cms -d vmlinuz.dat -e vmlinuz.env
这里使用了 cmsdetach 工具,它位于 iPXE 的 contrib/crypto 目录中,因为当前版本的 openssl cms 尚不支持分离式加密数据。
然后你可以使用 imgdecrypt 命令解密镜像。例如:
#!ipxe
dhcp
imgfetch http://${next-server}/boot/vmlinuz.dat
imgfetch http://${next-server}/boot/vmlinuz.env
imgdecrypt vmlinuz.dat vmlinuz.env
boot vmlinuz