feat: support systemd-boot ISO enroll keys option
Fixes #8196 Example (profile excerpt): ```yaml output: kind: iso isoOptions: sdBootEnrollKeys: force outFormat: raw ``` Defaults are still same (`if-safe` unless explicitly overridden). Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
parent
afa71d6b02
commit
087b50f429
@ -49,6 +49,20 @@ machine:
|
||||
features:
|
||||
localDNS: false
|
||||
```
|
||||
"""
|
||||
|
||||
[notes.secureboot-image]
|
||||
title = "Secure Boot Image"
|
||||
description = """\
|
||||
Talos Linux now provides a way to configure systemd-boot ISO 'secure-boot-enroll' option while generating a SecureBoot ISO image:
|
||||
|
||||
```yaml
|
||||
output:
|
||||
kind: iso
|
||||
isoOptions:
|
||||
sdBootEnrollKeys: force # default is still if-safe
|
||||
outFormat: raw
|
||||
```
|
||||
"""
|
||||
|
||||
[notes.rsa-service-account]
|
||||
|
@ -1,5 +0,0 @@
|
||||
# systemd-boot configuration
|
||||
|
||||
timeout 10
|
||||
|
||||
secure-boot-enroll if-safe
|
5
pkg/imager/iso/loader.conf.tmpl
Normal file
5
pkg/imager/iso/loader.conf.tmpl
Normal file
@ -0,0 +1,5 @@
|
||||
# systemd-boot configuration
|
||||
|
||||
timeout 10
|
||||
|
||||
secure-boot-enroll {{ .SecureBootEnroll }}
|
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/siderolabs/go-cmd/pkg/cmd"
|
||||
|
||||
@ -24,6 +25,9 @@ type UEFIOptions struct {
|
||||
UKIPath string
|
||||
SDBootPath string
|
||||
|
||||
// A value in loader.conf secure-boot-enroll: off, manual, if-safe, force.
|
||||
SDBootSecureBootEnrollKeys string
|
||||
|
||||
// optional, for auto-enrolling secureboot keys
|
||||
PlatformKeyPath string
|
||||
KeyExchangeKeyPath string
|
||||
@ -41,8 +45,8 @@ const (
|
||||
mib = 1024 * 1024
|
||||
)
|
||||
|
||||
//go:embed loader.conf
|
||||
var loaderConfig []byte
|
||||
//go:embed loader.conf.tmpl
|
||||
var loaderConfigTemplate string
|
||||
|
||||
// CreateUEFI creates an iso using a UKI, systemd-boot.
|
||||
//
|
||||
@ -54,6 +58,8 @@ func CreateUEFI(printf func(string, ...any), options UEFIOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
printf("preparing raw image")
|
||||
|
||||
efiBootImg := filepath.Join(options.ScratchDir, "efiboot.img")
|
||||
|
||||
// initial size
|
||||
@ -75,6 +81,18 @@ func CreateUEFI(printf func(string, ...any), options UEFIOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
printf("preparing loader.conf")
|
||||
|
||||
var loaderConfigOut bytes.Buffer
|
||||
|
||||
if err := template.Must(template.New("loader.conf").Parse(loaderConfigTemplate)).Execute(&loaderConfigOut, struct {
|
||||
SecureBootEnroll string
|
||||
}{
|
||||
SecureBootEnroll: options.SDBootSecureBootEnrollKeys,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error rendering loader.conf: %w", err)
|
||||
}
|
||||
|
||||
printf("creating vFAT EFI image")
|
||||
|
||||
fopts := []makefs.Option{
|
||||
@ -125,7 +143,7 @@ func CreateUEFI(printf func(string, ...any), options UEFIOptions) error {
|
||||
}
|
||||
|
||||
if _, err := cmd.RunContext(
|
||||
cmd.WithStdin(context.Background(), bytes.NewReader(loaderConfig)),
|
||||
cmd.WithStdin(context.Background(), &loaderConfigOut),
|
||||
"mcopy", "-i", efiBootImg, "-", "::loader/loader.conf",
|
||||
); err != nil {
|
||||
return err
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
||||
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||
"github.com/siderolabs/go-pointer"
|
||||
"github.com/siderolabs/go-procfs/procfs"
|
||||
|
||||
"github.com/siderolabs/talos/cmd/installer/pkg/install"
|
||||
@ -85,10 +86,14 @@ func (i *Imager) outISO(ctx context.Context, path string, report *reporter.Repor
|
||||
var err error
|
||||
|
||||
if i.prof.SecureBootEnabled() {
|
||||
isoOptions := pointer.SafeDeref(i.prof.Output.ISOOptions)
|
||||
|
||||
options := iso.UEFIOptions{
|
||||
UKIPath: i.ukiPath,
|
||||
SDBootPath: i.sdBootPath,
|
||||
|
||||
SDBootSecureBootEnrollKeys: isoOptions.SDBootEnrollKeys.String(),
|
||||
|
||||
PlatformKeyPath: i.prof.Input.SecureBoot.PlatformKeyPath,
|
||||
KeyExchangeKeyPath: i.prof.Input.SecureBoot.KeyExchangeKeyPath,
|
||||
SignatureKeyPath: i.prof.Input.SecureBoot.SignatureKeyPath,
|
||||
|
@ -37,5 +37,9 @@ func (o Profile) DeepCopy() Profile {
|
||||
cp.Output.ImageOptions = new(ImageOptions)
|
||||
*cp.Output.ImageOptions = *o.Output.ImageOptions
|
||||
}
|
||||
if o.Output.ISOOptions != nil {
|
||||
cp.Output.ISOOptions = new(ISOOptions)
|
||||
*cp.Output.ISOOptions = *o.Output.ISOOptions
|
||||
}
|
||||
return cp
|
||||
}
|
||||
|
@ -37,6 +37,9 @@ var Default = map[string]Profile{
|
||||
Output: Output{
|
||||
Kind: OutKindISO,
|
||||
OutFormat: OutFormatRaw,
|
||||
ISOOptions: &ISOOptions{
|
||||
SDBootEnrollKeys: SDBootEnrollKeysIfSafe,
|
||||
},
|
||||
},
|
||||
},
|
||||
// Metal images
|
||||
|
@ -15,6 +15,8 @@ type Output struct {
|
||||
Kind OutputKind `yaml:"kind"`
|
||||
// Options for the 'image' output.
|
||||
ImageOptions *ImageOptions `yaml:"imageOptions,omitempty"`
|
||||
// Options for the 'iso' output.
|
||||
ISOOptions *ISOOptions `yaml:"isoOptions,omitempty"`
|
||||
// OutFormat is the format for the output:
|
||||
// * raw - output raw file
|
||||
// * .tar.gz - output tar.gz archive
|
||||
@ -37,6 +39,14 @@ type ImageOptions struct {
|
||||
DiskFormatOptions string `yaml:"diskFormatOptions,omitempty"`
|
||||
}
|
||||
|
||||
// ISOOptions describes options for the 'iso' output.
|
||||
type ISOOptions struct {
|
||||
// SDBootEnrollKeys is a value in loader.conf secure-boot-enroll: off, manual, if-safe, force.
|
||||
//
|
||||
// If not set, it defaults to if-safe.
|
||||
SDBootEnrollKeys SDBootEnrollKeys `yaml:"sdBootEnrollKeys"`
|
||||
}
|
||||
|
||||
//go:generate enumer -type=OutputKind -linecomment -text
|
||||
|
||||
// OutputKind is output specification.
|
||||
@ -81,3 +91,16 @@ const (
|
||||
DiskFormatVPC // vhd
|
||||
DiskFormatOVA // ova
|
||||
)
|
||||
|
||||
//go:generate enumer -type SDBootEnrollKeys -linecomment -text
|
||||
|
||||
// SDBootEnrollKeys is a value in loader.conf secure-boot-enroll: off, manual, if-safe, force.
|
||||
type SDBootEnrollKeys int
|
||||
|
||||
// SDBootEnrollKeys values.
|
||||
const (
|
||||
SDBootEnrollKeysIfSafe SDBootEnrollKeys = iota // if-safe
|
||||
SDBootEnrollKeysManual // manual
|
||||
SDBootEnrollKeysForce // force
|
||||
SDBootEnrollKeysOff // off
|
||||
)
|
||||
|
63
pkg/imager/profile/sdbootenrollkeys_enumer.go
Normal file
63
pkg/imager/profile/sdbootenrollkeys_enumer.go
Normal file
@ -0,0 +1,63 @@
|
||||
// Code generated by "enumer -type SDBootEnrollKeys -linecomment -text"; DO NOT EDIT.
|
||||
|
||||
package profile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const _SDBootEnrollKeysName = "if-safemanualforceoff"
|
||||
|
||||
var _SDBootEnrollKeysIndex = [...]uint8{0, 7, 13, 18, 21}
|
||||
|
||||
func (i SDBootEnrollKeys) String() string {
|
||||
if i < 0 || i >= SDBootEnrollKeys(len(_SDBootEnrollKeysIndex)-1) {
|
||||
return fmt.Sprintf("SDBootEnrollKeys(%d)", i)
|
||||
}
|
||||
return _SDBootEnrollKeysName[_SDBootEnrollKeysIndex[i]:_SDBootEnrollKeysIndex[i+1]]
|
||||
}
|
||||
|
||||
var _SDBootEnrollKeysValues = []SDBootEnrollKeys{0, 1, 2, 3}
|
||||
|
||||
var _SDBootEnrollKeysNameToValueMap = map[string]SDBootEnrollKeys{
|
||||
_SDBootEnrollKeysName[0:7]: 0,
|
||||
_SDBootEnrollKeysName[7:13]: 1,
|
||||
_SDBootEnrollKeysName[13:18]: 2,
|
||||
_SDBootEnrollKeysName[18:21]: 3,
|
||||
}
|
||||
|
||||
// SDBootEnrollKeysString retrieves an enum value from the enum constants string name.
|
||||
// Throws an error if the param is not part of the enum.
|
||||
func SDBootEnrollKeysString(s string) (SDBootEnrollKeys, error) {
|
||||
if val, ok := _SDBootEnrollKeysNameToValueMap[s]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return 0, fmt.Errorf("%s does not belong to SDBootEnrollKeys values", s)
|
||||
}
|
||||
|
||||
// SDBootEnrollKeysValues returns all values of the enum
|
||||
func SDBootEnrollKeysValues() []SDBootEnrollKeys {
|
||||
return _SDBootEnrollKeysValues
|
||||
}
|
||||
|
||||
// IsASDBootEnrollKeys returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i SDBootEnrollKeys) IsASDBootEnrollKeys() bool {
|
||||
for _, v := range _SDBootEnrollKeysValues {
|
||||
if i == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface for SDBootEnrollKeys
|
||||
func (i SDBootEnrollKeys) MarshalText() ([]byte, error) {
|
||||
return []byte(i.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface for SDBootEnrollKeys
|
||||
func (i *SDBootEnrollKeys) UnmarshalText(text []byte) error {
|
||||
var err error
|
||||
*i, err = SDBootEnrollKeysString(string(text))
|
||||
return err
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user