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

fix(MeshTrafficPermission): support permissive mtls #8171

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v1alpha1
import (
envoy_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_resource "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"

mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1"
"github.com/kumahq/kuma/pkg/core"
Expand Down Expand Up @@ -82,6 +83,10 @@ func (p plugin) Apply(rs *core_xds.ResourceSet, ctx xds_context.Context, proxy *
Mesh: proxy.Dataplane.GetMeta().GetMesh(),
}
for _, filterChain := range listener.FilterChains {
if filterChain.TransportSocket.GetName() != wellknown.TransportSocketTLS {
// we only want to configure RBAC on listeners protected by Kuma's TLS
continue
}
if err := configurer.Configure(filterChain); err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/kumahq/kuma/pkg/test/matchers"
"github.com/kumahq/kuma/pkg/test/resources/builders"
test_model "github.com/kumahq/kuma/pkg/test/resources/model"
"github.com/kumahq/kuma/pkg/test/resources/samples"
util_proto "github.com/kumahq/kuma/pkg/util/proto"
xds_context "github.com/kumahq/kuma/pkg/xds/context"
"github.com/kumahq/kuma/pkg/xds/envoy"
Expand All @@ -30,11 +31,17 @@ var _ = Describe("RBAC", func() {
It("should enrich matching listener with RBAC filter", func() {
// given
rs := core_xds.NewResourceSet()
ctx := xds_context.Context{
Mesh: xds_context.MeshContext{
Resource: samples.MeshMTLSBuilder().WithName("mesh-1").Build(),
},
}

// listener that matches
listener, err := listeners.NewInboundListenerBuilder(envoy.APIV3, "192.168.0.1", 8080, core_xds.SocketAddressProtocolTCP).
WithOverwriteName("test_listener").
Configure(listeners.FilterChain(listeners.NewFilterChainBuilder(envoy.APIV3, envoy.AnonymousResource).
Configure(listeners.ServerSideMTLS(ctx.Mesh.Resource, envoy.NewSecretsTracker(ctx.Mesh.Resource.Meta.GetName(), nil))).
Configure(listeners.HttpConnectionManager("test_listener", false)))).
Build()
Expect(err).ToNot(HaveOccurred())
Expand All @@ -48,6 +55,7 @@ var _ = Describe("RBAC", func() {
listener2, err := listeners.NewInboundListenerBuilder(envoy.APIV3, "192.168.0.1", 8081, core_xds.SocketAddressProtocolTCP).
WithOverwriteName("test_listener2").
Configure(listeners.FilterChain(listeners.NewFilterChainBuilder(envoy.APIV3, envoy.AnonymousResource).
Configure(listeners.ServerSideMTLS(ctx.Mesh.Resource, envoy.NewSecretsTracker(ctx.Mesh.Resource.Meta.GetName(), nil))).
Configure(listeners.HttpConnectionManager("test_listener2", false)))).
Build()
Expect(err).ToNot(HaveOccurred())
Expand All @@ -61,6 +69,7 @@ var _ = Describe("RBAC", func() {
listener3, err := listeners.NewInboundListenerBuilder(envoy.APIV3, "192.168.0.1", 8082, core_xds.SocketAddressProtocolTCP).
WithOverwriteName("test_listener3").
Configure(listeners.FilterChain(listeners.NewFilterChainBuilder(envoy.APIV3, envoy.AnonymousResource).
Configure(listeners.ServerSideMTLS(ctx.Mesh.Resource, envoy.NewSecretsTracker(ctx.Mesh.Resource.Meta.GetName(), nil))).
Configure(listeners.HttpConnectionManager("test_listener3", false)))).
Build()
Expect(err).ToNot(HaveOccurred())
Expand All @@ -70,25 +79,18 @@ var _ = Describe("RBAC", func() {
Resource: listener3,
})

// mesh with enabled mTLS
ctx := xds_context.Context{
Mesh: xds_context.MeshContext{
Resource: &mesh.MeshResource{
Meta: &test_model.ResourceMeta{Name: "mesh-1", Mesh: core_model.NoMesh},
Spec: &mesh_proto.Mesh{
Mtls: &mesh_proto.Mesh_Mtls{
EnabledBackend: "builtin-1",
Backends: []*mesh_proto.CertificateAuthorityBackend{
{
Name: "builtin-1",
Type: "builtin",
},
},
},
},
},
},
}
// listener that matches but it does not have mTLS
listener4, err := listeners.NewInboundListenerBuilder(envoy.APIV3, "192.168.0.1", 8083, core_xds.SocketAddressProtocolTCP).
WithOverwriteName("test_listener4").
Configure(listeners.FilterChain(listeners.NewFilterChainBuilder(envoy.APIV3, envoy.AnonymousResource).
Configure(listeners.HttpConnectionManager("test_listener", false)))).
Build()
Expect(err).ToNot(HaveOccurred())
rs.Add(&core_xds.Resource{
Name: listener4.GetName(),
Origin: generator.OriginInbound,
Resource: listener4,
})

proxy := &core_xds.Proxy{
Dataplane: &mesh.DataplaneResource{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ resources:
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: test_listener
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
combinedValidationContext:
defaultValidationContext:
matchTypedSubjectAltNames:
- matcher:
prefix: spiffe://mesh-1/
sanType: URI
validationContextSdsSecretConfig:
name: mesh_ca:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
tlsCertificateSdsSecretConfigs:
- name: identity_cert:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
requireClientCertificate: true
name: test_listener
trafficDirection: INBOUND
- name: test_listener2
Expand All @@ -50,6 +72,28 @@ resources:
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: test_listener2
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
combinedValidationContext:
defaultValidationContext:
matchTypedSubjectAltNames:
- matcher:
prefix: spiffe://mesh-1/
sanType: URI
validationContextSdsSecretConfig:
name: mesh_ca:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
tlsCertificateSdsSecretConfigs:
- name: identity_cert:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
requireClientCertificate: true
name: test_listener2
trafficDirection: INBOUND
- name: test_listener3
Expand All @@ -70,5 +114,47 @@ resources:
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: test_listener3
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
combinedValidationContext:
defaultValidationContext:
matchTypedSubjectAltNames:
- matcher:
prefix: spiffe://mesh-1/
sanType: URI
validationContextSdsSecretConfig:
name: mesh_ca:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
tlsCertificateSdsSecretConfigs:
- name: identity_cert:secret:mesh-1
sdsConfig:
ads: {}
resourceApiVersion: V3
requireClientCertificate: true
name: test_listener3
trafficDirection: INBOUND
- name: test_listener4
resource:
'@type': type.googleapis.com/envoy.config.listener.v3.Listener
address:
socketAddress:
address: 192.168.0.1
portValue: 8083
enableReusePort: false
filterChains:
- filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
statPrefix: test_listener
name: test_listener4
trafficDirection: INBOUND
7 changes: 7 additions & 0 deletions pkg/test/resources/builders/mesh_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ func (m *MeshBuilder) WithoutMTLSBackends() *MeshBuilder {
return m
}

func (m *MeshBuilder) WithPermissiveMTLSBackends() *MeshBuilder {
for _, backend := range m.res.Spec.Mtls.Backends {
backend.Mode = mesh_proto.CertificateAuthorityBackend_PERMISSIVE
}
return m
}

func (m *MeshBuilder) AddBuiltinMTLSBackend(name string) *MeshBuilder {
if m.res.Spec.Mtls == nil {
m.res.Spec.Mtls = &mesh_proto.Mesh_Mtls{}
Expand Down
14 changes: 9 additions & 5 deletions pkg/xds/generator/inbound_proxy_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ func (g InboundProxyGenerator) Generate(ctx context.Context, xdsCtx xds_context.
Configure(envoy_listeners.ServerSideMTLS(xdsCtx.Mesh.Resource, proxy.SecretsTracker))
}
return filterChainBuilder.
Configure(envoy_listeners.Timeout(defaults_mesh.DefaultInboundTimeout(), protocol)).
Configure(envoy_listeners.NetworkRBAC(inboundListenerName, xdsCtx.Mesh.Resource.MTLSEnabled(),
proxy.Policies.TrafficPermissions[endpoint]))
Configure(envoy_listeners.Timeout(defaults_mesh.DefaultInboundTimeout(), protocol))
}

listenerBuilder := envoy_listeners.NewInboundListenerBuilder(proxy.APIVersion, endpoint.DataplaneIP, endpoint.DataplanePort, core_xds.SocketAddressProtocolTCP).
Expand All @@ -137,7 +135,9 @@ func (g InboundProxyGenerator) Generate(ctx context.Context, xdsCtx xds_context.
switch xdsCtx.Mesh.Resource.GetEnabledCertificateAuthorityBackend().GetMode() {
case mesh_proto.CertificateAuthorityBackend_STRICT:
listenerBuilder.
Configure(envoy_listeners.FilterChain(filterChainBuilder(true)))
Configure(envoy_listeners.FilterChain(filterChainBuilder(true).Configure(
envoy_listeners.NetworkRBAC(inboundListenerName, xdsCtx.Mesh.Resource.MTLSEnabled(), proxy.Policies.TrafficPermissions[endpoint]),
)))
case mesh_proto.CertificateAuthorityBackend_PERMISSIVE:
listenerBuilder.
Configure(envoy_listeners.TLSInspector()).
Expand All @@ -146,13 +146,17 @@ func (g InboundProxyGenerator) Generate(ctx context.Context, xdsCtx xds_context.
envoy_listeners.MatchTransportProtocol("raw_buffer"))),
).
Configure(envoy_listeners.FilterChain(
// we need to differentiate between just TLS and Kuma's TLS, because with permissive mode
// the app itself might be protected by TLS.
filterChainBuilder(false).Configure(
envoy_listeners.MatchTransportProtocol("tls"))),
).
Configure(envoy_listeners.FilterChain(
filterChainBuilder(true).Configure(
envoy_listeners.MatchTransportProtocol("tls"),
envoy_listeners.MatchApplicationProtocols(xds_tls.KumaALPNProtocols...))),
envoy_listeners.MatchApplicationProtocols(xds_tls.KumaALPNProtocols...),
envoy_listeners.NetworkRBAC(inboundListenerName, xdsCtx.Mesh.Resource.MTLSEnabled(), proxy.Policies.TrafficPermissions[endpoint]),
)),
)
default:
return nil, errors.New("unknown mode for CA backend")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ resources:
- filterChainMatch:
transportProtocol: raw_buffer
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_1_443.
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
Expand All @@ -64,11 +59,6 @@ resources:
- filterChainMatch:
transportProtocol: tls
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_1_443.
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
Expand Down Expand Up @@ -135,24 +125,6 @@ resources:
- filterChainMatch:
transportProtocol: raw_buffer
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules:
policies:
tp-1:
permissions:
- any: true
principals:
- andIds:
ids:
- authenticated:
principalName:
exact: kuma://version/1.0
- authenticated:
principalName:
exact: spiffe://default/web1
statPrefix: inbound_192_168_0_1_80.
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
Expand Down Expand Up @@ -260,24 +232,6 @@ resources:
- filterChainMatch:
transportProtocol: tls
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules:
policies:
tp-1:
permissions:
- any: true
principals:
- andIds:
ids:
- authenticated:
principalName:
exact: kuma://version/1.0
- authenticated:
principalName:
exact: spiffe://default/web1
statPrefix: inbound_192_168_0_1_80.
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
Expand Down Expand Up @@ -554,11 +508,6 @@ resources:
- filterChainMatch:
transportProtocol: raw_buffer
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_2_443.
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
Expand All @@ -568,11 +517,6 @@ resources:
- filterChainMatch:
transportProtocol: tls
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_2_443.
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
Expand Down Expand Up @@ -639,11 +583,6 @@ resources:
- filterChainMatch:
transportProtocol: raw_buffer
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_2_80.
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
Expand Down Expand Up @@ -676,11 +615,6 @@ resources:
- filterChainMatch:
transportProtocol: tls
filters:
- name: envoy.filters.network.rbac
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules: {}
statPrefix: inbound_192_168_0_2_80.
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
Expand Down
Loading