Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experimental] Use privileged dataplane entrypoint for ingress-gateway #4394

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
25 changes: 25 additions & 0 deletions charts/consul/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,33 @@ securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
{{- if not .Values.global.openshift.enabled -}}
{{/*
We must set runAsUser or else the root user will be used in some cases and
containers will fail to start due to runAsNonRoot above (e.g.
tls-init-cleanup). On OpenShift, runAsUser is automatically. We pick user 100
because it is a non-root user id that exists in the consul, consul-dataplane,
and consul-k8s-control-plane images.
*/}}
runAsUser: 100
{{- end -}}
{{- end -}}
{{- end -}}


{{- define "consul.restrictedSecurityContextWithNetBindService" -}}
{{- if not .Values.global.enablePodSecurityPolicies -}}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
Expand Down
9 changes: 7 additions & 2 deletions charts/consul/templates/ingress-gateways-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ spec:
- name: ingress-gateway
image: {{ $root.Values.global.imageConsulDataplane | quote }}
{{ template "consul.imagePullPolicy" $root }}
{{- include "consul.restrictedSecurityContext" $ | nindent 8 }}
{{- include "consul.restrictedSecurityContextWithNetBindService" $ | nindent 8 }}
{{- if (default $defaults.resources .resources) }}
resources: {{ toYaml (default $defaults.resources .resources) | nindent 10 }}
{{- end }}
Expand Down Expand Up @@ -291,9 +291,14 @@ spec:
value: component=ingress-gateway
- name: DP_SERVICE_NODE_NAME
value: $(NODE_NAME)-virtual
{{- if $root.Values.ingressGateways.supportPrivilegedPorts }}
command:
- consul-dataplane
- privileged-consul-dataplane
args:
- -envoy-executable-path=/usr/local/bin/privileged-envoy
{{- else }}
args:
{{- end }}
- -envoy-ready-bind-port=21000
{{- if $root.Values.externalServers.enabled }}
- -addresses={{ $root.Values.externalServers.hosts | first }}
Expand Down
6 changes: 2 additions & 4 deletions charts/consul/templates/mesh-gateway-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,12 @@ spec:
- name: mesh-gateway
image: {{ .Values.global.imageConsulDataplane | quote }}
{{ template "consul.imagePullPolicy" . }}
{{ if not .Values.meshGateway.hostNetwork}}
securityContext:
capabilities:
{{ if not .Values.meshGateway.hostNetwork}}
drop:
- ALL
{{- end }}
add:
- NET_BIND_SERVICE
{{- end }}
{{- if .Values.meshGateway.resources }}
resources:
{{- if eq (typeOf .Values.meshGateway.resources) "string" }}
Expand Down
2 changes: 0 additions & 2 deletions charts/consul/templates/mesh-gateway-podsecuritypolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ spec:
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
defaultAddCapabilities:
- NET_BIND_SERVICE
# Allow core volume types.
volumes:
- 'configMap'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ spec:
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
defaultAddCapabilities:
- NET_BIND_SERVICE
# Allow core volume types.
volumes:
- 'configMap'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ spec:
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
defaultAddCapabilities:
- NET_BIND_SERVICE
# Allow core volume types.
volumes:
- 'configMap'
Expand Down
2 changes: 0 additions & 2 deletions charts/consul/test/unit/server-statefulset.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,6 @@ load _helpers
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": ["ALL"],
"add": ["NET_BIND_SERVICE"]
},
"readOnlyRootFilesystem": true,
"runAsNonRoot": true,
Expand Down Expand Up @@ -1416,7 +1415,6 @@ load _helpers
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": ["ALL"],
"add": ["NET_BIND_SERVICE"]
},
"readOnlyRootFilesystem": true,
"runAsNonRoot": true,
Expand Down
5 changes: 5 additions & 0 deletions charts/consul/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3217,6 +3217,11 @@ ingressGateways:
# @type: string
logLevel: ""

