Skip to content

Commit

Permalink
feat: make group ID configurable
Browse files Browse the repository at this point in the history
This defines the group ID and adds the option to set it manually

Signed-off-by: Nico Feulner <[email protected]>

fix: runAsGroup instead of runAsUser

Signed-off-by: Nico Feulner <[email protected]>

fix: formatting in test files

Signed-off-by: Nico Feulner <[email protected]>

fix: re-generate helm docs

Signed-off-by: Nico Feulner <[email protected]>

fix: missing GID injection
  • Loading branch information
nico151999 committed Apr 17, 2024
1 parent 3c46e12 commit 4000715
Show file tree
Hide file tree
Showing 125 changed files with 745 additions and 13 deletions.
3 changes: 3 additions & 0 deletions charts/linkerd-control-plane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Kubernetes: `>=1.22.0-0`
| controlPlaneTracingNamespace | string | `"linkerd-jaeger"` | namespace to send control plane traces to |
| controller.podDisruptionBudget | object | `{"maxUnavailable":1}` | sets pod disruption budget parameter for all deployments |
| controller.podDisruptionBudget.maxUnavailable | int | `1` | Maximum number of pods that can be unavailable during disruption |
| controllerGID | int | `2103` | Group ID for the control plane components |
| controllerImage | string | `"cr.l5d.io/linkerd/controller"` | Docker image for the destination and identity components |
| controllerImageVersion | string | `""` | Optionally allow a specific container image Tag (or SHA) to be specified for the controllerImage. |
| controllerLogFormat | string | `"plain"` | Log format for the control plane components |
Expand Down Expand Up @@ -237,6 +238,7 @@ Kubernetes: `>=1.22.0-0`
| proxy.disableInboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the inbound side of the proxy by setting it to a very high value |
| proxy.disableOutboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the outbound side of the proxy by setting it to a very high value |
| proxy.enableExternalProfiles | bool | `false` | Enable service profiles for non-Kubernetes services |
| proxy.gid | int | `2102` | Group id under which the proxy runs |
| proxy.image.name | string | `"cr.l5d.io/linkerd/proxy"` | Docker image for the proxy |
| proxy.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy container image |
| proxy.image.version | string | linkerdVersion | Tag for the proxy container image |
Expand Down Expand Up @@ -284,6 +286,7 @@ Kubernetes: `>=1.22.0-0`
| proxyInit.resources.ephemeral-storage.request | string | `""` | Amount of ephemeral storage that the proxy-init container requests |
| proxyInit.resources.memory.limit | string | `"20Mi"` | Maximum amount of memory that the proxy-init container can use |
| proxyInit.resources.memory.request | string | `"20Mi"` | Amount of memory that the proxy-init container requests |
| proxyInit.runAsGroup | int | `65534` | This value is used only if runAsRoot is false; otherwise runAsGroup will be 0 |
| proxyInit.runAsRoot | bool | `false` | Allow overriding the runAsNonRoot behaviour (<https://github.com/linkerd/linkerd2/issues/7308>) |
| proxyInit.runAsUser | int | `65534` | This value is used only if runAsRoot is false; otherwise runAsUser will be 0 |
| proxyInit.skipSubnets | string | `""` | Comma-separated list of subnets in valid CIDR format that should be skipped by the proxy |
Expand Down
3 changes: 3 additions & 0 deletions charts/linkerd-control-plane/templates/destination.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down Expand Up @@ -294,6 +295,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down Expand Up @@ -354,6 +356,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down
1 change: 1 addition & 0 deletions charts/linkerd-control-plane/templates/heartbeat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down
1 change: 1 addition & 0 deletions charts/linkerd-control-plane/templates/identity.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down
1 change: 1 addition & 0 deletions charts/linkerd-control-plane/templates/proxy-injector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ spec:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.controllerUID}}
runAsGroup: {{.Values.controllerGID}}
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
Expand Down
9 changes: 9 additions & 0 deletions charts/linkerd-control-plane/templates/psp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ spec:
{{- else }}
rule: RunAsAny
{{- end }}
runAsGroup:
{{- if .Values.cniEnabled }}
rule: MustRunAs
ranges:
- min: 1000
max: 999999
{{- else }}
rule: RunAsAny
{{- end }}
supplementalGroups:
rule: MustRunAs
ranges:
Expand Down
6 changes: 6 additions & 0 deletions charts/linkerd-control-plane/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ proxy:
request: ""
# -- User id under which the proxy runs
uid: 2102
# -- Group id under which the proxy runs
gid: 2102
# -- If set the injected proxy sidecars in the data plane will stay alive for
# at least the given period before receiving the SIGTERM signal from
# Kubernetes but no longer than the pod's `terminationGracePeriodSeconds`.
Expand Down Expand Up @@ -297,6 +299,8 @@ proxyInit:
runAsRoot: false
# -- This value is used only if runAsRoot is false; otherwise runAsUser will be 0
runAsUser: 65534
# -- This value is used only if runAsRoot is false; otherwise runAsGroup will be 0
runAsGroup: 65534
xtMountPath:
mountPath: /run
name: linkerd-proxy-init-xtables-lock
Expand Down Expand Up @@ -344,6 +348,8 @@ controllerImageVersion: ""
controllerReplicas: 1
# -- User ID for the control plane components
controllerUID: 2103
# -- Group ID for the control plane components
controllerGID: 2103

