iPXE supports the HTTPS protocol, which allows you to encrypt all communication with a web server and to verify the server's identity. To enable support for the HTTPS protocol, you must enable the DOWNLOAD_PROTO_HTTPS build configuration option.
iPXE supports code signing, which allows you to verify the authenticity and integrity of files downloaded by iPXE. To enable support for code signing, you must enable the IMAGE_TRUST_CMD build configuration option, and use the imgtrust
command within an embedded script.
iPXE supports file decryption, which allows you to decrypt encrypted files downloaded by iPXE. To enable support for file decryption, you must enable the IMAGE_CRYPT_CMD build configuration option.
Protocol versions | TLSv1.0 TLSv1.1 TLSv1.2 |
---|---|
Public-key algorithms | RSA |
Key exchange algorithms | RSA DHE ECDHE |
Block cipher algorithms | AES-128-GCM AES-256-GCM AES-128-CBC AES-256-CBC |
Hash algorithms | MD5 SHA-1 SHA-224 SHA-256 SHA-384 SHA-512 SHA-512/224 SHA-512/256 |
Named curves | X25519 |
The exact list of supported cipher suites is:
In the default configuration, iPXE trusts only a single root certificate: the "iPXE root CA" certificate. This root certificate is used to cross-sign the standard Mozilla list of public CA certificates.
In the default configuration, iPXE will therefore automatically trust the same set of certificates as the Firefox web browser.
If you want more control over the chain of trust, then you can generate your own private root certificate ca.crt
using:
openssl req -x509 -newkey rsa:2048 -out ca.crt -keyout ca.key -days 1000
You can change the list of trusted root certificates when you build iPXE using the TRUST=...
build parameter. For example, to trust your private root certificate ca.crt
:
make bin/ipxe.iso TRUST=ca.crt
This will create a custom version of the iPXE binary ipxe.iso
which trusts your private root certificate ca.crt
.
You can specify multiple root certificates to trust. For example:
make bin/ipxe.iso TRUST=/path/to/ca1.crt,/path/to/ca2.crt
Certificates must be in PEM format.
The full root certificates are generally too large to be embedded into the iPXE binary, and so only the SHA-256 fingerprints will be included by default. If you are using the default "iPXE root CA" certificate, then iPXE will automatically download the full root certificate as needed from http://ca.ipxe.org/ca.crt (or from a mirror specified using the crosscert
setting).
If you are using a private root certificate, then you must make this certificate available to iPXE either by setting up your own crosscert
server, or by including the root certificate within all certificate chains presented to iPXE (as documented below), or by explicitly embedding the full root certificate within the iPXE binary.
You can use your private root certificate ca.crt
to issue certificates that will be trusted by iPXE. To do this, you must create a minimal private CA infrastructure:
echo 01 > ca.srl touch ca.idx mkdir signed
You must also create a minimal CA configuration file ca.cnf
, containing:
[ 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
You can now generate a new server certificate server.crt
and the corresponding private key server.key
using:
openssl req -newkey rsa -keyout server.key -out server.req openssl ca -config ca.cnf -in server.req -out server.crt
This will create a server certificate server.crt
which is signed by your private root certificate. You can optionally create a full certificate chain including both server.crt
and your private root certificiate ca.crt
using:
cat server.crt ca.crt > server-full.crt
You can use your private CA infrastructure to cross-sign an existing public CA root certificate. For example, to cross-sign the StartCom root certificate:
openssl ca -config ca.cnf -extensions cross -notext -preserveDN -ss_cert startcom.crt -out startcom-cross.crt
This will create a cross-signed certificate startcom-cross.crt
. This allows you to extend the trust from your private root certificate to include certificates signed by startcom.crt
, without having to directly include startcom.crt
as an iPXE trusted root certificate.
You can use a code-signing certificate to sign a binary so that it will be trusted by iPXE. Certificates used for code signing must include the digitalSignature key usage extension and the codeSigning extended key usage extension. You can generate a new code-signing certificate codesign.crt
and the corresponding private key codesign.key
using:
openssl req -newkey rsa -keyout codesign.key -out codesign.req openssl ca -config ca.cnf -extensions codesigning -in codesign.req -out codesign.crt
You can now use this certificate to sign a binary that will then be trusted by iPXE. For example, to sign the binary vmlinuz
:
openssl cms -sign -binary -noattr -in vmlinuz \ -signer codesign.crt -inkey codesign.key -certfile ca.crt \ -outform DER -out vmlinuz.sig
This will create the signature file vmlinuz.sig
, which you can use with the imgverify
command to verify the binary vmlinuz
. For example, suppose that you want to use an embedded script to download vmlinuz
over an untrusted network:
#!ipxe imgtrust --permanent dhcp kernel http://${next-server}/boot/vmlinuz imgverify vmlinuz http://${next-server}/boot/vmlinuz.sig boot vmlinuz
This embedded script would refuse to boot unless the downloaded version of vmlinuz
could be successfully verified using the signature file vmlinuz.sig
.
You can embed one or more full certificates when you build iPXE using the CERT=...
build parameter. For example:
make bin/ipxe.iso CERT=cert1.crt,cert2.crt
Embedded certificates are not automatically trusted; you will need to specify any trusted root certificates explicitly using the TRUST=...
build parameter. For example:
make bin/ipxe.iso CERT=ca.crt TRUST=ca.crt
Note that embedded certificates are generally quite large, and you should embed a certificate only if it is not feasible to obtain the certificate from another source (e.g. by configuring a crosscert
server).
You can generate a client certificate client.crt
and the corresponding private key client.key
using:
openssl req -newkey rsa -keyout client.key -out client.req openssl ca -config ca.cnf -in client.req -out client.crt
You can embed this client certificate (and the corresponding private key) when you build iPXE using the CERT=...
and PRIVKEY=...
build parameters. For example:
make bin/ipxe.iso CERT=client.crt PRIVKEY=client.key
This will create a custom version of the iPXE binary which includes your client certificate (and the corresponding private key). You can now configure your web server to require the use of this client certificate for authentication.
The certificate and key must both be in PEM format.
Note that the private key is stored unencrypted within the iPXE binary. You should therefore treat the iPXE binary as being confidential information.
Using a client certificate will add a noticeable delay (approximately one second) to each HTTPS connection.
You can encrypt a file using a client certificate, and then decrypt it within iPXE. For example, to encrypt the binary 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
This uses the cmsdetach
utility, which you can find in iPXE's contrib/crypto
directory, since current versions of openssl cms
do not yet support detached encrypted data.
You can then use the imgdecrypt
command to decrypt the image. For example:
#!ipxe dhcp imgfetch http://${next-server}/boot/vmlinuz.dat imgfetch http://${next-server}/boot/vmlinuz.env imgdecrypt vmlinuz.dat vmlinuz.env boot vmlinuz