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

chore(*) ExternalServices add CA and Client certificate support #1094

Merged
merged 26 commits into from
Nov 12, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
34b6fe1
chore(*) add CA and Client certificate support code
Oct 19, 2020
c2f8bf9
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 20, 2020
8ace4b5
feat(*) push ExternalService TLS config to Envoy
Oct 20, 2020
1ac997d
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 21, 2020
44d4a63
fix(*) tests
Oct 21, 2020
b14eaa5
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 22, 2020
e685596
fix(*) review
Oct 22, 2020
d07dee2
chore(*) move tls.go and fix for review
Oct 23, 2020
5173c84
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 23, 2020
f5b3d7c
chore(*) update UpstreamTlsContextOutsideMesh
Oct 23, 2020
25bf408
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 23, 2020
8c8d3a0
test(*) e2e for TLS certs
Oct 26, 2020
136eae2
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Oct 30, 2020
1bfe9db
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 2, 2020
a6665b6
fix(*) improve e2e
Nov 2, 2020
53a65d4
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 4, 2020
0ff0123
fix(*) load certificates at BuildEndpointMap
Nov 4, 2020
7c71513
fix(*) have a proper ca_cert thest for ExternalServices
Nov 4, 2020
ccb1766
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 6, 2020
71195ec
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 9, 2020
8d9392e
fix(*) fix review
Nov 9, 2020
45f0086
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 11, 2020
3c2e281
fix(*) review
Nov 11, 2020
2b4ce22
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 11, 2020
355966a
Merge remote-tracking branch 'origin/master' into chore/tls_origination
Nov 12, 2020
eba5a17
fix(*) e2e after upgrading to Ubuntu
Nov 12, 2020
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
82 changes: 58 additions & 24 deletions api/mesh/v1alpha1/externalservice.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions api/mesh/v1alpha1/externalservice.pb.validate.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion api/mesh/v1alpha1/externalservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ option go_package = "v1alpha1";

import "validate/validate.proto";

import "system/v1alpha1/datasource.proto";

