CRI: Support enable_unprivileged_icmp and enable_unprivileged_ports options

Signed-off-by: Olli Janatuinen <olli.janatuinen@gmail.com>
This commit is contained in:
Olli Janatuinen 2021-10-28 14:50:05 +03:00
parent 5b09dc5eb0
commit 2a81c9f677
4 changed files with 57 additions and 0 deletions

View File

@ -107,6 +107,19 @@ version = 2
# set to nil or `unconfined`, and the default used when the runtime default seccomp profile is requested. # set to nil or `unconfined`, and the default used when the runtime default seccomp profile is requested.
unset_seccomp_profile = "" unset_seccomp_profile = ""
# enable_unprivileged_ports configures net.ipv4.ip_unprivileged_port_start=0
# for all containers which are not using host network
# and if it is not overwritten by PodSandboxConfig
# Note that currently default is set to disabled but target change it in future, see:
# [k8s discussion](https://github.com/kubernetes/kubernetes/issues/102612)
enable_unprivileged_ports = false
# enable_unprivileged_icmp configures net.ipv4.ping_group_range="0 2147483647"
# for all containers which are not using host network, are not running in user namespace
# and if it is not overwritten by PodSandboxConfig
# Note that currently default is set to disabled but target change it in future together with enable_unprivileged_ports
enable_unprivileged_icmp = false
# 'plugins."io.containerd.grpc.v1.cri".containerd' contains config related to containerd # 'plugins."io.containerd.grpc.v1.cri".containerd' contains config related to containerd
[plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd]

View File

@ -282,6 +282,17 @@ type PluginConfig struct {
// of being placed under the hardcoded directory /var/run/netns. Changing this setting requires // of being placed under the hardcoded directory /var/run/netns. Changing this setting requires
// that all containers are deleted. // that all containers are deleted.
NetNSMountsUnderStateDir bool `toml:"netns_mounts_under_state_dir" json:"netnsMountsUnderStateDir"` NetNSMountsUnderStateDir bool `toml:"netns_mounts_under_state_dir" json:"netnsMountsUnderStateDir"`
// EnableUnprivilegedPorts configures net.ipv4.ip_unprivileged_port_start=0
// for all containers which are not using host network
// and if it is not overwritten by PodSandboxConfig
// Note that currently default is set to disabled but target change it in future, see:
// https://github.com/kubernetes/kubernetes/issues/102612
EnableUnprivilegedPorts bool `toml:"enable_unprivileged_ports" json:"enableUnprivilegedPorts"`
// EnableUnprivilegedICMP configures net.ipv4.ping_group_range="0 2147483647"
// for all containers which are not using host network, are not running in user namespace
// and if it is not overwritten by PodSandboxConfig
// Note that currently default is set to disabled but target change it in future together with EnableUnprivilegedPorts
EnableUnprivilegedICMP bool `toml:"enable_unprivileged_icmp" json:"enableUnprivilegedICMP"`
} }
// X509KeyPairStreaming contains the x509 configuration for streaming // X509KeyPairStreaming contains the x509 configuration for streaming

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/pkg/cri/annotations" "github.com/containerd/containerd/pkg/cri/annotations"
customopts "github.com/containerd/containerd/pkg/cri/opts" customopts "github.com/containerd/containerd/pkg/cri/opts"
osinterface "github.com/containerd/containerd/pkg/os" osinterface "github.com/containerd/containerd/pkg/os"
"github.com/containerd/containerd/pkg/userns"
) )
func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig,
@ -134,6 +135,19 @@ func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxC
// Add sysctls // Add sysctls
sysctls := config.GetLinux().GetSysctls() sysctls := config.GetLinux().GetSysctls()
if sysctls == nil {
sysctls = make(map[string]string)
}
_, ipUnprivilegedPortStart := sysctls["net.ipv4.ip_unprivileged_port_start"]
_, pingGroupRange := sysctls["net.ipv4.ping_group_range"]
if nsOptions.GetNetwork() != runtime.NamespaceMode_NODE {
if c.config.EnableUnprivilegedPorts && !ipUnprivilegedPortStart {
sysctls["net.ipv4.ip_unprivileged_port_start"] = "0"
}
if c.config.EnableUnprivilegedICMP && !pingGroupRange && !userns.RunningInUserNS() {
sysctls["net.ipv4.ping_group_range"] = "0 2147483647"
}
}
specOpts = append(specOpts, customopts.WithSysctls(sysctls)) specOpts = append(specOpts, customopts.WithSysctls(sysctls))
// Note: LinuxSandboxSecurityContext does not currently provide an apparmor profile // Note: LinuxSandboxSecurityContext does not currently provide an apparmor profile

View File

@ -115,6 +115,8 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
Type: runtimespec.IPCNamespace, Type: runtimespec.IPCNamespace,
}) })
assert.Contains(t, spec.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "0")
assert.Contains(t, spec.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647")
}, },
}, },
"host namespace": { "host namespace": {
@ -142,6 +144,8 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
assert.NotContains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ assert.NotContains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
Type: runtimespec.IPCNamespace, Type: runtimespec.IPCNamespace,
}) })
assert.NotContains(t, spec.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "0")
assert.NotContains(t, spec.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647")
}, },
}, },
"should set supplemental groups correctly": { "should set supplemental groups correctly": {
@ -156,9 +160,24 @@ func TestLinuxSandboxContainerSpec(t *testing.T) {
assert.Contains(t, spec.Process.User.AdditionalGids, uint32(2222)) assert.Contains(t, spec.Process.User.AdditionalGids, uint32(2222))
}, },
}, },
"should overwrite default sysctls": {
configChange: func(c *runtime.PodSandboxConfig) {
c.Linux.Sysctls = map[string]string{
"net.ipv4.ip_unprivileged_port_start": "500",
"net.ipv4.ping_group_range": "1 1000",
}
},
specCheck: func(t *testing.T, spec *runtimespec.Spec) {
require.NotNil(t, spec.Process)
assert.Contains(t, spec.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "500")
assert.Contains(t, spec.Linux.Sysctl["net.ipv4.ping_group_range"], "1 1000")
},
},
} { } {
t.Logf("TestCase %q", desc) t.Logf("TestCase %q", desc)
c := newTestCRIService() c := newTestCRIService()
c.config.EnableUnprivilegedICMP = true
c.config.EnableUnprivilegedPorts = true
config, imageConfig, specCheck := getRunPodSandboxTestData() config, imageConfig, specCheck := getRunPodSandboxTestData()
if test.configChange != nil { if test.configChange != nil {
test.configChange(config) test.configChange(config)