summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorumohnani8 <umohnani@redhat.com>2018-04-19 10:25:01 -0400
committerumohnani8 <umohnani@redhat.com>2018-04-23 13:17:12 -0400
commit57afb7514d5c123779601cae77d016bf6de8a5f1 (patch)
treeb1500483b4172c0b05baaf5690c76c3d5486d5ad
parent8493dba23c73617d9529b7ca13b400d50ac6f455 (diff)
downloadpodman-57afb7514d5c123779601cae77d016bf6de8a5f1.tar.gz
podman-57afb7514d5c123779601cae77d016bf6de8a5f1.tar.bz2
podman-57afb7514d5c123779601cae77d016bf6de8a5f1.zip
Add FIPS mode secret
If the host is in FIPS mode and /etc/system-fips exists /run/secrets/system-fips is created in the container so that the container can run in FIPS mode as well. Signed-off-by: umohnani8 <umohnani@redhat.com>
-rw-r--r--libpod/container_internal.go14
-rw-r--r--pkg/secrets/secrets.go81
-rw-r--r--test/e2e/run_test.go14
3 files changed, 91 insertions, 18 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 32f8d2aec..62960fa0f 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -754,8 +754,7 @@ func (c *Container) makeBindMounts() error {
}
// Add Secret Mounts
- secretMounts := c.getSecretMounts(secrets.OverrideMountsFile)
- secretMounts = append(secretMounts, c.getSecretMounts(secrets.DefaultMountsFile)...)
+ secretMounts := secrets.SecretMounts(c.config.MountLabel, c.state.RunDir)
for _, mount := range secretMounts {
if _, ok := c.state.BindMounts[mount.Destination]; !ok {
c.state.BindMounts[mount.Destination] = mount.Source
@@ -765,15 +764,6 @@ func (c *Container) makeBindMounts() error {
return nil
}
-// addSecrets mounts the secrets from the override and/or default mounts file
-func (c *Container) getSecretMounts(mountFile string) (secretMounts []spec.Mount) {
- secretMounts, err := secrets.SecretMounts(mountFile, c.config.MountLabel, c.state.RunDir)
- if err != nil {
- logrus.Warn("error mounting secrets, skipping...")
- }
- return secretMounts
-}
-
// writeStringToRundir copies the provided file to the runtimedir
func (c *Container) writeStringToRundir(destFile, output string) (string, error) {
destFileName := filepath.Join(c.state.RunDir, destFile)
@@ -932,6 +922,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
if !MountExists(g.Mounts(), dstPath) {
g.AddMount(newMount)
+ } else {
+ logrus.Warnf("User mount overriding libpod mount at %q", dstPath)
}
}
diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go
index be825d906..9b328575b 100644
--- a/pkg/secrets/secrets.go
+++ b/pkg/secrets/secrets.go
@@ -2,7 +2,6 @@ package secrets
import (
"bufio"
- "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -127,9 +126,35 @@ func getMountsMap(path string) (string, string, error) {
return "", "", errors.Errorf("unable to get host and container dir")
}
-// SecretMounts copies the contents of host directory to container directory
+// SecretMounts copies, adds, and mounts the secrets to the container root filesystem
+func SecretMounts(mountLabel, containerWorkingDir string) []rspec.Mount {
+ var secretMounts []rspec.Mount
+ // Add secrets from paths given in the mounts.conf files
+ for _, file := range []string{OverrideMountsFile, DefaultMountsFile} {
+ mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir)
+ if err != nil {
+ logrus.Warnf("error mounting secrets, skipping: %v", err)
+ }
+ secretMounts = append(secretMounts, mounts...)
+ }
+
+ // Add FIPS mode secret if /etc/system-fips exists on the host
+ _, err := os.Stat("/etc/system-fips")
+ if err == nil {
+ if err := addFIPSsModeSecret(&secretMounts, containerWorkingDir); err != nil {
+ logrus.Warnf("error adding FIPS mode secret to container: %v", err)
+ }
+ } else if os.IsNotExist(err) {
+ logrus.Debug("/etc/system-fips does not exist on host, not mounting FIPS mode secret")
+ } else {
+ logrus.Errorf("error stating /etc/system-fips for FIPS mode secret: %v", err)
+ }
+ return secretMounts
+}
+
+// addSecretsFromMountsFile copies the contents of host directory to container directory
// and returns a list of mounts
-func SecretMounts(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mount, error) {
+func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mount, error) {
var mounts []rspec.Mount
defaultMountsPaths := getMounts(filePath)
for _, path := range defaultMountsPaths {
@@ -144,15 +169,12 @@ func SecretMounts(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mou
}
ctrDirOnHost := filepath.Join(containerWorkingDir, ctrDir)
- if err = os.RemoveAll(ctrDirOnHost); err != nil {
- return nil, fmt.Errorf("remove container directory failed: %v", err)
- }
// In the event of a restart, don't want to copy secrets over again as they already would exist in ctrDirOnHost
_, err = os.Stat(ctrDirOnHost)
if os.IsNotExist(err) {
if err = os.MkdirAll(ctrDirOnHost, 0755); err != nil {
- return nil, fmt.Errorf("making container directory failed: %v", err)
+ return nil, errors.Wrapf(err, "making container directory failed")
}
hostDir, err = resolveSymbolicLink(hostDir)
@@ -190,6 +212,51 @@ func SecretMounts(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mou
return mounts, nil
}
+// addFIPSModeSecret creates /run/secrets/system-fips in the container
+// 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 addFIPSsModeSecret(mounts *[]rspec.Mount, containerWorkingDir string) error {
+ secretsDir := "/run/secrets"
+ ctrDirOnHost := filepath.Join(containerWorkingDir, secretsDir)
+ if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) {
+ if err = os.MkdirAll(ctrDirOnHost, 0755); err != nil {
+ return errors.Wrapf(err, "making container directory on host failed")
+ }
+ }
+ fipsFile := filepath.Join(ctrDirOnHost, "system-fips")
+ // In the event of restart, it is possible for the FIPS mode file to already exist
+ if _, err := os.Stat(fipsFile); os.IsNotExist(err) {
+ file, err := os.Create(fipsFile)
+ if err != nil {
+ return errors.Wrapf(err, "error creating system-fips file in container for FIPS mode")
+ }
+ defer file.Close()
+ }
+
+ if !mountExists(*mounts, secretsDir) {
+ m := rspec.Mount{
+ Source: ctrDirOnHost,
+ Destination: secretsDir,
+ Type: "bind",
+ Options: []string{"bind"},
+ }
+ *mounts = append(*mounts, m)
+ }
+
+ return nil
+}
+
+// mountExists checks if a mount already exists in the spec
+func mountExists(mounts []rspec.Mount, dest string) bool {
+ for _, mount := range mounts {
+ if mount.Destination == dest {
+ return true
+ }
+ }
+ return false
+}
+
// resolveSymbolicLink resolves a possbile symlink path. If the path is a symlink, returns resolved
// path; if not, returns the original path.
func resolveSymbolicLink(path string) (string, error) {
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 66e5791a7..501434852 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -302,6 +302,20 @@ var _ = Describe("Podman run", func() {
Expect(err).To(BeNil())
})
+ It("podman run with FIPS mode secrets", func() {
+ fipsFile := "/etc/system-fips"
+ err = ioutil.WriteFile(fipsFile, []byte{}, 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("system-fips"))
+
+ err = os.Remove(fipsFile)
+ Expect(err).To(BeNil())
+ })
+
It("podman run without group-add", func() {
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
session.WaitWithDefaultTimeout()