# destination configuration
# set resources for the sp-validator and its linkerd proxy respectively
Expand Down
1 change: 1 addition & 0 deletions charts/linkerd2-cni/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Kubernetes: `>=1.22.0-0`
| privileged | bool | `false` | Run the install-cni container in privileged mode |
| proxyAdminPort | int | `4191` | Admin port for the proxy container |
| proxyControlPort | int | `4190` | Control port for the proxy container |
| proxyGID | int | `2102` | Group id under which the proxy shall be ran |
| proxyUID | int | `2102` | User id under which the proxy shall be ran |
| repairController.enableSecurityContext | bool | `true` | Include a securityContext in the repair-controller container |
| repairController.enabled | bool | `false` | Enables the repair-controller container |
Expand Down
3 changes: 3 additions & 0 deletions charts/linkerd2-cni/templates/cni-plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ spec:
rule: RunAsAny
runAsUser:
rule: RunAsAny
runAsGroup:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
Expand Down Expand Up @@ -168,6 +170,7 @@ data:
"incoming-proxy-port": {{.Values.inboundProxyPort}},
"outgoing-proxy-port": {{.Values.outboundProxyPort}},
"proxy-uid": {{.Values.proxyUID}},
"proxy-gid": {{.Values.proxyGID}},
"ports-to-redirect": [{{.Values.portsToRedirect}}],
"inbound-ports-to-ignore": ["{{- .Values.proxyAdminPort }}","{{ .Values.proxyControlPort }}"
{{- if .Values.ignoreInboundPorts }},{{- include "partials.splitStringList" .Values.ignoreInboundPorts -}}{{- end }}],
Expand Down
2 changes: 2 additions & 0 deletions charts/linkerd2-cni/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ logLevel: info
portsToRedirect: ""
# -- User id under which the proxy shall be ran
proxyUID: 2102
# -- Group id under which the proxy shall be ran
proxyGID: 2102
# -- Directory on the host where the CNI plugin binaries reside
destCNINetDir: "/etc/cni/net.d"
# -- Directory on the host where the CNI configuration will be placed
Expand Down
1 change: 1 addition & 0 deletions charts/partials/templates/_network-validator.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ securityContext:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 65534
runAsNonRoot: true
runAsUser: 65534
seccompProfile:
Expand Down
4 changes: 4 additions & 0 deletions charts/partials/templates/_proxy-init.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ args:
- {{.Values.proxy.ports.outbound | quote}}
- --proxy-uid
- {{.Values.proxy.uid | quote}}
- --proxy-gid
- {{.Values.proxy.gid | quote}}
- --inbound-ports-to-ignore
- "{{.Values.proxy.ports.control}},{{.Values.proxy.ports.admin}}{{ternary (printf ",%s" (.Values.proxyInit.ignoreInboundPorts | toString)) "" (not (empty .Values.proxyInit.ignoreInboundPorts)) }}"
{{- if .Values.proxyInit.ignoreOutboundPorts }}
Expand Down Expand Up @@ -67,11 +69,13 @@ securityContext:
privileged: false
{{- end }}
{{- if .Values.proxyInit.runAsRoot }}
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
{{- else }}
runAsNonRoot: true
runAsUser: {{ .Values.proxyInit.runAsUser | int | eq 0 | ternary 65534 .Values.proxyInit.runAsUser }}
runAsGroup: {{ .Values.proxyInit.runAsGroup | int | eq 0 | ternary 65534 .Values.proxyInit.runAsGroup }}
{{- end }}
readOnlyRootFilesystem: true
seccompProfile:
Expand Down
1 change: 1 addition & 0 deletions charts/partials/templates/_proxy.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: {{.Values.proxy.uid}}
runAsGroup: {{.Values.proxy.gid}}
seccompProfile:
type: RuntimeDefault
terminationMessagePolicy: FallbackToLogsOnError
Expand Down
4 changes: 4 additions & 0 deletions cli/cmd/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ func generateAnnotationsDocs() []annotationDoc {
Name: k8s.ProxyUIDAnnotation,
Description: "Run the proxy under this user ID",
},
{
Name: k8s.ProxyGIDAnnotation,
Description: "Run the proxy under this group ID",
},
{
Name: k8s.ProxyLogLevelAnnotation,
Description: "Log level for the proxy",
Expand Down
4 changes: 4 additions & 0 deletions cli/cmd/inject.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ func getOverrideAnnotations(values *linkerd2.Values, base *linkerd2.Values) map[
overrideAnnotations[k8s.ProxyUIDAnnotation] = strconv.FormatInt(proxy.UID, 10)
}

if proxy.GID != baseProxy.GID {
overrideAnnotations[k8s.ProxyGIDAnnotation] = strconv.FormatInt(proxy.GID, 10)
}

if proxy.LogLevel != baseProxy.LogLevel {
overrideAnnotations[k8s.ProxyLogLevelAnnotation] = proxy.LogLevel
}
Expand Down
2 changes: 2 additions & 0 deletions cli/cmd/inject_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ func TestProxyConfigurationAnnotations(t *testing.T) {
values.Proxy.Ports.Inbound = 4144
values.Proxy.Ports.Outbound = 4141
values.Proxy.UID = 999
values.Proxy.GID = 999
values.Proxy.LogLevel = "debug"
values.Proxy.LogFormat = "cool"
values.Proxy.EnableExternalProfiles = true
Expand All @@ -701,6 +702,7 @@ func TestProxyConfigurationAnnotations(t *testing.T) {
k8s.ProxyInboundPortAnnotation: "4144",
k8s.ProxyOutboundPortAnnotation: "4141",
k8s.ProxyUIDAnnotation: "999",
k8s.ProxyGIDAnnotation: "999",
k8s.ProxyLogLevelAnnotation: "debug",
k8s.ProxyLogFormatAnnotation: "cool",

Expand Down
4 changes: 4 additions & 0 deletions cli/cmd/install-cni-plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type cniPluginOptions struct {
ignoreOutboundPorts []string
portsToRedirect []uint
proxyUID int64
proxyGID int64
image cniPluginImage
logLevel string
destCNINetDir string
Expand Down Expand Up @@ -120,6 +121,7 @@ The installation can be configured by using the --set, --values, --set-string an
cmd.PersistentFlags().StringVar(&options.dockerRegistry, "registry", options.dockerRegistry,
fmt.Sprintf("Docker registry to pull images from ($%s)", flags.EnvOverrideDockerRegistry))
cmd.PersistentFlags().Int64Var(&options.proxyUID, "proxy-uid", options.proxyUID, "Run the proxy under this user ID")
cmd.PersistentFlags().Int64Var(&options.proxyGID, "proxy-gid", options.proxyGID, "Run the proxy under this group ID")
cmd.PersistentFlags().UintVar(&options.inboundPort, "inbound-port", options.inboundPort, "Proxy port to use for inbound traffic")
cmd.PersistentFlags().UintVar(&options.outboundPort, "outbound-port", options.outboundPort, "Proxy port to use for outbound traffic")
cmd.PersistentFlags().UintVar(&options.proxyControlPort, "control-port", options.proxyControlPort, "Proxy port to use for control")
Expand Down Expand Up @@ -165,6 +167,7 @@ func newCNIInstallOptionsWithDefaults() (*cniPluginOptions, error) {
ignoreInboundPorts: nil,
ignoreOutboundPorts: nil,
proxyUID: defaults.ProxyUID,
proxyGID: defaults.ProxyGID,
image: cniPluginImage,
logLevel: "info",
destCNINetDir: defaults.DestCNINetDir,
Expand Down Expand Up @@ -203,6 +206,7 @@ func (options *cniPluginOptions) buildValues() (*cnicharts.Values, error) {
installValues.IgnoreOutboundPorts = strings.Join(options.ignoreOutboundPorts, ",")
installValues.PortsToRedirect = strings.Join(portsToRedirect, ",")
installValues.ProxyUID = options.proxyUID
installValues.ProxyGID = options.proxyGID
installValues.DestCNINetDir = options.destCNINetDir
installValues.DestCNIBinDir = options.destCNIBinDir
installValues.UseWaitFlag = options.useWaitFlag
Expand Down
3 changes: 3 additions & 0 deletions cli/cmd/install-cni-plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestRenderCNIPlugin(t *testing.T) {
ignoreInboundPorts: make([]string, 0),
ignoreOutboundPorts: make([]string, 0),
proxyUID: 12102,
proxyGID: 12102,
image: image,
logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d",
Expand All @@ -46,6 +47,7 @@ func TestRenderCNIPlugin(t *testing.T) {
ignoreInboundPorts: make([]string, 0),
ignoreOutboundPorts: make([]string, 0),
proxyUID: 12102,
proxyGID: 12102,
image: image,
logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d",
Expand All @@ -63,6 +65,7 @@ func TestRenderCNIPlugin(t *testing.T) {
ignoreInboundPorts: make([]string, 0),
ignoreOutboundPorts: make([]string, 0),
proxyUID: 12102,
proxyGID: 12102,
image: image,
logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d",
Expand Down
3 changes: 2 additions & 1 deletion cli/cmd/install_cni_helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestRenderCniHelm(t *testing.T) {
// override most defaults with pinned values.
// use the Helm lib to render the templates.
// the golden file is generated using the following `helm template` command:
// bin/helm template --set namespace="linkerd-test" --set inboundProxyPort=1234 --set outboundProxyPort=5678 --set cniPluginImage="cr.l5d.io/linkerd/cni-plugin-test" --set cniPluginVersion="test-version" --set logLevel="debug" --set proxyUID=1111 --set destCNINetDir="/etc/cni/net.d-test" --set destCNIBinDir="/opt/cni/bin-test" --set useWaitFlag=true --set cliVersion=test-version charts/linkerd2-cni
// bin/helm template --set namespace="linkerd-test" --set inboundProxyPort=1234 --set outboundProxyPort=5678 --set cniPluginImage="cr.l5d.io/linkerd/cni-plugin-test" --set cniPluginVersion="test-version" --set logLevel="debug" --set proxyUID=1111 --set proxyGID=1111 --set destCNINetDir="/etc/cni/net.d-test" --set destCNIBinDir="/opt/cni/bin-test" --set useWaitFlag=true --set cliVersion=test-version charts/linkerd2-cni

t.Run("Cni Install with defaults", func(t *testing.T) {
chartCni := chartCniPlugin(t)
Expand All @@ -38,6 +38,7 @@ func TestRenderCniHelm(t *testing.T) {
"version": "v1.4.0"
},
"proxyUID": 1111,
"proxyGID": 1111,
"destCNINetDir": "/etc/cni/net.d-test",
"destCNIBinDir": "/opt/cni/bin-test",
"useWaitFlag": true,
Expand Down
7 changes: 5 additions & 2 deletions cli/cmd/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestRender(t *testing.T) {
ControllerImage: "ControllerImage",
LinkerdVersion: "LinkerdVersion",
ControllerUID: 2103,
ControllerGID: 2103,
EnableH2Upgrade: true,
WebhookFailurePolicy: "WebhookFailurePolicy",
HeartbeatSchedule: "1 2 3 4 5",
Expand Down Expand Up @@ -97,6 +98,7 @@ func TestRender(t *testing.T) {
Outbound: 4140,
},
UID: 2102,
GID: 2102,
OpaquePorts: "25,443,587,3306,5432,11211",
Await: true,
DefaultInboundPolicy: "default-allow-policy",
Expand Down Expand Up @@ -131,8 +133,9 @@ func TestRender(t *testing.T) {
MountPath: "/run",
Name: "linkerd-proxy-init-xtables-lock",
},
RunAsRoot: false,
RunAsUser: 65534,
RunAsRoot: false,
RunAsUser: 65534,
RunAsGroup: 65534,
},
NetworkValidator: &charts.NetworkValidator{
LogLevel: "debug",
Expand Down
12 changes: 12 additions & 0 deletions cli/cmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ func makeInstallUpgradeFlags(defaults *l5dcharts.Values) ([]flag.Flag, *pflag.Fl
return nil
}),

flag.NewInt64Flag(installUpgradeFlags, "controller-gid", defaults.ControllerGID,
"Run the control plane components under this group ID", func(values *l5dcharts.Values, value int64) error {
values.ControllerGID = value
return nil
}),

flag.NewBoolFlag(installUpgradeFlags, "disable-h2-upgrade", !defaults.EnableH2Upgrade,
"Prevents the controller from instructing proxies to perform transparent HTTP/2 upgrading (default false)",
func(values *l5dcharts.Values, value bool) error {
Expand Down Expand Up @@ -313,6 +319,12 @@ func makeProxyFlags(defaults *l5dcharts.Values) ([]flag.Flag, *pflag.FlagSet) {
return nil
}),

flag.NewInt64Flag(proxyFlags, "proxy-gid", defaults.Proxy.GID, "Run the proxy under this group ID",
func(values *l5dcharts.Values, value int64) error {
values.Proxy.GID = value
return nil
}),

flag.NewStringFlag(proxyFlags, "proxy-log-level", defaults.Proxy.LogLevel, "Log level for the proxy",
func(values *l5dcharts.Values, value string) error {
values.Proxy.LogLevel = value
Expand Down
4 changes: 4 additions & 0 deletions cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ spec:
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsGroup: 2102
runAsNonRoot: true
runAsUser: 2102
seccompProfile:
Expand All @@ -177,6 +178,8 @@ spec:
- "4140"
- --proxy-uid
- "2102"
- --proxy-gid
- "2102"
- --inbound-ports-to-ignore
- 4190,4191,4567,4568
- --outbound-ports-to-ignore
Expand All @@ -199,6 +202,7 @@ spec:
- NET_RAW
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 65534
runAsNonRoot: true
runAsUser: 65534
seccompProfile:
Expand Down
Loading

0 comments on commit 4000715

Please sign in to comment.