# When set, ingress-gateway containers use a privileged entrypoint in consul-dataplane which requires the
# NET_BIND_SERVICE capability at runtime. Disabling this setting will use the non-privileged entrypoint and
# drop the requirement for NET_BIND_SERVICE. Only disable this if you are *not* using privileged ports (< 1024).
supportPrivilegedPorts: true

# Defaults sets default values for all gateway fields. With the exception
# of annotations, defining any of these values in the `gateways` list
# will override the default values provided here. Annotations will
Expand Down
3 changes: 0 additions & 3 deletions control-plane/api-gateway/gatekeeper/dataplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

const (
allCapabilities = "ALL"
netBindCapability = "NET_BIND_SERVICE"
consulDataplaneDNSBindHost = "127.0.0.1"
consulDataplaneDNSBindPort = 8600
defaultEnvoyProxyConcurrency = 1
Expand Down Expand Up @@ -114,9 +113,7 @@ func consulDataplaneContainer(metrics common.MetricsConfig, config common.HelmCo
// otherwise, allow the user to be assigned by OpenShift.
container.SecurityContext = &corev1.SecurityContext{
ReadOnlyRootFilesystem: ptr.To(true),
// Drop any Linux capabilities you'd get as root other than NET_BIND_SERVICE.
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{netBindCapability},
Drop: []corev1.Capability{allCapabilities},
},
}
Expand Down
4 changes: 1 addition & 3 deletions control-plane/api-gateway/gatekeeper/gatekeeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1506,8 +1506,7 @@ func validateResourcesExist(t *testing.T, client client.Client, helmConfig commo
}
assert.True(t, hasInitContainer)

// Ensure there is a consul-dataplane container dropping ALL capabilities, adding
// back the NET_BIND_SERVICE capability, and establishing a read-only root filesystem
// Ensure there is a consul-dataplane container dropping ALL capabilities and establishing a read-only root filesystem
hasDataplaneContainer := false
for _, container := range actual.Spec.Template.Spec.Containers {
if container.Image == dataplaneImage {
Expand All @@ -1516,7 +1515,6 @@ func validateResourcesExist(t *testing.T, client client.Client, helmConfig commo
require.NotNil(t, container.SecurityContext.Capabilities)
require.NotNil(t, container.SecurityContext.ReadOnlyRootFilesystem)
assert.True(t, *container.SecurityContext.ReadOnlyRootFilesystem)
assert.Equal(t, []corev1.Capability{netBindCapability}, container.SecurityContext.Capabilities.Add)
assert.Equal(t, []corev1.Capability{allCapabilities}, container.SecurityContext.Capabilities.Drop)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
"strings"

"github.com/google/shlex"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/common"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"

"github.com/hashicorp/consul-k8s/control-plane/connect-inject/common"
"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
)

const (
Expand Down Expand Up @@ -264,12 +265,7 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor
RunAsGroup: ptr.To(group),
RunAsNonRoot: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
// consul-dataplane requires the NET_BIND_SERVICE capability regardless of binding port #.
// See https://developer.hashicorp.com/consul/docs/connect/dataplane#technical-constraints
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_BIND_SERVICE"},
},
ReadOnlyRootFilesystem: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
}
return container, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -807,9 +807,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) {
RunAsNonRoot: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_BIND_SERVICE"},
},
},
},
"tproxy enabled; openshift disabled": {
Expand All @@ -821,9 +818,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) {
RunAsNonRoot: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_BIND_SERVICE"},
},
},
},
"tproxy disabled; openshift enabled": {
Expand All @@ -835,9 +829,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) {
RunAsNonRoot: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_BIND_SERVICE"},
},
},
},
"tproxy enabled; openshift enabled": {
Expand All @@ -849,9 +840,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) {
RunAsNonRoot: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_BIND_SERVICE"},
},
},
},
}
Expand Down
Loading