Simplified installer: add support for encrypted raw images

Signed-off-by: Antonio Murdaca <runcom@linux.com>
This commit is contained in:
Antonio Murdaca 2022-02-11 14:19:46 +01:00 committed by Tom Gundersen
parent 437dd397cd
commit 3be67ad965
11 changed files with 175 additions and 31 deletions

View file

@ -12,6 +12,12 @@ type Argon2id struct {
Memory uint
Parallelism uint
}
type ClevisBind struct {
Pin string
Policy string
RemovePassphrase bool
}
type LUKSContainer struct {
Passphrase string
UUID string
@ -23,6 +29,8 @@ type LUKSContainer struct {
// password-based key derivation function
PBKDF Argon2id
Clevis *ClevisBind
Payload Entity
}
@ -48,8 +56,7 @@ func (lc *LUKSContainer) Clone() Entity {
if lc == nil {
return nil
}
return &LUKSContainer{
clc := &LUKSContainer{
Passphrase: lc.Passphrase,
UUID: lc.UUID,
Cipher: lc.Cipher,
@ -63,6 +70,14 @@ func (lc *LUKSContainer) Clone() Entity {
},
Payload: lc.Payload.Clone(),
}
if lc.Clevis != nil {
clc.Clevis = &ClevisBind{
Pin: lc.Clevis.Pin,
Policy: lc.Clevis.Policy,
RemovePassphrase: lc.Clevis.RemovePassphrase,
}
}
return clc
}
func (lc *LUKSContainer) GenUUID(rng *rand.Rand) {

View file

@ -72,7 +72,12 @@ func ec2BuildPackageSet(t *imageType) rpmmd.PackageSet {
func edgeBuildPackageSet(t *imageType) rpmmd.PackageSet {
return distroBuildPackageSet(t).Append(
rpmmd.PackageSet{
Include: []string{"rpm-ostree"},
Include: []string{
"clevis",
"clevis-luks",
"cryptsetup",
"rpm-ostree",
},
Exclude: nil,
})
}

View file

@ -230,13 +230,28 @@ var edgeBasePartitionTables = distro.BasePartitionTableMap{
Size: 2 * 1024 * 1024 * 1024, // 2 GiB
Type: disk.FilesystemDataGUID,
UUID: disk.RootPartitionUUID,
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
Payload: &disk.LUKSContainer{
Label: "crypt_root",
Cipher: "cipher_null",
Passphrase: "osbuild",
PBKDF: disk.Argon2id{
Memory: 32,
Iterations: 4,
Parallelism: 1,
},
Clevis: &disk.ClevisBind{
Pin: "null",
Policy: "{}",
RemovePassphrase: true,
},
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},
@ -276,13 +291,28 @@ var edgeBasePartitionTables = distro.BasePartitionTableMap{
Size: 2 * 1024 * 1024 * 1024, // 2 GiB
Type: disk.FilesystemDataGUID,
UUID: disk.RootPartitionUUID,
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
Payload: &disk.LUKSContainer{
Label: "crypt_root",
Cipher: "cipher_null",
Passphrase: "osbuild",
PBKDF: disk.Argon2id{
Memory: 32,
Iterations: 4,
Parallelism: 1,
},
Clevis: &disk.ClevisBind{
Pin: "null",
Policy: "{}",
RemovePassphrase: true,
},
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},

View file

@ -323,6 +323,7 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers
Kernel: osbuild.ISOKernel{
Dir: "/images/pxeboot",
Opts: []string{"rd.neednet=1",
"coreos.inst.crypt_root=1",
"coreos.inst.isoroot=" + isolabel,
"coreos.inst.install_dev=" + installDevice,
"coreos.inst.image_file=/run/media/iso/disk.img.xz",

View file

@ -79,6 +79,9 @@ func edgeBuildPackageSet(t *imageType) rpmmd.PackageSet {
return distroBuildPackageSet(t).Append(
rpmmd.PackageSet{
Include: []string{
"clevis",
"clevis-luks",
"cryptsetup",
"rpm-ostree",
},
})

View file

@ -207,13 +207,28 @@ var edgeBasePartitionTables = distro.BasePartitionTableMap{
{
Type: disk.FilesystemDataGUID,
UUID: disk.RootPartitionUUID,
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
Payload: &disk.LUKSContainer{
Label: "crypt_root",
Cipher: "cipher_null",
Passphrase: "osbuild",
PBKDF: disk.Argon2id{
Memory: 32,
Iterations: 4,
Parallelism: 1,
},
Clevis: &disk.ClevisBind{
Pin: "null",
Policy: "{}",
RemovePassphrase: true,
},
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},
@ -252,13 +267,28 @@ var edgeBasePartitionTables = distro.BasePartitionTableMap{
{
Type: disk.FilesystemDataGUID,
UUID: disk.RootPartitionUUID,
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
Payload: &disk.LUKSContainer{
Label: "crypt_root",
Cipher: "cipher_null",
Passphrase: "osbuild",
PBKDF: disk.Argon2id{
Memory: 32,
Iterations: 4,
Parallelism: 1,
},
Clevis: &disk.ClevisBind{
Pin: "null",
Policy: "{}",
RemovePassphrase: true,
},
Payload: &disk.Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},

View file

@ -323,6 +323,7 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers
Kernel: osbuild.ISOKernel{
Dir: "/images/pxeboot",
Opts: []string{"rd.neednet=1",
"coreos.inst.crypt_root=1",
"coreos.inst.isoroot=" + isolabel,
"coreos.inst.install_dev=" + installDevice,
"coreos.inst.image_file=/run/media/iso/disk.img.xz",

View file

@ -0,0 +1,17 @@
package osbuild2
type ClevisLuksBindStageOptions struct {
Passphrase string `json:"passphrase"`
Pin string `json:"pin"`
Policy string `json:"policy"`
}
func (ClevisLuksBindStageOptions) isStageOptions() {}
func NewClevisLuksBindStage(options *ClevisLuksBindStageOptions, devices Devices) *Stage {
return &Stage{
Type: "org.osbuild.clevis.luks-bind",
Options: options,
Devices: devices,
}
}

View file

@ -54,6 +54,14 @@ func GenDeviceCreationStages(pt *disk.PartitionTable, filename string) []*Stage
stages = append(stages, stage)
if ent.Clevis != nil {
stages = append(stages, NewClevisLuksBindStage(&ClevisLuksBindStageOptions{
Passphrase: ent.Passphrase,
Pin: ent.Clevis.Pin,
Policy: ent.Clevis.Policy,
}, stageDevices))
}
case *disk.LVMVolumeGroup:
// do not include us when getting the devices
stageDevices, lastName := getDevices(path[:len(path)-1], filename, true)
@ -93,6 +101,21 @@ func GenDeviceFinishStages(pt *disk.PartitionTable, filename string) []*Stage {
genStages := func(e disk.Entity, path []disk.Entity) error {
switch ent := e.(type) {
case *disk.LUKSContainer:
// do not include us when getting the devices
stageDevices, lastName := getDevices(path[:len(path)-1], filename, true)
lastDevice := stageDevices[lastName]
delete(stageDevices, lastName)
stageDevices["device"] = lastDevice
if ent.Clevis != nil {
if ent.Clevis.RemovePassphrase {
stages = append(stages, NewLUKS2RemoveKeyStage(&LUKS2RemoveKeyStageOptions{
Passphrase: ent.Passphrase,
}, stageDevices))
}
}
case *disk.LVMVolumeGroup:
// do not include us when getting the devices
stageDevices, lastName := getDevices(path[:len(path)-1], filename, true)

View file

@ -0,0 +1,15 @@
package osbuild2
type LUKS2RemoveKeyStageOptions struct {
Passphrase string `json:"passphrase"`
}
func (LUKS2RemoveKeyStageOptions) isStageOptions() {}
func NewLUKS2RemoveKeyStage(options *LUKS2RemoveKeyStageOptions, devices Devices) *Stage {
return &Stage{
Type: "org.osbuild.luks2.remove-key",
Options: options,
Devices: devices,
}
}

View file

@ -160,6 +160,10 @@ func (stage *Stage) UnmarshalJSON(data []byte) error {
options = new(YumReposStageOptions)
case "org.osbuild.luks2.format":
options = new(LUKS2CreateStageOptions)
case "org.osbuild.clevis.luks-bind":
options = new(ClevisLuksBindStageOptions)
case "org.osbuild.luks2.remove-key":
options = new(LUKS2RemoveKeyStageOptions)
default:
return fmt.Errorf("unexpected stage type: %s", rawStage.Type)
}