CIS Linkerd Benchmark
Security configuration benchmark for Linkerd service mesh
v1.0.0 03-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for Linkerd. It covers mTLS enforcement, authorization policies, dashboard access control, proxy logging, resource limits, identity certificate management, service profiles, traffic splitting, and upgrade procedures.
| Section | Area | Focus |
|---|---|---|
| 1 | Installation & Identity | Version management, custom CA |
| 2 | mTLS & Authorization | Mutual TLS, authorization policies |
| 3 | Dashboard & RBAC | Viz access control, namespace RBAC |
| 4 | Logging & Observability | Proxy logs, Prometheus metrics |
| 5 | Traffic Management | Retry budgets, canary splits |
| 6 | Proxy Hardening | Resource limits, opaque ports |
| 7 | Maintenance & Upgrades | Health checks, cert rotation |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Linkerd deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Installation & Identity
▶1.1 Deployment & Trust Anchor
▶This recommendation verifies that Linkerd is running the latest stable version on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Linkerd version linkerd version linkerd check --pre
# Install latest Linkerd curl --proto '=https' -sL https://run.linkerd.io/install | sh linkerd install --crds | kubectl apply -f - linkerd install | kubectl apply -f - linkerd check
This recommendation verifies that custom trust anchor CA is configured on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Linkerd identity trust anchor linkerd check | grep -A2 identity kubectl get secret -n linkerd linkerd-identity-issuer -o yaml | grep -c 'tls.crt'
# Configure custom trust anchor CA step certificate create root.linkerd.cluster.local ca.crt ca.key --profile root-ca --no-password --insecure step certificate create identity.linkerd.cluster.local issuer.crt issuer.key --profile intermediate-ca --ca ca.crt --ca-key ca.key --no-password --insecure linkerd install --identity-trust-anchors-file ca.crt --identity-issuer-certificate-file issuer.crt --identity-issuer-key-file issuer.key | kubectl apply -f -
2 — mTLS & Authorization
▶2.1 Encryption & Policy
▶This recommendation ensures that mutual TLS is enforced for all meshed traffic on the Linkerd service mesh. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the Linkerd service mesh may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check mTLS is enabled linkerd viz stat deploy -n default linkerd viz edges deploy -n default | head -10
# Ensure mTLS is enforced # Inject Linkerd proxy into deployments: kubectl get deploy -n default -o yaml | linkerd inject - | kubectl apply -f - # Verify mTLS: linkerd viz stat deploy -n default # All traffic should show 100% meshed
This recommendation verifies that authorization policies restrict service access on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check authorization policies kubectl get authorizationpolicies -A kubectl get serverauthorizations -A kubectl get servers -A
# Configure authorization policies
apiVersion: policy.linkerd.io/v1beta2
kind: Server
metadata:
name: web-server
namespace: default
spec:
podSelector:
matchLabels:
app: web
port: 8080
---
apiVersion: policy.linkerd.io/v1beta2
kind: AuthorizationPolicy
metadata:
name: web-authz
spec:
targetRef:
group: policy.linkerd.io
kind: Server
name: web-server
requiredAuthenticationRefs:
- name: web-clients
kind: MeshTLSAuthentication3 — Dashboard & RBAC
▶3.1 Viz Access & Permissions
▶This recommendation verifies that dashboard is not publicly exposed without authentication on the Linkerd service mesh. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.
Running unnecessary components on the Linkerd service mesh increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.
# Check Linkerd Viz dashboard access kubectl get svc -n linkerd-viz kubectl get ingress -n linkerd-viz 2>/dev/null
# Restrict dashboard access # Do NOT expose dashboard without auth # Use port-forward for local access: # linkerd viz dashboard & # If exposing via ingress, add auth: # nginx.ingress.kubernetes.io/auth-type: basic # nginx.ingress.kubernetes.io/auth-secret: linkerd-dashboard-auth
This recommendation verifies that RBAC restricts access to Linkerd namespaces on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check RBAC for Linkerd namespaces kubectl get rolebindings,clusterrolebindings -A | grep linkerd
# Restrict Linkerd namespace access apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: linkerd-readonly rules: - apiGroups: ["linkerd.io"] resources: ["*"] verbs: ["get", "list", "watch"] --- # Bind to specific groups only
4 — Logging & Observability
▶4.1 Proxy Logs & Metrics
▶This recommendation verifies that proxy log levels are appropriately configured on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check proxy log level kubectl get deploy -n linkerd -o yaml | grep -E 'LINKERD2_PROXY_LOG|log-level'
# Configure proxy logging
# Set proxy log level via annotation:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.linkerd.io/proxy-log-level: "warn,linkerd=info"
# For control plane:
linkerd install --set proxyLogLevel=warn,linkerd=info | kubectl apply -f -This recommendation verifies that monitoring with alerting is configured on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Linkerd Viz metrics linkerd viz stat deploy -A | head -20 kubectl get prometheusrules -n linkerd-viz 2>/dev/null
# Configure monitoring and alerting # Ensure Viz extension is installed: linkerd viz install | kubectl apply -f - # Export metrics to external Prometheus: # linkerd viz install --set prometheusUrl=http://prometheus:9090 | kubectl apply -f - # Set up alerts for: # - High error rates (>1%) # - High latency (p99 > 500ms) # - Proxy injection failures
5 — Traffic Management
▶5.1 Retries & Splitting
▶This recommendation verifies that service profiles define timeouts and retry budgets on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check retry and timeout configuration kubectl get serviceprofiles -A kubectl get httproutes -A 2>/dev/null
# Configure service profiles for retries/timeouts
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: web.default.svc.cluster.local
spec:
routes:
- name: "GET /api"
condition:
method: GET
pathRegex: "/api/.*"
timeout: 5s
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 10sThis recommendation verifies that traffic splitting is used for safe deployments on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check traffic split configuration kubectl get trafficsplits -A 2>/dev/null
# Configure traffic management
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: web-canary
spec:
service: web
backends:
- service: web-stable
weight: 900
- service: web-canary
weight: 1006 — Proxy Hardening
▶6.1 Resources & Ports
▶This recommendation verifies that proxy resource limits are configured on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check proxy resource limits kubectl get deploy -n default -o yaml | grep -A5 'proxy-cpu\|proxy-memory'
# Set proxy resource limits
# Via annotations:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.linkerd.io/proxy-cpu-request: "100m"
config.linkerd.io/proxy-cpu-limit: "500m"
config.linkerd.io/proxy-memory-request: "128Mi"
config.linkerd.io/proxy-memory-limit: "256Mi"This recommendation verifies that opaque ports are configured for non-HTTP traffic on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check opaque ports kubectl get deploy -n default -o yaml | grep 'opaque-ports'
# Configure opaque ports for non-HTTP traffic
# Via annotation:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.linkerd.io/opaque-ports: "3306,6379,27017"
# This ensures mTLS is applied to non-HTTP protocols7 — Maintenance & Upgrades
▶7.1 Health & Rotation
▶This recommendation verifies that all health checks pass including certificate validity on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Run Linkerd health checks linkerd check linkerd check --proxy -n default
# Ensure all health checks pass
linkerd check
# Fix certificate rotation before expiry:
linkerd identity
# Check certificate expiry:
kubectl get secret linkerd-identity-issuer -n linkerd -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -datesThis recommendation verifies that Linkerd and extensions are regularly updated on the Linkerd service mesh. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Linkerd service mesh vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Linkerd extensions linkerd check --extensions
# Update Linkerd and extensions linkerd upgrade | kubectl apply -f - linkerd viz install | kubectl apply -f - linkerd check # Rotate identity certificates annually: step certificate create root.linkerd.cluster.local ca.crt ca.key --profile root-ca --not-after=8760h