rhel84: add a first boot stage for user SSH key

User home directories don't survive the rpm-ostree stage.  They are
converted to systemd-tmpfiles via rpm-ostree post-process, but the
contents are left behind, so any keys we add to the authorized_keys file
will be gone.

This stage sets up a first-boot service that writes the user's public
key to the file in the home directory during the first system boot.
This commit is contained in:
Achilleas Koutsou 2021-03-16 18:11:44 +01:00 committed by Tom Gundersen
parent 1aa0dc28a9
commit b843c77c8c

View file

@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"math/rand"
"path/filepath"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/distro"
@ -272,6 +273,7 @@ func (t *imageTypeS2) ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rp
return nil, err
}
p.AddStage(osbuild.NewUsersStage(options))
p.AddStage(osbuild.NewFirstBootStage(t.usersFirstBootOptions(options)))
}
if services := c.GetServices(); services != nil || t.enabledServices != nil || t.disabledServices != nil || t.defaultTarget != "" {
@ -532,6 +534,27 @@ func (t *imageTypeS2) userStageOptions(users []blueprint.UserCustomization) (*os
return &options, nil
}
func (t *imageTypeS2) usersFirstBootOptions(usersStageOptions *osbuild.UsersStageOptions) *osbuild.FirstBootStageOptions {
cmds := make([]string, 0, 3*len(usersStageOptions.Users)+1)
// workaround for creating authorized_keys file for user
varhome := filepath.Join("/var", "home")
for name, user := range usersStageOptions.Users {
if user.Key != nil {
sshdir := filepath.Join(varhome, name, ".ssh")
cmds = append(cmds, fmt.Sprintf("mkdir -p %s", sshdir))
cmds = append(cmds, fmt.Sprintf("sh -c 'echo %q >> %q'", *user.Key, filepath.Join(sshdir, "authorized_keys")))
cmds = append(cmds, fmt.Sprintf("chown %s:%s -Rc %s", name, name, sshdir))
}
}
cmds = append(cmds, fmt.Sprintf("restorecon -rvF %s", varhome))
options := &osbuild.FirstBootStageOptions{
Commands: cmds,
WaitForNetwork: false,
}
return options
}
func (t *imageTypeS2) groupStageOptions(groups []blueprint.GroupCustomization) *osbuild.GroupsStageOptions {
options := osbuild.GroupsStageOptions{
Groups: map[string]osbuild.GroupsStageOptionsGroup{},