moby/integration-cli/fixtures_linux_daemon_test.go
Justin Cormack 7e3a596a63 Block obsolete socket families in the default seccomp profile
Linux supports many obsolete address families, which are usually available in
common distro kernels, but they are less likely to be properly audited and
may have security issues

This blocks all socket families in the socket (and socketcall where applicable) syscall
except
- AF_UNIX - Unix domain sockets
- AF_INET - IPv4
- AF_INET6 - IPv6
- AF_NETLINK - Netlink sockets for communicating with the ekrnel
- AF_PACKET - raw sockets, which are only allowed with CAP_NET_RAW

All other socket families are blocked, including Appletalk (native, not
over IP), IPX (remember that!), VSOCK and HVSOCK, which should not generally
be used in containers, etc.

Note that users can of course provide a profile per container or in the daemon
config if they have unusual use cases that require these.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
2017-01-17 17:50:44 +00:00

151 lines
4.5 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/fixtures/load"
"github.com/go-check/check"
)
type testingT interface {
logT
Fatalf(string, ...interface{})
}
type logT interface {
Logf(string, ...interface{})
}
func ensureFrozenImagesLinux(t testingT) {
images := []string{"busybox:latest", "hello-world:frozen", "debian:jessie"}
err := load.FrozenImagesLinux(dockerBinary, images...)
if err != nil {
t.Logf(dockerCmdWithError("images"))
t.Fatalf("%+v", err)
}
for _, img := range images {
protectedImages[img] = struct{}{}
}
}
var ensureSyscallTestOnce sync.Once
func ensureSyscallTest(c *check.C) {
var doIt bool
ensureSyscallTestOnce.Do(func() {
doIt = true
})
if !doIt {
return
}
protectedImages["syscall-test:latest"] = struct{}{}
// if no match, must build in docker, which is significantly slower
// (slower mostly because of the vfs graphdriver)
if testEnv.DaemonPlatform() != runtime.GOOS {
ensureSyscallTestBuild(c)
return
}
tmp, err := ioutil.TempDir("", "syscall-test-build")
c.Assert(err, checker.IsNil, check.Commentf("couldn't create temp dir"))
defer os.RemoveAll(tmp)
gcc, err := exec.LookPath("gcc")
c.Assert(err, checker.IsNil, check.Commentf("could not find gcc"))
tests := []string{"userns", "ns", "acct", "setuid", "setgid", "socket", "raw", "appletalk"}
for _, test := range tests {
out, err := exec.Command(gcc, "-g", "-Wall", "-static", fmt.Sprintf("../contrib/syscall-test/%s.c", test), "-o", fmt.Sprintf("%s/%s-test", tmp, test)).CombinedOutput()
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
}
if runtime.GOOS == "linux" && runtime.GOARCH == "amd64" {
out, err := exec.Command(gcc, "-s", "-m32", "-nostdlib", "../contrib/syscall-test/exit32.s", "-o", tmp+"/"+"exit32-test").CombinedOutput()
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
}
dockerFile := filepath.Join(tmp, "Dockerfile")
content := []byte(`
FROM debian:jessie
COPY . /usr/bin/
`)
err = ioutil.WriteFile(dockerFile, content, 600)
c.Assert(err, checker.IsNil)
var buildArgs []string
if arg := os.Getenv("DOCKER_BUILD_ARGS"); strings.TrimSpace(arg) != "" {
buildArgs = strings.Split(arg, " ")
}
buildArgs = append(buildArgs, []string{"-q", "-t", "syscall-test", tmp}...)
buildArgs = append([]string{"build"}, buildArgs...)
dockerCmd(c, buildArgs...)
}
func ensureSyscallTestBuild(c *check.C) {
err := load.FrozenImagesLinux(dockerBinary, "buildpack-deps:jessie")
c.Assert(err, checker.IsNil)
var buildArgs []string
if arg := os.Getenv("DOCKER_BUILD_ARGS"); strings.TrimSpace(arg) != "" {
buildArgs = strings.Split(arg, " ")
}
buildArgs = append(buildArgs, []string{"-q", "-t", "syscall-test", "../contrib/syscall-test"}...)
buildArgs = append([]string{"build"}, buildArgs...)
dockerCmd(c, buildArgs...)
}
func ensureNNPTest(c *check.C) {
protectedImages["nnp-test:latest"] = struct{}{}
if testEnv.DaemonPlatform() != runtime.GOOS {
ensureNNPTestBuild(c)
return
}
tmp, err := ioutil.TempDir("", "docker-nnp-test")
c.Assert(err, checker.IsNil)
gcc, err := exec.LookPath("gcc")
c.Assert(err, checker.IsNil, check.Commentf("could not find gcc"))
out, err := exec.Command(gcc, "-g", "-Wall", "-static", "../contrib/nnp-test/nnp-test.c", "-o", filepath.Join(tmp, "nnp-test")).CombinedOutput()
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
dockerfile := filepath.Join(tmp, "Dockerfile")
content := `
FROM debian:jessie
COPY . /usr/bin
RUN chmod +s /usr/bin/nnp-test
`
err = ioutil.WriteFile(dockerfile, []byte(content), 600)
c.Assert(err, checker.IsNil, check.Commentf("could not write Dockerfile for nnp-test image"))
var buildArgs []string
if arg := os.Getenv("DOCKER_BUILD_ARGS"); strings.TrimSpace(arg) != "" {
buildArgs = strings.Split(arg, " ")
}
buildArgs = append(buildArgs, []string{"-q", "-t", "nnp-test", tmp}...)
buildArgs = append([]string{"build"}, buildArgs...)
dockerCmd(c, buildArgs...)
}
func ensureNNPTestBuild(c *check.C) {
err := load.FrozenImagesLinux(dockerBinary, "buildpack-deps:jessie")
c.Assert(err, checker.IsNil)
var buildArgs []string
if arg := os.Getenv("DOCKER_BUILD_ARGS"); strings.TrimSpace(arg) != "" {
buildArgs = strings.Split(arg, " ")
}
buildArgs = append(buildArgs, []string{"-q", "-t", "npp-test", "../contrib/nnp-test"}...)
buildArgs = append([]string{"build"}, buildArgs...)
dockerCmd(c, buildArgs...)
}