moby: Docker engine does not support the parameter "--security-opt seccomp=" when executing command "docker build"

Description

Steps to reproduce the issue: You can execute the command “docker build”, and append the parameter “–security-opt seccomp=[SECCOMP PROFILE]” in the Linux or macOS system.

Describe the results you received: Thus it emits the following error message: Error response from daemon: the daemon on this platform does not support --security-opt to build

Describe the results you expected: The command “docker build” can support the parameter “–security-opt seccomp=<SECCOMP PROFILE>” when building docker image from Dockerfile in the macOS or Linux system.

Additional information you deem important (e.g. issue happens only occasionally): Otherwise, I saw the docker engine source code (v17.06), and it has been set the SecurityOpt in HostConfig when executing RUN instruction. However, why should check the runtime OS type, and it must be windows platform in the newImageBuildOptions method?

The code is:

if runtime.GOOS != "windows" && options.SecurityOpt != nil {
	return nil, fmt.Errorf("the daemon on this platform does not support --security-opt to build")
}
func (b *Builder) create(runConfig *container.Config) (string, error) {
	resources := container.Resources{
		CgroupParent: b.options.CgroupParent,
		CPUShares:    b.options.CPUShares,
		CPUPeriod:    b.options.CPUPeriod,
		CPUQuota:     b.options.CPUQuota,
		CpusetCpus:   b.options.CPUSetCPUs,
		CpusetMems:   b.options.CPUSetMems,
		Memory:       b.options.Memory,
		MemorySwap:   b.options.MemorySwap,
		Ulimits:      b.options.Ulimits,
	}

	// TODO: why not embed a hostconfig in builder?
	hostConfig := &container.HostConfig{
		SecurityOpt: b.options.SecurityOpt,
		Isolation:   b.options.Isolation,
		ShmSize:     b.options.ShmSize,
		Resources:   resources,
		NetworkMode: container.NetworkMode(b.options.NetworkMode),
		// Set a log config to override any default value set on the daemon
		LogConfig:  defaultLogConfig,
		ExtraHosts: b.options.ExtraHosts,
	}

	// Create the container
	c, err := b.docker.ContainerCreate(types.ContainerCreateConfig{
		Config:     runConfig,
		HostConfig: hostConfig,
	})
	if err != nil {
		return "", err
	}
	for _, warning := range c.Warnings {
		fmt.Fprintf(b.Stdout, " ---> [Warning] %s\n", warning)
	}

	b.tmpContainers[c.ID] = struct{}{}
	fmt.Fprintf(b.Stdout, " ---> Running in %s\n", stringid.TruncateID(c.ID))
	return c.ID, nil
}

Output of docker version:

Server:
 Version:      17.06.0-ce
 API version:  1.30 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   02c1d87
 Built:        Fri Jun 23 21:51:55 2017
 OS/Arch:      linux/amd64
 Experimental: true

Output of docker info:

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 29
Server Version: 17.06.0-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host ipvlan macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: cfb82a876ecc11b5ca0977d1733adbe58599088a
runc version: 2d41c047c83e09a6d61d464906feb2a2f3c52aa4
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 4.9.36-moby
Operating System: Alpine Linux v3.5
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.952GiB
Name: moby
ID: NL37:KZKS:2644:6E6R:2C4J:GYYZ:MHIO:NBKB:ESQ6:D7UT:JYWP:4FHF
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: 17
 Goroutines: 28
 System Time: 2017-08-09T01:25:51.531480835Z
 EventsListeners: 1
Registry: https://index.docker.io/v1/
Experimental: true
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

Additional environment details (AWS, VirtualBox, physical, etc.):

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

