diff --git a/connectivity/check/features.go b/connectivity/check/features.go index 6e9aa4513d..7bfe492a03 100644 --- a/connectivity/check/features.go +++ b/connectivity/check/features.go @@ -59,6 +59,8 @@ const ( FeatureCNP Feature = "cilium-network-policy" FeatureKNP Feature = "k8s-network-policy" + + FeatureAuthMTLSSpiffe Feature = "auth-mtls-spiffe" ) // FeatureStatus describes the status of a feature. Some features are either @@ -199,6 +201,10 @@ func (ct *ConnectivityTest) extractFeaturesFromConfigMap(ctx context.Context, cl Enabled: cm.Data["enable-endpoint-routes"] == "true", } + result[FeatureAuthMTLSSpiffe] = FeatureStatus{ + Enabled: cm.Data["mesh-auth-mtls-enabled"] == "true", + } + return nil } diff --git a/connectivity/check/policy.go b/connectivity/check/policy.go index 75156fe4b5..f9c30d2c80 100644 --- a/connectivity/check/policy.go +++ b/connectivity/check/policy.go @@ -202,6 +202,10 @@ func defaultDenyReason(flow *flowpb.Flow) bool { return flow.GetDropReasonDesc() == flowpb.DropReason_POLICY_DENIED } +func authRequiredDropReason(flow *flowpb.Flow) bool { + return flow.GetDropReasonDesc() == flowpb.DropReason_AUTH_REQUIRED +} + var ( // ResultNone expects a successful command, don't match any packets. ResultNone = Result{ @@ -248,6 +252,12 @@ var ( DropReasonFunc: defaultDropReason, } + // ResultDropAuthRequired expects a dropped flow with auth required as reason. + ResultDropAuthRequired = Result{ + Drop: true, + DropReasonFunc: authRequiredDropReason, + } + // ResultAnyReasonEgressDrop expects a dropped flow at Egress and a failed command. ResultAnyReasonEgressDrop = Result{ Drop: true, diff --git a/connectivity/manifests/echo-ingress-auth-fail.yaml b/connectivity/manifests/echo-ingress-auth-fail.yaml new file mode 100644 index 0000000000..7b4389598f --- /dev/null +++ b/connectivity/manifests/echo-ingress-auth-fail.yaml @@ -0,0 +1,21 @@ + +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: auth-ingress-fail + namespace: cilium-test +spec: + description: "Allow other client to contact echo but fail on auth" + endpointSelector: + matchLabels: + kind: echo + ingress: + - fromEndpoints: + - matchLabels: + kind: client + toPorts: + - ports: + - port: "8080" + protocol: TCP + auth: + type: always-fail diff --git a/connectivity/manifests/echo-ingress-mtls.yaml b/connectivity/manifests/echo-ingress-mtls.yaml new file mode 100644 index 0000000000..3b3f22317c --- /dev/null +++ b/connectivity/manifests/echo-ingress-mtls.yaml @@ -0,0 +1,21 @@ + +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: auth-ingress + namespace: cilium-test +spec: + description: "Allow other client to contact echo after mTLS" + endpointSelector: + matchLabels: + kind: echo + ingress: + - fromEndpoints: + - matchLabels: + kind: client + toPorts: + - ports: + - port: "8080" + protocol: TCP + auth: + type: mtls-spiffe diff --git a/connectivity/suite.go b/connectivity/suite.go index dae890c760..a3facf6efa 100644 --- a/connectivity/suite.go +++ b/connectivity/suite.go @@ -135,6 +135,12 @@ var ( //go:embed manifests/echo-ingress-icmp-deny.yaml echoIngressICMPDenyPolicyYAML string + + //go:embed manifests/echo-ingress-auth-fail.yaml + echoIngressAuthFailPolicyYAML string + + //go:embed manifests/echo-ingress-mtls.yaml + echoIngressMTLSPolicyYAML string ) var ( @@ -824,6 +830,27 @@ func Run(ctx context.Context, ct *check.ConnectivityTest) error { return check.ResultCurlHTTPError, check.ResultNone // if the header is not set the request will get a 401 }) + // Test mTLS auth with always-fail + ct.NewTest("echo-ingress-auth-always-fail").WithCiliumPolicy(echoIngressAuthFailPolicyYAML). + // this test is only useful when auth is supported in the Cilium version and it is enabled + // currently this is tested my mtls-spiffe as that is the only functional auth method + WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureAuthMTLSSpiffe)). + WithScenarios( + tests.PodToPod(), + tests.PodToPodWithEndpoints(), + ). + WithExpectations(func(a *check.Action) (egress, ingress check.Result) { + return check.ResultDropCurlTimeout, check.ResultDropAuthRequired + }) + + // Test mTLS auth with SPIFFE + ct.NewTest("echo-ingress-auth-mtls-spiffe").WithCiliumPolicy(echoIngressMTLSPolicyYAML). + WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureAuthMTLSSpiffe)). + WithScenarios( + tests.PodToPod(), + tests.PodToPodWithEndpoints(), + ) + // Only allow UDP:53 to kube-dns, no DNS proxy enabled. ct.NewTest("dns-only").WithCiliumPolicy(clientEgressOnlyDNSPolicyYAML). WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureL7Proxy)).