// ExternalService defines configuration of the externaly accessible service
message ExternalService {

Expand All @@ -18,6 +20,15 @@ message ExternalService {
message TLS {
// denotes that the external service uses TLS
bool enabled = 1;

// Data source for the certificate of CA
kuma.system.v1alpha1.DataSource ca_cert = 2;

// Data source for the authentication
kuma.system.v1alpha1.DataSource client_cert = 3;

// Data source for the authentication
kuma.system.v1alpha1.DataSource client_key = 4;
}

TLS tls = 2;
Expand All @@ -27,5 +38,5 @@ message ExternalService {

// Tags associated with the external service,
// e.g. kuma.io/service=web, kuma.io/protocol, version=1.0.
map<string, string> tags = 3 [ (validate.rules).map.min_pairs = 1 ];
map<string, string> tags = 2 [ (validate.rules).map.min_pairs = 1 ];
}
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
Expand Down Expand Up @@ -1202,6 +1204,7 @@ google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
1 change: 1 addition & 0 deletions pkg/core/runtime/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func (b *Builder) Build() (Runtime, error) {
ss: b.ss,
cam: b.cam,
xds: b.xds,
dsl: b.dsl,
ext: b.ext,
dns: b.dns,
configm: b.configm,
Expand Down
7 changes: 7 additions & 0 deletions pkg/core/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package runtime
import (
"context"

"github.com/kumahq/kuma/pkg/core/datasource"

"github.com/kumahq/kuma/pkg/core/dns/lookup"
"github.com/kumahq/kuma/pkg/core/secrets/store"
"github.com/kumahq/kuma/pkg/metrics"
Expand Down Expand Up @@ -36,6 +38,7 @@ type RuntimeInfo interface {
type RuntimeContext interface {
Config() kuma_cp.Config
XDS() core_xds.XdsContext
DataSourceLoader() datasource.Loader
ResourceManager() core_manager.ResourceManager
ResourceStore() core_store.ResourceStore
ReadOnlyResourceManager() core_manager.ReadOnlyResourceManager
Expand Down Expand Up @@ -88,6 +91,7 @@ type runtimeContext struct {
rom core_manager.ReadOnlyResourceManager
cam ca.Managers
xds core_xds.XdsContext
dsl datasource.Loader
ext context.Context
dns dns.DNSResolver
configm config_manager.ConfigManager
Expand All @@ -109,6 +113,9 @@ func (rc *runtimeContext) Config() kuma_cp.Config {
func (rc *runtimeContext) XDS() core_xds.XdsContext {
return rc.xds
}
func (rc *runtimeContext) DataSourceLoader() datasource.Loader {
return rc.dsl
}
func (rc *runtimeContext) ResourceManager() core_manager.ResourceManager {
return rc.rm
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/core/xds/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type DestinationMap map[ServiceName]TagSelectorSet

type ExternalService struct {
TLSEnabled bool
CaCert []byte
ClientCert []byte
ClientKey []byte
}

// Endpoint holds routing-related information about a single endpoint.
Expand Down
7 changes: 6 additions & 1 deletion pkg/xds/cache/cla/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"time"

"github.com/kumahq/kuma/pkg/core/datasource"

"github.com/prometheus/client_golang/prometheus"

"github.com/kumahq/kuma/pkg/metrics"
Expand Down Expand Up @@ -32,6 +34,7 @@ var (
type Cache struct {
cache *cache.Cache
rm manager.ReadOnlyResourceManager
dsl datasource.Loader
ipFunc lookup.LookupIPFunc
zone string
onceMap *once.Map
Expand All @@ -40,6 +43,7 @@ type Cache struct {

func NewCache(
rm manager.ReadOnlyResourceManager,
dsl datasource.Loader,
zone string, expirationTime time.Duration,
ipFunc lookup.LookupIPFunc,
metrics metrics.Metrics,
Expand All @@ -54,6 +58,7 @@ func NewCache(
return &Cache{
cache: cache.New(expirationTime, time.Duration(int64(float64(expirationTime)*0.9))),
rm: rm,
dsl: dsl,
zone: zone,
ipFunc: ipFunc,
onceMap: once.NewMap(),
Expand Down Expand Up @@ -85,7 +90,7 @@ func (c *Cache) GetCLA(ctx context.Context, meshName, service string) (*envoy_ap
if err := c.rm.List(ctx, externalServices, core_store.ListByMesh(meshName)); err != nil {
return nil, err
}
endpointMap := topology.BuildEndpointMap(dataplanes.Items, c.zone, mesh, externalServices.Items)
endpointMap := topology.BuildEndpointMap(mesh, c.zone, dataplanes.Items, externalServices.Items, c.dsl)
cla := endpoints.CreateClusterLoadAssignment(service, endpointMap[service])
c.cache.SetDefault(key, cla)
c.onceMap.Delete(key)
Expand Down
16 changes: 13 additions & 3 deletions pkg/xds/cache/cla/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"sync"
"time"

"github.com/kumahq/kuma/pkg/core/datasource"
"github.com/kumahq/kuma/pkg/core/secrets/cipher"
secret_manager "github.com/kumahq/kuma/pkg/core/secrets/manager"
secret_store "github.com/kumahq/kuma/pkg/core/secrets/store"

core_metrics "github.com/kumahq/kuma/pkg/metrics"
test_metrics "github.com/kumahq/kuma/pkg/test/metrics"

Expand Down Expand Up @@ -51,16 +56,21 @@ var _ = Describe("ClusterLoadAssignment Cache", func() {
expiration := 500 * time.Millisecond

BeforeEach(func() {
dataSourceLoader := datasource.NewDataSourceLoader(
secret_manager.NewSecretManager(
secret_store.NewSecretStore(memory.NewStore()), cipher.None(), nil))

s = memory.NewStore()
countingManager = &countingResourcesManager{store: s}
var err error

metrics, err = core_metrics.NewMetrics("Standalone")
Expect(err).ToNot(HaveOccurred())

claCache, err = cla.NewCache(countingManager, "", expiration, func(s string) ([]net.IP, error) {
return []net.IP{net.ParseIP(s)}, nil
}, metrics)
claCache, err = cla.NewCache(countingManager, dataSourceLoader, "", expiration,
func(s string) ([]net.IP, error) {
return []net.IP{net.ParseIP(s)}, nil
}, metrics)
Expect(err).ToNot(HaveOccurred())
})

Expand Down
30 changes: 29 additions & 1 deletion pkg/xds/envoy/clusters/client_side_tls_configurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ type clientSideTLSConfigurer struct {
func (c *clientSideTLSConfigurer) Configure(cluster *envoy_api.Cluster) error {
for _, ep := range c.endpoints {
if ep.ExternalService.TLSEnabled {
tlsContext, err := envoy.CreateUpstreamTlsContextNoMetadata(ep.Target)
ca, cert, key := externalServiceTlsCerts(ep.ExternalService)
tlsContext, err := envoy.CreateUpstreamTlsContextNoMetadata(ca, cert, key, ep.Target)
if err != nil {
return err
}

pbst, err := proto.MarshalAnyDeterministic(tlsContext)
if err != nil {
return err
}

transportSocket := &envoy_core.TransportSocket{
Name: envoy_wellknown.TransportSocketTls,
ConfigType: &envoy_core.TransportSocket_TypedConfig{
Expand All @@ -53,3 +56,28 @@ func (c *clientSideTLSConfigurer) Configure(cluster *envoy_api.Cluster) error {

return nil
}

func externalServiceTlsCerts(es *xds.ExternalService) (ca, cert, key *envoy_core.DataSource) {
if es.CaCert != nil {
ca = &envoy_core.DataSource{
Specifier: &envoy_core.DataSource_InlineBytes{
InlineBytes: es.CaCert,
},
}
}
if es.ClientCert != nil {
cert = &envoy_core.DataSource{
Specifier: &envoy_core.DataSource_InlineBytes{
InlineBytes: es.ClientCert,
},
}
}
if es.ClientKey != nil {
key = &envoy_core.DataSource{
Specifier: &envoy_core.DataSource_InlineBytes{
InlineBytes: es.ClientKey,
},
}
}
return
}
Loading