Allow passing flags to luksify

flags for luks version and use tpm

Signed-off-by: Itxaka <itxaka@kairos.io>
This commit is contained in:
Itxaka 2023-11-30 11:01:39 +01:00
parent 365f16e8f1
commit e43da08f2d
4 changed files with 62 additions and 27 deletions

1
go.mod
View File

@ -14,6 +14,7 @@ require (
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.12 github.com/urfave/cli v1.22.12
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
k8s.io/apimachinery v0.26.2
) )
require ( require (

2
go.sum
View File

@ -442,3 +442,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=

38
main.go
View File

@ -24,11 +24,24 @@ func main() {
Name: "encrypt", Name: "encrypt",
Description: "Encrypts a partition", Description: "Encrypts a partition",
Usage: "Encrypts a partition",
ArgsUsage: "kcrypt [--version VERSION] [--tpm] LABEL",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "version",
Value: "luks1",
Usage: "luks version to use",
},
&cli.BoolFlag{
Name: "tpm",
Usage: "Use TPM to lock the partition",
},
},
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if c.NArg() != 1 { if c.NArg() != 1 {
return fmt.Errorf("requires 1 arg, the partition label") return fmt.Errorf("requires 1 arg, the partition label")
} }
out, err := lib.Luksify(c.Args().First()) out, err := lib.Luksify(c.Args().First(), c.String("version"), c.Bool("tpm"))
if err != nil { if err != nil {
return err return err
} }
@ -38,24 +51,19 @@ func main() {
}, },
{ {
Name: "unlock-all", Name: "unlock-all",
UsageText: "unlock-all", UsageText: "unlock-all",
Usage: "Try to unlock all LUKS partitions", Usage: "Try to unlock all LUKS partitions",
Description: ` Description: "Typically run during initrd to unlock all the LUKS partitions found",
Typically run during initrd to unlock all the LUKS partitions found ArgsUsage: "kcrypt unlock-all",
`,
ArgsUsage: "kcrypt unlock-all",
Flags: []cli.Flag{
&cli.StringFlag{},
},
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
return lib.UnlockAll() return lib.UnlockAll()
}, },
}, },
{ {
Name: "extract-initrd", Name: "extract-initrd",
Hidden: true,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if c.NArg() != 2 { if c.NArg() != 2 {
return fmt.Errorf("requires 3 args. initrd,, dst") return fmt.Errorf("requires 3 args. initrd,, dst")
@ -64,8 +72,8 @@ Typically run during initrd to unlock all the LUKS partitions found
}, },
}, },
{ {
Name: "inject-initrd",
Name: "inject-initrd", Hidden: true,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if c.NArg() != 3 { if c.NArg() != 3 {
return fmt.Errorf("requires 3 args. initrd, srcfile, dst") return fmt.Errorf("requires 3 args. initrd, srcfile, dst")

View File

@ -2,10 +2,12 @@ package lib
import ( import (
"fmt" "fmt"
"github.com/anatol/luks.go"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
"github.com/jaypipes/ghw" "github.com/jaypipes/ghw"
"github.com/jaypipes/ghw/pkg/block" "github.com/jaypipes/ghw/pkg/block"
configpkg "github.com/kairos-io/kcrypt/pkg/config" configpkg "github.com/kairos-io/kcrypt/pkg/config"
"k8s.io/apimachinery/pkg/util/rand"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
@ -29,33 +31,55 @@ func CreateLuks(dev, password, version string, cryptsetupArgs ...string) error {
return nil return nil
} }
// Take a part label, and recreates it with LUKS. IT OVERWRITES DATA! // Luksify Take a part label, and recreates it with LUKS. IT OVERWRITES DATA!
// On success, it returns a machine parseable string with the partition information // On success, it returns a machine parseable string with the partition information
// (label:name:uuid) so that it can be stored by the caller for later use. // (label:name:uuid) so that it can be stored by the caller for later use.
// This is because the label of the encrypted partition is not accessible unless // This is because the label of the encrypted partition is not accessible unless
// the partition is decrypted first and the uuid changed after encryption so // the partition is decrypted first and the uuid changed after encryption so
// any stored information needs to be updated (by the caller). // any stored information needs to be updated (by the caller).
func Luksify(label string) (string, error) { func Luksify(label, version string, tpm bool) (string, error) {
// blkid var pass string
persistent, b, err := FindPartition(label) if version == "" {
version = "luks1"
}
if version != "luks1" && version != "luks2" {
return "", fmt.Errorf("version must be luks1 or luks2")
}
part, b, err := FindPartition(label)
if err != nil { if err != nil {
return "", err return "", err
} }
pass, err := GetPassword(b) if tpm {
if err != nil { // On TPM locking we generate a random password that will only be used here then discarded.
return "", err // only unlocking method will be PCR values
pass = rand.String(32)
} else {
pass, err = GetPassword(b)
if err != nil {
return "", err
}
} }
persistent = fmt.Sprintf("/dev/%s", persistent) part = fmt.Sprintf("/dev/%s", part)
devMapper := fmt.Sprintf("/dev/mapper/%s", b.Name) devMapper := fmt.Sprintf("/dev/mapper/%s", b.Name)
partUUID := uuid.NewV5(uuid.NamespaceURL, label) partUUID := uuid.NewV5(uuid.NamespaceURL, label)
if err := CreateLuks(persistent, pass, "luks1", []string{"--uuid", partUUID.String()}...); err != nil { extraArgs := []string{"--uuid", partUUID.String()}
if err := CreateLuks(part, pass, version, extraArgs...); err != nil {
return "", err return "", err
} }
if tpm {
// Enroll PCR values as an unlock method
out, err := SH(fmt.Sprintf("systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+8+9 %s", part))
if err != nil {
return "", fmt.Errorf("err: %w, out: %s", err, out)
}
}
if err := LuksUnlock(persistent, b.Name, pass); err != nil { if err := LuksUnlock(part, b.Name, pass); err != nil {
return "", err return "", err
} }
@ -69,9 +93,9 @@ func Luksify(label string) (string, error) {
return "", fmt.Errorf("err: %w, out: %s", err, out) return "", fmt.Errorf("err: %w, out: %s", err, out)
} }
out2, err := SH(fmt.Sprintf("cryptsetup close %s", b.Name)) err = luks.Lock(b.Name)
if err != nil { if err != nil {
return "", fmt.Errorf("err: %w, out: %s", err, out2) return "", fmt.Errorf("err: %w", err)
} }
return configpkg.PartitionToString(b), nil return configpkg.PartitionToString(b), nil