From 2a81c9f6771eb8c94c7979cc8f2683e2b780d432 Mon Sep 17 00:00:00 2001 From: Olli Janatuinen Date: Thu, 28 Oct 2021 14:50:05 +0300 Subject: [PATCH] CRI: Support enable_unprivileged_icmp and enable_unprivileged_ports options Signed-off-by: Olli Janatuinen --- docs/cri/config.md | 13 +++++++++++++ pkg/cri/config/config.go | 11 +++++++++++ pkg/cri/server/sandbox_run_linux.go | 14 ++++++++++++++ pkg/cri/server/sandbox_run_linux_test.go | 19 +++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/docs/cri/config.md b/docs/cri/config.md index d10e6f663..5c0940098 100644 --- a/docs/cri/config.md +++ b/docs/cri/config.md @@ -107,6 +107,19 @@ version = 2 # set to nil or `unconfined`, and the default used when the runtime default seccomp profile is requested. 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] diff --git a/pkg/cri/config/config.go b/pkg/cri/config/config.go index d35fadbe3..2896b0448 100644 --- a/pkg/cri/config/config.go +++ b/pkg/cri/config/config.go @@ -282,6 +282,17 @@ type PluginConfig struct { // of being placed under the hardcoded directory /var/run/netns. Changing this setting requires // that all containers are deleted. 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 diff --git a/pkg/cri/server/sandbox_run_linux.go b/pkg/cri/server/sandbox_run_linux.go index 145c62aea..82c197310 100644 --- a/pkg/cri/server/sandbox_run_linux.go +++ b/pkg/cri/server/sandbox_run_linux.go @@ -34,6 +34,7 @@ import ( "github.com/containerd/containerd/pkg/cri/annotations" customopts "github.com/containerd/containerd/pkg/cri/opts" osinterface "github.com/containerd/containerd/pkg/os" + "github.com/containerd/containerd/pkg/userns" ) func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, @@ -134,6 +135,19 @@ func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxC // Add sysctls 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)) // Note: LinuxSandboxSecurityContext does not currently provide an apparmor profile diff --git a/pkg/cri/server/sandbox_run_linux_test.go b/pkg/cri/server/sandbox_run_linux_test.go index 119c04546..b203984e2 100644 --- a/pkg/cri/server/sandbox_run_linux_test.go +++ b/pkg/cri/server/sandbox_run_linux_test.go @@ -115,6 +115,8 @@ func TestLinuxSandboxContainerSpec(t *testing.T) { assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ 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": { @@ -142,6 +144,8 @@ func TestLinuxSandboxContainerSpec(t *testing.T) { assert.NotContains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ 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": { @@ -156,9 +160,24 @@ func TestLinuxSandboxContainerSpec(t *testing.T) { 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) c := newTestCRIService() + c.config.EnableUnprivilegedICMP = true + c.config.EnableUnprivilegedPorts = true config, imageConfig, specCheck := getRunPodSandboxTestData() if test.configChange != nil { test.configChange(config)