Add support for swarm seccomp and apparmor
And also no-new-privileges Signed-off-by: Drew Erny <derny@mirantis.com>
This commit is contained in:
parent
bd7b27b5c8
commit
42a51cb285
12 changed files with 1298 additions and 408 deletions
|
@ -118,4 +118,13 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
|||
service.Mode.ReplicatedJob = nil
|
||||
service.Mode.GlobalJob = nil
|
||||
}
|
||||
|
||||
if versions.LessThan(cliVersion, "1.44") {
|
||||
// seccomp, apparmor, and no_new_privs were added in 1.44.
|
||||
if service.TaskTemplate.ContainerSpec != nil && service.TaskTemplate.ContainerSpec.Privileges != nil {
|
||||
service.TaskTemplate.ContainerSpec.Privileges.Seccomp = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.AppArmor = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.NoNewPrivileges = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3553,6 +3553,32 @@ definitions:
|
|||
Level:
|
||||
type: "string"
|
||||
description: "SELinux level label"
|
||||
Seccomp:
|
||||
type: "object"
|
||||
description: "Options for configuring seccomp on the container"
|
||||
properties:
|
||||
Mode:
|
||||
type: "string"
|
||||
enum:
|
||||
- "default"
|
||||
- "unconfined"
|
||||
- "custom"
|
||||
Profile:
|
||||
description: "The custom seccomp profile as a json object"
|
||||
type: "string"
|
||||
AppArmor:
|
||||
type: "object"
|
||||
description: "Options for configuring AppArmor on the container"
|
||||
properties:
|
||||
Mode:
|
||||
type: "string"
|
||||
enum:
|
||||
- "default"
|
||||
- "disabled"
|
||||
NoNewPrivileges:
|
||||
type: "boolean"
|
||||
description: "Configuration of the no_new_privs bit in the container"
|
||||
|
||||
TTY:
|
||||
description: "Whether a pseudo-TTY should be allocated."
|
||||
type: "boolean"
|
||||
|
|
|
@ -32,6 +32,42 @@ type SELinuxContext struct {
|
|||
Level string
|
||||
}
|
||||
|
||||
// SeccompMode is the type used for the enumeration of possible seccomp modes
|
||||
// in SeccompOpts
|
||||
type SeccompMode string
|
||||
|
||||
const (
|
||||
SeccompModeDefault SeccompMode = "default"
|
||||
SeccompModeUnconfined SeccompMode = "unconfined"
|
||||
SeccompModeCustom SeccompMode = "custom"
|
||||
)
|
||||
|
||||
// SeccompOpts defines the options for configuring seccomp on a swarm-managed
|
||||
// container.
|
||||
type SeccompOpts struct {
|
||||
// Mode is the SeccompMode used for the container.
|
||||
Mode SeccompMode `json:",omitempty"`
|
||||
// Profile is the custom seccomp profile as a json object to be used with
|
||||
// the container. Mode should be set to SeccompModeCustom when using a
|
||||
// custom profile in this manner.
|
||||
Profile []byte `json:",omitempty"`
|
||||
}
|
||||
|
||||
// AppArmorMode is type used for the enumeration of possible AppArmor modes in
|
||||
// AppArmorOpts
|
||||
type AppArmorMode string
|
||||
|
||||
const (
|
||||
AppArmorModeDefault AppArmorMode = "default"
|
||||
AppArmorModeDisabled AppArmorMode = "disabled"
|
||||
)
|
||||
|
||||
// AppArmorOpts defines the options for configuring AppArmor on a swarm-managed
|
||||
// container. Currently, custom AppArmor profiles are not supported.
|
||||
type AppArmorOpts struct {
|
||||
Mode AppArmorMode `json:",omitempty"`
|
||||
}
|
||||
|
||||
// CredentialSpec for managed service account (Windows only)
|
||||
type CredentialSpec struct {
|
||||
Config string
|
||||
|
@ -41,8 +77,11 @@ type CredentialSpec struct {
|
|||
|
||||
// Privileges defines the security options for the container.
|
||||
type Privileges struct {
|
||||
CredentialSpec *CredentialSpec
|
||||
SELinuxContext *SELinuxContext
|
||||
CredentialSpec *CredentialSpec
|
||||
SELinuxContext *SELinuxContext
|
||||
Seccomp *SeccompOpts `json:",omitempty"`
|
||||
AppArmor *AppArmorOpts `json:",omitempty"`
|
||||
NoNewPrivileges bool
|
||||
}
|
||||
|
||||
// ContainerSpec represents the spec of a container.
|
||||
|
|
|
@ -69,6 +69,34 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
|
|||
Level: c.Privileges.SELinuxContext.Level,
|
||||
}
|
||||
}
|
||||
|
||||
if c.Privileges.Seccomp != nil {
|
||||
containerSpec.Privileges.Seccomp = &types.SeccompOpts{
|
||||
Profile: c.Privileges.Seccomp.Profile,
|
||||
}
|
||||
|
||||
switch c.Privileges.Seccomp.Mode {
|
||||
case swarmapi.Privileges_SeccompOpts_DEFAULT:
|
||||
containerSpec.Privileges.Seccomp.Mode = types.SeccompModeDefault
|
||||
case swarmapi.Privileges_SeccompOpts_UNCONFINED:
|
||||
containerSpec.Privileges.Seccomp.Mode = types.SeccompModeUnconfined
|
||||
case swarmapi.Privileges_SeccompOpts_CUSTOM:
|
||||
containerSpec.Privileges.Seccomp.Mode = types.SeccompModeCustom
|
||||
}
|
||||
}
|
||||
|
||||
if c.Privileges.Apparmor != nil {
|
||||
containerSpec.Privileges.AppArmor = &types.AppArmorOpts{}
|
||||
|
||||
switch c.Privileges.Apparmor.Mode {
|
||||
case swarmapi.Privileges_AppArmorOpts_DEFAULT:
|
||||
containerSpec.Privileges.AppArmor.Mode = types.AppArmorModeDefault
|
||||
case swarmapi.Privileges_AppArmorOpts_DISABLED:
|
||||
containerSpec.Privileges.AppArmor.Mode = types.AppArmorModeDisabled
|
||||
}
|
||||
}
|
||||
|
||||
containerSpec.Privileges.NoNewPrivileges = c.Privileges.NoNewPrivileges
|
||||
}
|
||||
|
||||
// Mounts
|
||||
|
@ -308,6 +336,34 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
|
|||
Level: c.Privileges.SELinuxContext.Level,
|
||||
}
|
||||
}
|
||||
|
||||
if c.Privileges.Seccomp != nil {
|
||||
containerSpec.Privileges.Seccomp = &swarmapi.Privileges_SeccompOpts{
|
||||
Profile: c.Privileges.Seccomp.Profile,
|
||||
}
|
||||
|
||||
switch c.Privileges.Seccomp.Mode {
|
||||
case types.SeccompModeDefault:
|
||||
containerSpec.Privileges.Seccomp.Mode = swarmapi.Privileges_SeccompOpts_DEFAULT
|
||||
case types.SeccompModeUnconfined:
|
||||
containerSpec.Privileges.Seccomp.Mode = swarmapi.Privileges_SeccompOpts_UNCONFINED
|
||||
case types.SeccompModeCustom:
|
||||
containerSpec.Privileges.Seccomp.Mode = swarmapi.Privileges_SeccompOpts_CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
if c.Privileges.AppArmor != nil {
|
||||
containerSpec.Privileges.Apparmor = &swarmapi.Privileges_AppArmorOpts{}
|
||||
|
||||
switch c.Privileges.AppArmor.Mode {
|
||||
case types.AppArmorModeDefault:
|
||||
containerSpec.Privileges.Apparmor.Mode = swarmapi.Privileges_AppArmorOpts_DEFAULT
|
||||
case types.AppArmorModeDisabled:
|
||||
containerSpec.Privileges.Apparmor.Mode = swarmapi.Privileges_AppArmorOpts_DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
containerSpec.Privileges.NoNewPrivileges = c.Privileges.NoNewPrivileges
|
||||
}
|
||||
|
||||
if c.Configs != nil {
|
||||
|
|
|
@ -698,6 +698,32 @@ func (c *containerConfig) applyPrivileges(hc *enginecontainer.HostConfig) {
|
|||
hc.SecurityOpt = append(hc.SecurityOpt, "label=type:"+selinux.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// variable to make the lines shorter and easier to read
|
||||
if seccomp := privileges.Seccomp; seccomp != nil {
|
||||
switch seccomp.Mode {
|
||||
// case api.Privileges_SeccompOpts_DEFAULT:
|
||||
// if the setting is default, nothing needs to be set here. we leave
|
||||
// the option empty.
|
||||
case api.Privileges_SeccompOpts_UNCONFINED:
|
||||
hc.SecurityOpt = append(hc.SecurityOpt, "seccomp=unconfined")
|
||||
case api.Privileges_SeccompOpts_CUSTOM:
|
||||
// Profile is bytes, but those bytes are actually a string. This is
|
||||
// basically verbatim what happens in the cli after a file is read.
|
||||
hc.SecurityOpt = append(hc.SecurityOpt, fmt.Sprintf("seccomp=%s", seccomp.Profile))
|
||||
}
|
||||
}
|
||||
|
||||
// if the setting is DEFAULT, then nothing to be done. If it's DISABLED,
|
||||
// we set that. Custom not supported yet. When custom *is* supported, make
|
||||
// it look like the above.
|
||||
if apparmor := privileges.Apparmor; apparmor != nil && apparmor.Mode == api.Privileges_AppArmorOpts_DISABLED {
|
||||
hc.SecurityOpt = append(hc.SecurityOpt, "apparmor=unconfined")
|
||||
}
|
||||
|
||||
if privileges.NoNewPrivileges {
|
||||
hc.SecurityOpt = append(hc.SecurityOpt, "no-new-privileges=true")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *containerConfig) eventFilter() filters.Args {
|
||||
|
|
|
@ -52,6 +52,9 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
These endpoints will also return the full set of validation errors they find,
|
||||
instead of returning only the first one.
|
||||
Note that this change is _unversioned_ and applies to all API versions.
|
||||
* `POST /services/create` and `POST /services/{id}/update` now accept `Seccomp`
|
||||
and `AppArmor` fields in the `ContainerSpec.Privileges` object. This allows
|
||||
some configuration of Seccomp and AppArmor in Swarm services.
|
||||
|
||||
## v1.43 API changes
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ require (
|
|||
github.com/moby/locker v1.0.1
|
||||
github.com/moby/patternmatcher v0.6.0
|
||||
github.com/moby/pubsub v1.0.0
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230815220644-3f2e40b3ed51
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230823155524-12f0c246fed0
|
||||
github.com/moby/sys/mount v0.3.3
|
||||
github.com/moby/sys/mountinfo v0.6.2
|
||||
github.com/moby/sys/sequential v0.5.0
|
||||
|
|
|
@ -917,8 +917,8 @@ github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkV
|
|||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/pubsub v1.0.0 h1:jkp/imWsmJz2f6LyFsk7EkVeN2HxR/HTTOY8kHrsxfA=
|
||||
github.com/moby/pubsub v1.0.0/go.mod h1:bXSO+3h5MNXXCaEG+6/NlAIk7MMZbySZlnB+cUQhKKc=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230815220644-3f2e40b3ed51 h1:Am1RXolTCcQT5zaEUBGczaHZaV069crCKpLHckp9isM=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230815220644-3f2e40b3ed51/go.mod h1:dHTjRFlamMrutFg1Vi0AEZKtVx2qZV/7A/imviPXQiE=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230823155524-12f0c246fed0 h1:DBx1xD69N0nQjoMQskoTQQTb0hpZbo+8Rk9ug0wUMKs=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230823155524-12f0c246fed0/go.mod h1:dHTjRFlamMrutFg1Vi0AEZKtVx2qZV/7A/imviPXQiE=
|
||||
github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
|
||||
github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
|
||||
github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs=
|
||||
|
|
78
vendor/github.com/moby/swarmkit/v2/api/api.pb.txt
generated
vendored
78
vendor/github.com/moby/swarmkit/v2/api/api.pb.txt
generated
vendored
|
@ -4324,6 +4324,29 @@ file {
|
|||
}
|
||||
json_name: "selinuxContext"
|
||||
}
|
||||
field {
|
||||
name: "seccomp"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".docker.swarmkit.v1.Privileges.SeccompOpts"
|
||||
json_name: "seccomp"
|
||||
}
|
||||
field {
|
||||
name: "apparmor"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".docker.swarmkit.v1.Privileges.AppArmorOpts"
|
||||
json_name: "apparmor"
|
||||
}
|
||||
field {
|
||||
name: "no_new_privileges"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_BOOL
|
||||
json_name: "noNewPrivileges"
|
||||
}
|
||||
nested_type {
|
||||
name: "CredentialSpec"
|
||||
field {
|
||||
|
@ -4392,6 +4415,61 @@ file {
|
|||
json_name: "level"
|
||||
}
|
||||
}
|
||||
nested_type {
|
||||
name: "SeccompOpts"
|
||||
field {
|
||||
name: "mode"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_ENUM
|
||||
type_name: ".docker.swarmkit.v1.Privileges.SeccompOpts.SeccompMode"
|
||||
json_name: "mode"
|
||||
}
|
||||
field {
|
||||
name: "profile"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_BYTES
|
||||
json_name: "profile"
|
||||
}
|
||||
enum_type {
|
||||
name: "SeccompMode"
|
||||
value {
|
||||
name: "DEFAULT"
|
||||
number: 0
|
||||
}
|
||||
value {
|
||||
name: "UNCONFINED"
|
||||
number: 1
|
||||
}
|
||||
value {
|
||||
name: "CUSTOM"
|
||||
number: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
nested_type {
|
||||
name: "AppArmorOpts"
|
||||
field {
|
||||
name: "mode"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_ENUM
|
||||
type_name: ".docker.swarmkit.v1.Privileges.AppArmorOpts.AppArmorMode"
|
||||
json_name: "mode"
|
||||
}
|
||||
enum_type {
|
||||
name: "AppArmorMode"
|
||||
value {
|
||||
name: "DEFAULT"
|
||||
number: 0
|
||||
}
|
||||
value {
|
||||
name: "DISABLED"
|
||||
number: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "JobStatus"
|
||||
|
|
1424
vendor/github.com/moby/swarmkit/v2/api/types.pb.go
generated
vendored
1424
vendor/github.com/moby/swarmkit/v2/api/types.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
33
vendor/github.com/moby/swarmkit/v2/api/types.proto
generated
vendored
33
vendor/github.com/moby/swarmkit/v2/api/types.proto
generated
vendored
|
@ -1156,6 +1156,39 @@ message Privileges {
|
|||
string level = 5;
|
||||
}
|
||||
SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"];
|
||||
|
||||
// SeccompOpts contains options for configuring seccomp profiles on the
|
||||
// container. See https://docs.docker.com/engine/security/seccomp/ for more
|
||||
// information.
|
||||
message SeccompOpts {
|
||||
enum SeccompMode {
|
||||
DEFAULT = 0;
|
||||
UNCONFINED = 1;
|
||||
CUSTOM = 2;
|
||||
}
|
||||
SeccompMode mode = 1;
|
||||
// Profile contains the json definition of the seccomp profile to use,
|
||||
// if Mode is set to custom.
|
||||
bytes profile = 2;
|
||||
}
|
||||
SeccompOpts seccomp = 3;
|
||||
|
||||
// AppArmorOpts contains options for configuring AppArmor profiles on the
|
||||
// container. Currently, custom profiles are not supported. See
|
||||
// https://docs.docker.com/engine/security/apparmor/ for more information.
|
||||
message AppArmorOpts {
|
||||
enum AppArmorMode {
|
||||
DEFAULT = 0;
|
||||
DISABLED = 1;
|
||||
}
|
||||
AppArmorMode mode = 1;
|
||||
}
|
||||
AppArmorOpts apparmor = 4;
|
||||
|
||||
// NoNewPrivileges, if set to true, disables the container from gaining new
|
||||
// privileges. See https://docs.kernel.org/userspace-api/no_new_privs.html
|
||||
// for details.
|
||||
bool no_new_privileges = 5;
|
||||
}
|
||||
|
||||
// JobStatus indicates the status of a Service that is in one of the Job modes.
|
||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -829,7 +829,7 @@ github.com/moby/patternmatcher/ignorefile
|
|||
# github.com/moby/pubsub v1.0.0
|
||||
## explicit; go 1.19
|
||||
github.com/moby/pubsub
|
||||
# github.com/moby/swarmkit/v2 v2.0.0-20230815220644-3f2e40b3ed51
|
||||
# github.com/moby/swarmkit/v2 v2.0.0-20230823155524-12f0c246fed0
|
||||
## explicit; go 1.18
|
||||
github.com/moby/swarmkit/v2/agent
|
||||
github.com/moby/swarmkit/v2/agent/configs
|
||||
|
|
Loading…
Add table
Reference in a new issue