you can supply a custom default profile to the daemon. `–secomp-profile /path/to/profile.json’

@cpuguy83 How?

# sudo docker build -t test . --secomp-profile test.json
unknown flag: --secomp-profile
See 'docker build --help'.

And what is the equivalent of --security-opt seccomp:unconfined in the json file?

This is getting ridiculous, I am just trying to update a recent ubuntu via apt-get update (in image) and I have to jump through so many hoops to do it? I am starting to wonder if docker wasn’t a giant mistake… https://askubuntu.com/questions/1263284/apt-update-throws-signature-error-in-ubuntu-20-04-container-on-arm

There’s two/three related, but distinct issues discussed in this ticket;

  1. docker build does not allow for a seccomp profile to be set for containers used during build (through --security-opt)
  2. docker build, when using BuildKit as builder, always uses the default seccomp profile, and does not inherit the daemon’s setting.
  3. The default seccomp profile currently uses EPERM for syscalls that are blocked, which can cause some binaries to not fall back to alternatives (whereas ENOSYS would)

For the last one (3.), there’s an open ticket, which hasn’t been revisited in some time, but came up in recent discussions. While changing the default to ENOSYS is something we think is worth considering, the devil can be in the detail, and this needs to be looked into. If you’re interested in that topic or have input that would help, feel free to participate on the ticket;

For 1. (the original request reported in this ticket), and 2., the best place to continue that conversation would be in the BuildKit repository, as this is where this would have to be implemented (first). There’s a couple of issues that would have to be discussed (and UX to be worked on);

  • The BuildKit maintainers started work on re-designing security options for build; the intent is to make the Dockerfile more declarative on what’s needed to perform the build. If a specific step in the Dockerfile requires specific privileges (which could be networking or other options), those can be defined as an option on the RUN command. This approach both allows for such options to be applied more granular (i.e., only for specific steps in the Dockerfile), and making the Dockerfile more descriptive (a user building the Dockerfile needs to grant the permissions, whereas previously the build could fail for “unclear reasons” if, for example, networking was required, but the build was started without --network=<option>). This feature is not final yet (the “labs” version of the Dockerfile syntax allows for some --security options. It does not yet allow seccomp options to be set, but does allow for “privileged” steps (be careful using those, as it effectively disables all protection)); see RUN --security in the documentation.
  • For (custom) seccomp profiles to be supported (or some other way to define what syscalls should be (un)blocked), this would likely have to be implemented through such an option, but the UX may need input / brainstorming (how to pass the (custom) profile? seccomp profiles can be difficult to write; perhaps there’s a more convenient way to declare what’s needed?). If you’re interested in this feature, and perhaps have ideas on the UX / design, I encourage you to open a ticket in the BuildKit issue tracker (https://github.com/moby/buildkit/issues) (and add a link to this ticket).
  • For inheriting the (custom) profile as set on the daemon; this is something that would (I think) also have to be implemented in BuildKit, and have to be decided on by the BuildKit maintainers; if this is something you’d like to see implemented, I would recommend creating a separate ticket from the previous one, as it may need additional discussion: from discussions I had with the maintainers, there were some concerns, as this could lead to more “works on my machine” situations for docker build (depending on what’s configured on the daemon), which is why their preference was to make security options part of the Dockerfile. That said, “I want to enforce a stricter profile” could be a compelling case, so perhaps they’re open to discussing.

It’s an option on the daemon, so needs to be set either in the systemd unit file, or in the daemon.json configuration file for the daemon; https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file

but doing so will disable seccomp for all containers and I don’t think the option currently passed through to docker build with BuildKit enabled.

And what is the equivalent of --security-opt seccomp:unconfined in the json file?

The daemon currently does not support the “named” profiles (and thus, doesn’t accept unconfined until https://github.com/moby/moby/pull/42481 is merged/released), but you can instead create an file containing an empty JSON profile ({}) and set the location of the file as the profile.

I am just trying to update a recent ubuntu via apt-get update (in image) and I have to jump through so many hoops to do it?

What version of docker, containerd and runc are you running? I think those issues should be fixed in current patch releases.

@cason you can supply a custom default profile to the daemon. `–secomp-profile /path/to/profile.json’

On Tue, Aug 8, 2017 at 10:31 PM, cason notifications@github.com wrote:

@cpuguy83 https://github.com/cpuguy83 I have a problem that I need the specific seccomp profile when executing docker build to prevent system vulnerability, such as CVE-2017-7533. I need to disable inotify_init and inotify_init1 syscall, and how can i do that?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/moby/moby/issues/34454#issuecomment-321135216, or mute the thread https://github.com/notifications/unsubscribe-auth/AAwxZs5HQIFBXsyUJDUJS_O9dGY5y9-kks5sWRn_gaJpZM4OxfBP .

  • Brian Goff