Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions api/machina/v1alpha3/machine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,18 @@ type PXESpec struct {
// +optional
BootProtocol string `json:"bootProtocol,omitempty"`

// InsecureDisableSecureBoot disables UEFI Secure Boot when using HTTP
// boot. By default, metalman enables Secure Boot for HTTP boot repaves.
// +optional
InsecureDisableSecureBoot bool `json:"insecureDisableSecureBoot,omitempty"`

// TrustedSecureBootKeys configures public certificates that metalman
// enrolls into UEFI Secure Boot databases through Redfish. The referenced
// data must contain a PEM-encoded X.509 certificate. Metalman only enrolls
// missing certificates and does not remove keys already present on the BMC.
// +optional
TrustedSecureBootKeys []TrustedSecureBootKeyRef `json:"trustedSecureBootKeys,omitempty"`

// DHCPLeases defines static DHCP leases for PXE booting.
// +optional
DHCPLeases []DHCPLease `json:"dhcpLeases,omitempty"`
Expand Down Expand Up @@ -327,8 +339,66 @@ const (
DefaultPXEArchitecture = PXEArchitectureAMD64
// DefaultPXEBootProtocol is used when spec.pxe.bootProtocol is omitted.
DefaultPXEBootProtocol = PXEBootProtocolPXE
// SecureBootDatabasePK is the UEFI Platform Key database.
SecureBootDatabasePK = "PK"
// SecureBootDatabaseKEK is the UEFI Key Exchange Key database.
SecureBootDatabaseKEK = "KEK"
// SecureBootDatabaseDB is the UEFI allowed signatures database.
SecureBootDatabaseDB = "db"
// SecureBootDatabaseDBX is the UEFI forbidden signatures database.
SecureBootDatabaseDBX = "dbx"
// DefaultSecureBootDatabase is used when a trusted Secure Boot key does
// not specify a database.
DefaultSecureBootDatabase = SecureBootDatabaseDB
)

// TrustedSecureBootKeyRef references a public Secure Boot certificate to enroll.
type TrustedSecureBootKeyRef struct {
// Database is the UEFI Secure Boot database to enroll into. Defaults to db,
// the allowed signatures database used to trust bootloader signing keys.
// +kubebuilder:validation:Enum=PK;KEK;db;dbx
// +kubebuilder:default=db
// +optional
Database string `json:"database,omitempty"`

// SecretKeyRef references a Secret key containing a PEM-encoded X.509
// certificate.
// +optional
SecretKeyRef *SecureBootObjectKeySelector `json:"secretKeyRef,omitempty"`

// ConfigMapKeyRef references a ConfigMap key containing a PEM-encoded X.509
// certificate.
// +optional
ConfigMapKeyRef *SecureBootObjectKeySelector `json:"configMapKeyRef,omitempty"`
}

// TargetDatabase returns the effective UEFI Secure Boot database.
func (r *TrustedSecureBootKeyRef) TargetDatabase() string {
if r == nil || r.Database == "" {
return DefaultSecureBootDatabase
}

return r.Database
}

// SecureBootObjectKeySelector selects a key from a Secret or ConfigMap.
type SecureBootObjectKeySelector struct {
// Name of the object.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`

// Namespace of the object.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Namespace string `json:"namespace"`

// Key within the object.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Key string `json:"key"`
}

// TargetArchitecture returns the effective PXE target architecture.
func (p *PXESpec) TargetArchitecture() string {
if p == nil || p.Architecture == "" {
Expand Down
47 changes: 47 additions & 0 deletions api/machina/v1alpha3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions cmd/metalman/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ spec:
image: ghcr.io/azure/host-ubuntu2404:v1
# Defaults to PXE. Set to HTTP to use Redfish UEFI HTTP boot.
bootProtocol: PXE
# HTTP boot enables UEFI Secure Boot by default. Set this only when
# the target image or firmware cannot boot with Secure Boot enabled.
insecureDisableSecureBoot: false
dhcpLeases:
- mac: "aa:bb:cc:dd:ee:01"
ipv4: "10.0.0.11"
Expand All @@ -201,6 +204,13 @@ boot artifacts from the default netboot image. Set `spec.pxe.netbootImage` only
when a Machine needs a non-default PXE boot environment. The node must be
manually PXE-booted (or have PXE as its default boot option).

When `spec.pxe.bootProtocol` is `HTTP`, Metalman uses Redfish UEFI HTTP boot and
reconciles the BMC SecureBoot resource before the repave. Secure Boot is enabled
by default. Set `spec.pxe.insecureDisableSecureBoot: true` to actively reconcile
`SecureBootEnable` to `false`. The default netboot image serves signed shim
artifacts via `metadata.yaml:httpBootPath`; custom netboot images should set
`httpBootPath` to their signed HTTP bootloader path.

#### BMC

Adding a `redfish` block enables remote power management. The controller will
Expand Down
72 changes: 72 additions & 0 deletions deploy/machina/crd/unbounded-cloud.io_machines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@ spec:
The image must contain /disk/disk.img.gz.
Example: "ghcr.io/azure/host-ubuntu2404:v1"
type: string
insecureDisableSecureBoot:
description: |-
InsecureDisableSecureBoot disables UEFI Secure Boot when using HTTP
boot. By default, metalman enables Secure Boot for HTTP boot repaves.
type: boolean
netbootImage:
description: |-
NetbootImage is an OCI image reference containing the PXE boot
Expand Down Expand Up @@ -443,6 +448,73 @@ spec:
- url
- username
type: object
trustedSecureBootKeys:
description: |-
TrustedSecureBootKeys configures public certificates that metalman
enrolls into UEFI Secure Boot databases through Redfish. The referenced
data must contain a PEM-encoded X.509 certificate. Metalman only enrolls
missing certificates and does not remove keys already present on the BMC.
items:
description: TrustedSecureBootKeyRef references a public Secure
Boot certificate to enroll.
properties:
configMapKeyRef:
description: |-
ConfigMapKeyRef references a ConfigMap key containing a PEM-encoded X.509
certificate.
properties:
key:
description: Key within the object.
minLength: 1
type: string
name:
description: Name of the object.
minLength: 1
type: string
namespace:
description: Namespace of the object.
minLength: 1
type: string
required:
- key
- name
- namespace
type: object
database:
default: db
description: |-
Database is the UEFI Secure Boot database to enroll into. Defaults to db,
the allowed signatures database used to trust bootloader signing keys.
enum:
- PK
- KEK
- db
- dbx
type: string
secretKeyRef:
description: |-
SecretKeyRef references a Secret key containing a PEM-encoded X.509
certificate.
properties:
key:
description: Key within the object.
minLength: 1
type: string
name:
description: Name of the object.
minLength: 1
type: string
namespace:
description: Namespace of the object.
minLength: 1
type: string
required:
- key
- name
- namespace
type: object
type: object
type: array
required:
- image
type: object
Expand Down
47 changes: 47 additions & 0 deletions docs/content/guides/pxe.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,53 @@ spec:

Store BMC passwords in a Secret referenced by `passwordRef`. See the [CRD Reference]({{< relref "/reference/machina-crd" >}}) for all fields.

## Secure Boot Trusted Keys

When a Machine has `spec.pxe.redfish`, metalman can enroll trusted UEFI Secure Boot certificates through Redfish before enabling Secure Boot or changing boot order. Each trusted key must be a PEM-encoded X.509 certificate stored in a Secret or ConfigMap. By default certificates are enrolled into `db`, the UEFI allowed signatures database used to trust bootloader signing keys.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: secure-boot-certs
namespace: unbounded-kube
type: Opaque
stringData:
db.pem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
```

Reference the certificate from the Machine:

```yaml
apiVersion: unbounded-cloud.io/v1alpha3
kind: Machine
metadata:
name: server-01
spec:
pxe:
image: ghcr.io/azure/host-ubuntu2404:v1
redfish:
url: "https://bmc-01.example.com"
username: admin
passwordRef:
name: bmc-passwords
namespace: unbounded-kube
key: bmc-01
trustedSecureBootKeys:
- database: db
secretKeyRef:
name: secure-boot-certs
namespace: unbounded-kube
key: db.pem
```

`database` can be `PK`, `KEK`, `db`, or `dbx`; omit it to use `db`. ConfigMap-backed certificates use `configMapKeyRef` with the same `name`, `namespace`, and `key` fields.

Metalman compares the certificate's SHA-256 DER fingerprint with certificates already reported by the BMC and only POSTs missing certificates. It does not delete keys that are present on the BMC but absent from the Machine spec. If a Machine configures trusted keys and the BMC does not support Redfish certificate enrollment, reconciliation fails closed and sets `SecureBootKeyEnrollmentSupported=False`.

## Cloud-Init Customization

Cloud-init on PXE-booted machines uses two data sources that are merged at boot:
Expand Down
11 changes: 11 additions & 0 deletions docs/content/reference/machina-crd.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ PXE boot configuration consumed by the metalman controller.
| `pxe.architecture` | string | No | `amd64` | Target CPU architecture for PXE boot artifacts and machine images. Allowed values: `amd64`, `arm64`. |
| `pxe.netbootImage` | string | No | Metalman default | OCI netboot image reference containing PXE boot artifacts. |
| `pxe.bootProtocol` | string | No | `PXE` | Network boot trigger protocol for repaves. `PXE` uses DHCP/TFTP bootfile options. `HTTP` uses Redfish UEFI HTTP boot with a URL derived from the netboot image metadata. Allowed values: `PXE`, `HTTP`. |
| `pxe.insecureDisableSecureBoot` | bool | No | `false` | Disables UEFI Secure Boot configuration through Redfish. By default, metalman enables Secure Boot for HTTP boot repaves. |
| `pxe.trustedSecureBootKeys` | []TrustedSecureBootKeyRef | No | - | PEM-encoded X.509 certificates to enroll into UEFI Secure Boot databases through Redfish. Metalman enrolls missing certificates and does not remove existing keys. |
| `pxe.trustedSecureBootKeys[].database` | string | No | `db` | UEFI Secure Boot database to enroll into. Allowed values: `PK`, `KEK`, `db`, `dbx`. |
| `pxe.trustedSecureBootKeys[].secretKeyRef` | SecureBootObjectKeySelector | No | - | Secret key containing a PEM-encoded X.509 certificate. Exactly one of `secretKeyRef` or `configMapKeyRef` should be set. |
| `pxe.trustedSecureBootKeys[].configMapKeyRef` | SecureBootObjectKeySelector | No | - | ConfigMap key containing a PEM-encoded X.509 certificate. Exactly one of `secretKeyRef` or `configMapKeyRef` should be set. |
| `pxe.trustedSecureBootKeys[].secretKeyRef.name` | string | Yes | - | Secret name. |
| `pxe.trustedSecureBootKeys[].secretKeyRef.namespace` | string | Yes | - | Secret namespace. |
| `pxe.trustedSecureBootKeys[].secretKeyRef.key` | string | Yes | - | Secret data key. |
| `pxe.trustedSecureBootKeys[].configMapKeyRef.name` | string | Yes | - | ConfigMap name. |
| `pxe.trustedSecureBootKeys[].configMapKeyRef.namespace` | string | Yes | - | ConfigMap namespace. |
| `pxe.trustedSecureBootKeys[].configMapKeyRef.key` | string | Yes | - | ConfigMap data or binaryData key. |
| `pxe.dhcpLeases` | []DHCPLease | No | - | Static DHCP leases served during PXE boot. |
| `pxe.dhcpLeases[].ipv4` | string | Yes | - | Static IPv4 address to assign. |
| `pxe.dhcpLeases[].mac` | string | Yes | - | NIC MAC address (matched case-insensitively). |
Expand Down
Loading