Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for FIPS-Mode backends #2031

Merged
merged 1 commit into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 38 additions & 10 deletions pkg/secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,21 @@ func getMountsMap(path string) (string, string, error) {
}

// SecretMounts copies, adds, and mounts the secrets to the container root filesystem
// Deprecated, Please use SecretMountWithUIDGID
func SecretMounts(mountLabel, containerWorkingDir, mountFile string, rootless, disableFips bool) []rspec.Mount {
return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, containerWorkingDir, 0, 0, rootless, disableFips)
}

// SecretMountsWithUIDGID specifies the uid/gid of the owner
func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPrefix string, uid, gid int, rootless, disableFips bool) []rspec.Mount {
// SecretMountsWithUIDGID copies, adds, and mounts the secrets to the container root filesystem
// mountLabel: MAC/SELinux label for container content
// containerWorkingDir: Private data for storing secrets on the host mounted in container.
// mountFile: Additional mount points required for the container.
// mountPoint: Container image mountpoint
// uid: to assign to content created for secrets
// gid: to assign to content created for secrets
// rootless: indicates whether container is running in rootless mode
// disableFips: indicates whether system should ignore fips mode
func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPoint string, uid, gid int, rootless, disableFips bool) []rspec.Mount {
var (
secretMounts []rspec.Mount
mountFiles []string
Expand All @@ -171,7 +180,7 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre
}
for _, file := range mountFiles {
if _, err := os.Stat(file); err == nil {
mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, mountPrefix, uid, gid)
mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, uid, gid)
if err != nil {
logrus.Warnf("error mounting secrets, skipping entry in %s: %v", file, err)
}
Expand All @@ -187,7 +196,7 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre
// Add FIPS mode secret if /etc/system-fips exists on the host
_, err := os.Stat("/etc/system-fips")
if err == nil {
if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPrefix, mountLabel, uid, gid); err != nil {
if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPoint, mountLabel, uid, gid); err != nil {
logrus.Errorf("error adding FIPS mode secret to container: %v", err)
}
} else if os.IsNotExist(err) {
Expand All @@ -206,7 +215,7 @@ func rchown(chowndir string, uid, gid int) error {

// addSecretsFromMountsFile copies the contents of host directory to container directory
// and returns a list of mounts
func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPrefix string, uid, gid int) ([]rspec.Mount, error) {
func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string, uid, gid int) ([]rspec.Mount, error) {
var mounts []rspec.Mount
defaultMountsPaths := getMounts(filePath)
for _, path := range defaultMountsPaths {
Expand Down Expand Up @@ -285,7 +294,7 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPr
}

m := rspec.Mount{
Source: filepath.Join(mountPrefix, ctrDirOrFile),
Source: ctrDirOrFileOnHost,
Destination: ctrDirOrFile,
Type: "bind",
Options: []string{"bind", "rprivate"},
Expand All @@ -300,15 +309,15 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPr
// root filesystem if /etc/system-fips exists on hosts.
// This enables the container to be FIPS compliant and run openssl in
// FIPS mode as the host is also in FIPS mode.
func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPrefix, mountLabel string, uid, gid int) error {
func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPoint, mountLabel string, uid, gid int) error {
secretsDir := "/run/secrets"
ctrDirOnHost := filepath.Join(containerWorkingDir, secretsDir)
if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) {
if err = idtools.MkdirAllAs(ctrDirOnHost, 0755, uid, gid); err != nil {
return errors.Wrapf(err, "making container directory on host failed")
return errors.Wrapf(err, "making container directory %q on host failed", ctrDirOnHost)
}
if err = label.Relabel(ctrDirOnHost, mountLabel, false); err != nil {
return errors.Wrap(err, "error applying correct labels")
return errors.Wrapf(err, "error applying correct labels on %q", ctrDirOnHost)
}
}
fipsFile := filepath.Join(ctrDirOnHost, "system-fips")
Expand All @@ -323,14 +332,33 @@ func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPrefix,

if !mountExists(*mounts, secretsDir) {
m := rspec.Mount{
Source: filepath.Join(mountPrefix, secretsDir),
Source: ctrDirOnHost,
Destination: secretsDir,
Type: "bind",
Options: []string{"bind", "rprivate"},
}
*mounts = append(*mounts, m)
}

srcBackendDir := "/usr/share/crypto-policies/back-ends/FIPS"
destDir := "/etc/crypto-policies/back-ends"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhatdan would it make sense to add the above two variables into containers.conf at some point?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'm not a big fan of having a directory defined like this in a middle of a function somewhere, but personal twitch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if containers.conf is the right place. The place to extend would be mounts.conf I guess. but we would need some changes to how this is parsed.

Currently
SRC:DEST

But SRC is on the host and DEST is in the container

This patch basically does SRC in the container to DEST in the container.

Mounts.conf also copies SRC into container local storage and then mounts Container Local Storage at DEST.

The HPC guys want additional volumes "bind" mounted into automatically into the containers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added

# List of additional volumes. Specified as
# "<directory-on-host>:<derectory-in-container>:<options>", for example: 
# "/db:/var/lib/db:ro".
# If it is empty or commented out, no volumes will be added
# additional_volumes = []

To containers.conf, but this does not solve the issue we have here either.

srcOnHost := filepath.Join(mountPoint, srcBackendDir)
if _, err := os.Stat(srcOnHost); err != nil {
if os.IsNotExist(err) {
return nil
}
return errors.Wrapf(err, "failed to stat FIPS Backend directory %q", ctrDirOnHost)
}

if !mountExists(*mounts, destDir) {
m := rspec.Mount{
Source: srcOnHost,
Destination: destDir,
Type: "bind",
Options: []string{"bind", "rprivate"},
}
*mounts = append(*mounts, m)
}
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion run_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
}

// Get the list of secrets mounts.
secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, cdir, int(rootUID), int(rootGID), unshare.IsRootless(), false)
secretMounts := secrets.SecretMountsWithUIDGID(b.MountLabel, cdir, b.DefaultMountsFilePath, mountPoint, int(rootUID), int(rootGID), unshare.IsRootless(), false)

// Add temporary copies of the contents of volume locations at the
// volume locations, unless we already have something there.
Expand Down