From c6e3f1747af765c87a3503fd8afbac3de5b16fb0 Mon Sep 17 00:00:00 2001 From: Stephen Lowrie Date: Thu, 28 May 2020 20:25:32 -0500 Subject: [PATCH] TMP: rebase down --- config/shared/errors/errors.go | 1 + .../v3_1_experimental/translate/translate.go | 4 +- config/v3_1_experimental/types/luks.go | 6 ++- internal/exec/stages/disks/luks.go | 18 ++++--- internal/exec/stages/files/files.go | 4 ++ .../exec/stages/files/filesystemEntries.go | 49 +++++++++++++++++++ internal/exec/util/luks.go | 17 +++++++ 7 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 internal/exec/util/luks.go diff --git a/config/shared/errors/errors.go b/config/shared/errors/errors.go index 71a6b43313..e256a8d054 100644 --- a/config/shared/errors/errors.go +++ b/config/shared/errors/errors.go @@ -55,6 +55,7 @@ var ( ErrSwapLabelTooLong = errors.New("filesystem labels cannot be longer than 15 characters when using swap") ErrVfatLabelTooLong = errors.New("filesystem labels cannot be longer than 11 characters when using vfat") ErrLuksLabelTooLong = errors.New("device labels cannot be longer than 16 characters when using luks") + ErrInvalidLuksVolume = errors.New("a key-file or clevis configuration must be specified") ErrFileIllegalMode = errors.New("illegal file mode") ErrBothIDAndNameSet = errors.New("cannot set both id and name") ErrLabelTooLong = errors.New("partition labels may not exceed 36 characters") diff --git a/config/v3_1_experimental/translate/translate.go b/config/v3_1_experimental/translate/translate.go index 4d9ac47434..be7b8bf425 100644 --- a/config/v3_1_experimental/translate/translate.go +++ b/config/v3_1_experimental/translate/translate.go @@ -97,10 +97,12 @@ func translateIgnition(old old_types.Ignition) (ret types.Ignition) { func translateStorage(old old_types.Storage) (ret types.Storage) { tr := translate.NewTranslator() + tr.AddCustomTranslator(translateFileContents) + tr.AddCustomTranslator(translateFilesystem) tr.Translate(&old.Directories, &ret.Directories) tr.Translate(&old.Disks, &ret.Disks) tr.Translate(&old.Files, &ret.Files) - tr.AddCustomTranslator(translateFilesystem) + tr.Translate(&old.Filesystems, &ret.Filesystems) tr.Translate(&old.Links, &ret.Links) tr.Translate(&old.Raid, &ret.Raid) return diff --git a/config/v3_1_experimental/types/luks.go b/config/v3_1_experimental/types/luks.go index 7980291c36..20ea5613b6 100644 --- a/config/v3_1_experimental/types/luks.go +++ b/config/v3_1_experimental/types/luks.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// Copyright 2020 Red Hat, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,6 +35,10 @@ func (l Luks) IgnoreDuplicates() map[string]struct{} { func (l Luks) Validate(c path.ContextPath) (r report.Report) { r.AddOnError(c.Append("label"), l.validateLabel()) r.AddOnError(c.Append("device"), validatePath(l.Device)) + + if util.NilOrEmpty(l.KeyFile) && l.Clevis == nil { + r.AddOnError(c.Append("keys"), errors.ErrInvalidLuksVolume) + } return } diff --git a/internal/exec/stages/disks/luks.go b/internal/exec/stages/disks/luks.go index 0fcc923127..3c58af6d8b 100644 --- a/internal/exec/stages/disks/luks.go +++ b/internal/exec/stages/disks/luks.go @@ -25,13 +25,15 @@ import ( "io/ioutil" "os" "os/exec" + "path/filepath" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_1_experimental/types" "github.com/coreos/ignition/v2/internal/distro" + execUtil "github.com/coreos/ignition/v2/internal/exec/util" ) -var defaultKeyFilePath = "/rootfs/luks%s" +var defaultKeyFilePath = "/sysroot/etc/luks/%s" type Tang struct { URL string `json:"url"` @@ -39,29 +41,29 @@ type Tang struct { } type Pin struct { - Tpm bool - Tang []Tang + Tpm bool `json:"tpm"` + Tang []Tang `json:"tang,omitempty"` } -func (p *Pin) MarshalJSON() ([]byte, error) { +func (p Pin) MarshalJSON() ([]byte, error) { if p.Tpm { return json.Marshal(&struct { Tang []Tang `json:"tang,omitempty"` - Tpm struct{} `json:"tpm"` + Tpm struct{} `json:"tpm2"` }{ Tang: p.Tang, Tpm: struct{}{}, }) } return json.Marshal(&struct { - Tang []Tang + Tang []Tang `json:"tang"` }{ Tang: p.Tang, }) } type Clevis struct { - Pins Pin + Pins Pin `json:"pins"` Threshold int `json:"t"` } @@ -74,7 +76,7 @@ func (s *stage) createLuks(config types.Config) error { // track whether Ignition creates the KeyFile // so that it can be removed creation var ignitionCreatedKeyFile bool - keyFilePath := fmt.Sprintf(defaultKeyFilePath, luks.Name) + keyFilePath := filepath.Join("/sysroot", execUtil.LuksKeyFilePath, luks.Name) if luks.KeyFile == nil || *luks.KeyFile == "" { // create a keyfile if _, err := s.Logger.LogCmd( diff --git a/internal/exec/stages/files/files.go b/internal/exec/stages/files/files.go index fee0a22b32..5acea6f12a 100644 --- a/internal/exec/stages/files/files.go +++ b/internal/exec/stages/files/files.go @@ -85,6 +85,10 @@ func (s stage) Run(config types.Config) error { return fmt.Errorf("failed to create units: %v", err) } + if err := s.createCrypttabEntries(config); err != nil { + return fmt.Errorf("creating crypttab entries: %v", err) + } + if err := s.relabelFiles(); err != nil { return fmt.Errorf("failed to handle relabeling: %v", err) } diff --git a/internal/exec/stages/files/filesystemEntries.go b/internal/exec/stages/files/filesystemEntries.go index 2275ffe9f2..2066e80c2c 100644 --- a/internal/exec/stages/files/filesystemEntries.go +++ b/internal/exec/stages/files/filesystemEntries.go @@ -17,15 +17,64 @@ package files import ( "fmt" "os" + "os/exec" "path/filepath" + "regexp" "sort" "strings" "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/distro" "github.com/coreos/ignition/v2/internal/exec/util" "github.com/coreos/ignition/v2/internal/log" + + "github.com/vincent-petithory/dataurl" ) +// createCrypttabEntries creates entries inside of /etc/crypttab for LUKS volumes. +func (s *stage) createCrypttabEntries(config types.Config) error { + if len(config.Storage.Luks) == 0 { + return nil + } + + s.Logger.PushPrefix("createCrypttabEntries") + defer s.Logger.PopPrefix() + + crypttab := fileEntry{ + types.Node{ + Path: "/etc/crypttab", + }, + types.FileEmbedded1{}, + } + for _, luks := range config.Storage.Luks { + dump, err := exec.Command(distro.CryptsetupCmd(), "luksDump", luks.Device).CombinedOutput() + if err != nil { + return fmt.Errorf("gathering luks header: %v", err) + } + pattern := regexp.MustCompile(`UUID:\s+(?P[a-f0-9\-]+)`) + match := pattern.FindSubmatch(dump) + if len(match) < 2 { + return fmt.Errorf("couldn't gather luks device %v uuid", luks.Name) + } + uuid := string(match[1]) + var appendLine string + if luks.Clevis != nil { + appendLine = fmt.Sprintf("%s UUID=%s none luks", luks.Name, uuid) + } else { + appendLine = fmt.Sprintf("%s UUID=%s %s luks", luks.Name, uuid, filepath.Join(util.LuksKeyFilePath, luks.Name)) + } + uri := dataurl.EncodeBytes([]byte(appendLine)) + crypttab.Append = append(crypttab.Append, types.FileContents{ + Source: &uri, + }) + } + err := crypttab.create(s.Logger, s.Util) + if err != nil { + return fmt.Errorf("adding luks devices to crypttab: %v", err) + } + return nil +} + // createFilesystemsEntries creates the files described in config.Storage.{Files,Directories}. func (s *stage) createFilesystemsEntries(config types.Config) error { s.Logger.PushPrefix("createFilesystemsFiles") diff --git a/internal/exec/util/luks.go b/internal/exec/util/luks.go new file mode 100644 index 0000000000..a78e3e88bb --- /dev/null +++ b/internal/exec/util/luks.go @@ -0,0 +1,17 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +var LuksKeyFilePath = "/etc/luks/"