istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/cluster_tls_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package core 16 17 import ( 18 "fmt" 19 "reflect" 20 "testing" 21 "time" 22 23 cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 24 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 25 tls "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" 26 "github.com/google/go-cmp/cmp" 27 "google.golang.org/protobuf/testing/protocmp" 28 "google.golang.org/protobuf/types/known/durationpb" 29 30 meshconfig "istio.io/api/mesh/v1alpha1" 31 networking "istio.io/api/networking/v1alpha3" 32 "istio.io/istio/pilot/pkg/features" 33 "istio.io/istio/pilot/pkg/model" 34 "istio.io/istio/pilot/pkg/networking/util" 35 authn_model "istio.io/istio/pilot/pkg/security/model" 36 "istio.io/istio/pilot/pkg/serviceregistry/provider" 37 "istio.io/istio/pkg/test" 38 "istio.io/istio/pkg/test/util/assert" 39 ) 40 41 func TestApplyUpstreamTLSSettings(t *testing.T) { 42 istioMutualTLSSettings := &networking.ClientTLSSettings{ 43 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 44 SubjectAltNames: []string{"custom.foo.com"}, 45 Sni: "custom.foo.com", 46 } 47 mutualTLSSettingsWithCerts := &networking.ClientTLSSettings{ 48 Mode: networking.ClientTLSSettings_MUTUAL, 49 CaCertificates: "root-cert.pem", 50 ClientCertificate: "cert-chain.pem", 51 PrivateKey: "key.pem", 52 SubjectAltNames: []string{"custom.foo.com"}, 53 Sni: "custom.foo.com", 54 } 55 simpleTLSSettingsWithCerts := &networking.ClientTLSSettings{ 56 Mode: networking.ClientTLSSettings_SIMPLE, 57 CaCertificates: "root-cert.pem", 58 SubjectAltNames: []string{"custom.foo.com"}, 59 Sni: "custom.foo.com", 60 } 61 62 tests := []struct { 63 name string 64 mtlsCtx mtlsContextType 65 discoveryType cluster.Cluster_DiscoveryType 66 tls *networking.ClientTLSSettings 67 h2 bool 68 expectTransportSocket bool 69 expectTransportSocketMatch bool 70 71 validateTLSContext func(t *testing.T, ctx *tls.UpstreamTlsContext) 72 }{ 73 { 74 name: "user specified without tls", 75 mtlsCtx: userSupplied, 76 discoveryType: cluster.Cluster_EDS, 77 tls: nil, 78 expectTransportSocket: false, 79 expectTransportSocketMatch: false, 80 }, 81 { 82 name: "user specified with istio_mutual tls", 83 mtlsCtx: userSupplied, 84 discoveryType: cluster.Cluster_EDS, 85 tls: istioMutualTLSSettings, 86 expectTransportSocket: true, 87 expectTransportSocketMatch: false, 88 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 89 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNInMeshWithMxc) { 90 t.Fatalf("expected alpn list %v; got %v", util.ALPNInMeshWithMxc, got) 91 } 92 }, 93 }, 94 { 95 name: "user specified with istio_mutual tls with h2", 96 mtlsCtx: userSupplied, 97 discoveryType: cluster.Cluster_EDS, 98 tls: istioMutualTLSSettings, 99 expectTransportSocket: true, 100 expectTransportSocketMatch: false, 101 h2: true, 102 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 103 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNInMeshH2WithMxc) { 104 t.Fatalf("expected alpn list %v; got %v", util.ALPNInMeshH2WithMxc, got) 105 } 106 }, 107 }, 108 { 109 name: "user specified simple tls", 110 mtlsCtx: userSupplied, 111 discoveryType: cluster.Cluster_EDS, 112 tls: simpleTLSSettingsWithCerts, 113 expectTransportSocket: true, 114 expectTransportSocketMatch: false, 115 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 116 rootName := "file-root:" + mutualTLSSettingsWithCerts.CaCertificates 117 if got := ctx.CommonTlsContext.GetCombinedValidationContext().GetValidationContextSdsSecretConfig().GetName(); rootName != got { 118 t.Fatalf("expected root name %v got %v", rootName, got) 119 } 120 if got := ctx.CommonTlsContext.GetAlpnProtocols(); got != nil { 121 t.Fatalf("expected alpn list nil as not h2 or Istio_Mutual TLS Setting; got %v", got) 122 } 123 if got := ctx.GetSni(); got != simpleTLSSettingsWithCerts.Sni { 124 t.Fatalf("expected TLSContext SNI %v; got %v", simpleTLSSettingsWithCerts.Sni, got) 125 } 126 }, 127 }, 128 { 129 name: "user specified simple tls with h2", 130 mtlsCtx: userSupplied, 131 discoveryType: cluster.Cluster_EDS, 132 tls: simpleTLSSettingsWithCerts, 133 expectTransportSocket: true, 134 expectTransportSocketMatch: false, 135 h2: true, 136 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 137 rootName := "file-root:" + mutualTLSSettingsWithCerts.CaCertificates 138 if got := ctx.CommonTlsContext.GetCombinedValidationContext().GetValidationContextSdsSecretConfig().GetName(); rootName != got { 139 t.Fatalf("expected root name %v got %v", rootName, got) 140 } 141 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNH2Only) { 142 t.Fatalf("expected alpn list %v; got %v", util.ALPNH2Only, got) 143 } 144 if got := ctx.GetSni(); got != simpleTLSSettingsWithCerts.Sni { 145 t.Fatalf("expected TLSContext SNI %v; got %v", simpleTLSSettingsWithCerts.Sni, got) 146 } 147 }, 148 }, 149 { 150 name: "user specified mutual tls", 151 mtlsCtx: userSupplied, 152 discoveryType: cluster.Cluster_EDS, 153 tls: mutualTLSSettingsWithCerts, 154 expectTransportSocket: true, 155 expectTransportSocketMatch: false, 156 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 157 rootName := "file-root:" + mutualTLSSettingsWithCerts.CaCertificates 158 certName := fmt.Sprintf("file-cert:%s~%s", mutualTLSSettingsWithCerts.ClientCertificate, mutualTLSSettingsWithCerts.PrivateKey) 159 if got := ctx.CommonTlsContext.GetCombinedValidationContext().GetValidationContextSdsSecretConfig().GetName(); rootName != got { 160 t.Fatalf("expected root name %v got %v", rootName, got) 161 } 162 if got := ctx.CommonTlsContext.GetTlsCertificateSdsSecretConfigs()[0].GetName(); certName != got { 163 t.Fatalf("expected cert name %v got %v", certName, got) 164 } 165 if got := ctx.CommonTlsContext.GetAlpnProtocols(); got != nil { 166 t.Fatalf("expected alpn list nil as not h2 or Istio_Mutual TLS Setting; got %v", got) 167 } 168 if got := ctx.GetSni(); got != mutualTLSSettingsWithCerts.Sni { 169 t.Fatalf("expected TLSContext SNI %v; got %v", mutualTLSSettingsWithCerts.Sni, got) 170 } 171 }, 172 }, 173 { 174 name: "user specified mutual tls with h2", 175 mtlsCtx: userSupplied, 176 discoveryType: cluster.Cluster_EDS, 177 tls: mutualTLSSettingsWithCerts, 178 expectTransportSocket: true, 179 expectTransportSocketMatch: false, 180 h2: true, 181 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 182 rootName := "file-root:" + mutualTLSSettingsWithCerts.CaCertificates 183 certName := fmt.Sprintf("file-cert:%s~%s", mutualTLSSettingsWithCerts.ClientCertificate, mutualTLSSettingsWithCerts.PrivateKey) 184 if got := ctx.CommonTlsContext.GetCombinedValidationContext().GetValidationContextSdsSecretConfig().GetName(); rootName != got { 185 t.Fatalf("expected root name %v got %v", rootName, got) 186 } 187 if got := ctx.CommonTlsContext.GetTlsCertificateSdsSecretConfigs()[0].GetName(); certName != got { 188 t.Fatalf("expected cert name %v got %v", certName, got) 189 } 190 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNH2Only) { 191 t.Fatalf("expected alpn list %v; got %v", util.ALPNH2Only, got) 192 } 193 if got := ctx.GetSni(); got != mutualTLSSettingsWithCerts.Sni { 194 t.Fatalf("expected TLSContext SNI %v; got %v", mutualTLSSettingsWithCerts.Sni, got) 195 } 196 }, 197 }, 198 { 199 name: "auto detect with tls", 200 mtlsCtx: autoDetected, 201 discoveryType: cluster.Cluster_EDS, 202 tls: istioMutualTLSSettings, 203 expectTransportSocket: false, 204 expectTransportSocketMatch: true, 205 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 206 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNInMeshWithMxc) { 207 t.Fatalf("expected alpn list %v; got %v", util.ALPNInMeshWithMxc, got) 208 } 209 }, 210 }, 211 { 212 name: "auto detect with tls and h2 options", 213 mtlsCtx: autoDetected, 214 discoveryType: cluster.Cluster_EDS, 215 tls: istioMutualTLSSettings, 216 expectTransportSocket: false, 217 expectTransportSocketMatch: true, 218 h2: true, 219 validateTLSContext: func(t *testing.T, ctx *tls.UpstreamTlsContext) { 220 if got := ctx.CommonTlsContext.GetAlpnProtocols(); !reflect.DeepEqual(got, util.ALPNInMeshH2WithMxc) { 221 t.Fatalf("expected alpn list %v; got %v", util.ALPNInMeshH2WithMxc, got) 222 } 223 }, 224 }, 225 } 226 227 proxy := &model.Proxy{ 228 Type: model.SidecarProxy, 229 Metadata: &model.NodeMetadata{}, 230 IstioVersion: &model.IstioVersion{Major: 1, Minor: 5}, 231 } 232 push := model.NewPushContext() 233 for _, test := range tests { 234 t.Run(test.name, func(t *testing.T) { 235 cb := NewClusterBuilder(proxy, &model.PushRequest{Push: push}, model.DisabledCache{}) 236 opts := &buildClusterOpts{ 237 mutable: newClusterWrapper(&cluster.Cluster{ 238 ClusterDiscoveryType: &cluster.Cluster_Type{Type: test.discoveryType}, 239 }), 240 mesh: push.Mesh, 241 } 242 if test.h2 { 243 setH2Options(opts.mutable) 244 } 245 cb.applyUpstreamTLSSettings(opts, test.tls, test.mtlsCtx) 246 247 if test.expectTransportSocket && opts.mutable.cluster.TransportSocket == nil || 248 !test.expectTransportSocket && opts.mutable.cluster.TransportSocket != nil { 249 t.Errorf("Expected TransportSocket %v", test.expectTransportSocket) 250 } 251 if test.expectTransportSocketMatch && opts.mutable.cluster.TransportSocketMatches == nil || 252 !test.expectTransportSocketMatch && opts.mutable.cluster.TransportSocketMatches != nil { 253 t.Errorf("Expected TransportSocketMatch %v", test.expectTransportSocketMatch) 254 } 255 256 if test.validateTLSContext != nil { 257 ctx := &tls.UpstreamTlsContext{} 258 if test.expectTransportSocket { 259 if err := opts.mutable.cluster.TransportSocket.GetTypedConfig().UnmarshalTo(ctx); err != nil { 260 t.Fatal(err) 261 } 262 } else if test.expectTransportSocketMatch { 263 if err := opts.mutable.cluster.TransportSocketMatches[0].TransportSocket.GetTypedConfig().UnmarshalTo(ctx); err != nil { 264 t.Fatal(err) 265 } 266 } 267 test.validateTLSContext(t, ctx) 268 } 269 }) 270 } 271 } 272 273 type expectedResult struct { 274 tlsContext *tls.UpstreamTlsContext 275 err error 276 } 277 278 // TestBuildUpstreamClusterTLSContext tests the buildUpstreamClusterTLSContext function 279 func TestBuildUpstreamClusterTLSContext(t *testing.T) { 280 clientCert := "/path/to/cert" 281 rootCert := "path/to/cacert" 282 clientKey := "/path/to/key" 283 284 credentialName := "some-fake-credential" 285 286 testCases := []struct { 287 name string 288 opts *buildClusterOpts 289 tls *networking.ClientTLSSettings 290 h2 bool 291 router bool 292 result expectedResult 293 enableAutoSni bool 294 enableVerifyCertAtClient bool 295 }{ 296 { 297 name: "tls mode disabled", 298 opts: &buildClusterOpts{ 299 mutable: newClusterWrapper(&cluster.Cluster{ 300 Name: "test-cluster", 301 }), 302 }, 303 tls: &networking.ClientTLSSettings{ 304 Mode: networking.ClientTLSSettings_DISABLE, 305 }, 306 result: expectedResult{nil, nil}, 307 }, 308 { 309 name: "tls mode ISTIO_MUTUAL", 310 opts: &buildClusterOpts{ 311 mutable: newTestCluster(), 312 }, 313 tls: &networking.ClientTLSSettings{ 314 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 315 SubjectAltNames: []string{"SAN"}, 316 Sni: "some-sni.com", 317 }, 318 result: expectedResult{ 319 tlsContext: &tls.UpstreamTlsContext{ 320 CommonTlsContext: &tls.CommonTlsContext{ 321 TlsParams: &tls.TlsParameters{ 322 // if not specified, envoy use TLSv1_2 as default for client. 323 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 324 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 325 }, 326 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 327 { 328 Name: "default", 329 SdsConfig: &core.ConfigSource{ 330 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 331 ApiConfigSource: &core.ApiConfigSource{ 332 ApiType: core.ApiConfigSource_GRPC, 333 SetNodeOnFirstMessageOnly: true, 334 TransportApiVersion: core.ApiVersion_V3, 335 GrpcServices: []*core.GrpcService{ 336 { 337 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 338 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 339 }, 340 }, 341 }, 342 }, 343 }, 344 InitialFetchTimeout: durationpb.New(time.Second * 0), 345 ResourceApiVersion: core.ApiVersion_V3, 346 }, 347 }, 348 }, 349 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 350 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 351 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 352 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 353 Name: "ROOTCA", 354 SdsConfig: &core.ConfigSource{ 355 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 356 ApiConfigSource: &core.ApiConfigSource{ 357 ApiType: core.ApiConfigSource_GRPC, 358 SetNodeOnFirstMessageOnly: true, 359 TransportApiVersion: core.ApiVersion_V3, 360 GrpcServices: []*core.GrpcService{ 361 { 362 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 363 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 364 }, 365 }, 366 }, 367 }, 368 }, 369 InitialFetchTimeout: durationpb.New(time.Second * 0), 370 ResourceApiVersion: core.ApiVersion_V3, 371 }, 372 }, 373 }, 374 }, 375 AlpnProtocols: util.ALPNInMeshWithMxc, 376 }, 377 Sni: "some-sni.com", 378 }, 379 err: nil, 380 }, 381 }, 382 { 383 name: "tls mode ISTIO_MUTUAL and H2", 384 opts: &buildClusterOpts{ 385 mutable: newTestCluster(), 386 }, 387 tls: &networking.ClientTLSSettings{ 388 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 389 SubjectAltNames: []string{"SAN"}, 390 Sni: "some-sni.com", 391 }, 392 h2: true, 393 result: expectedResult{ 394 tlsContext: &tls.UpstreamTlsContext{ 395 CommonTlsContext: &tls.CommonTlsContext{ 396 TlsParams: &tls.TlsParameters{ 397 // if not specified, envoy use TLSv1_2 as default for client. 398 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 399 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 400 }, 401 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 402 { 403 Name: "default", 404 SdsConfig: &core.ConfigSource{ 405 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 406 ApiConfigSource: &core.ApiConfigSource{ 407 ApiType: core.ApiConfigSource_GRPC, 408 SetNodeOnFirstMessageOnly: true, 409 TransportApiVersion: core.ApiVersion_V3, 410 GrpcServices: []*core.GrpcService{ 411 { 412 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 413 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 414 }, 415 }, 416 }, 417 }, 418 }, 419 InitialFetchTimeout: durationpb.New(time.Second * 0), 420 ResourceApiVersion: core.ApiVersion_V3, 421 }, 422 }, 423 }, 424 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 425 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 426 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 427 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 428 Name: "ROOTCA", 429 SdsConfig: &core.ConfigSource{ 430 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 431 ApiConfigSource: &core.ApiConfigSource{ 432 ApiType: core.ApiConfigSource_GRPC, 433 SetNodeOnFirstMessageOnly: true, 434 TransportApiVersion: core.ApiVersion_V3, 435 GrpcServices: []*core.GrpcService{ 436 { 437 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 438 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 439 }, 440 }, 441 }, 442 }, 443 }, 444 InitialFetchTimeout: durationpb.New(time.Second * 0), 445 ResourceApiVersion: core.ApiVersion_V3, 446 }, 447 }, 448 }, 449 }, 450 AlpnProtocols: util.ALPNInMeshH2WithMxc, 451 }, 452 Sni: "some-sni.com", 453 }, 454 err: nil, 455 }, 456 }, 457 { 458 name: "tls mode SIMPLE, with no certs specified in tls", 459 opts: &buildClusterOpts{ 460 mutable: newTestCluster(), 461 }, 462 tls: &networking.ClientTLSSettings{ 463 Mode: networking.ClientTLSSettings_SIMPLE, 464 SubjectAltNames: []string{"SAN"}, 465 Sni: "some-sni.com", 466 }, 467 result: expectedResult{ 468 tlsContext: &tls.UpstreamTlsContext{ 469 CommonTlsContext: &tls.CommonTlsContext{ 470 TlsParams: &tls.TlsParameters{ 471 // if not specified, envoy use TLSv1_2 as default for client. 472 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 473 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 474 }, 475 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 476 }, 477 Sni: "some-sni.com", 478 }, 479 err: nil, 480 }, 481 }, 482 { 483 name: "tls mode SIMPLE, with AutoSni enabled and no sni specified in tls", 484 opts: &buildClusterOpts{ 485 mutable: newTestCluster(), 486 }, 487 tls: &networking.ClientTLSSettings{ 488 Mode: networking.ClientTLSSettings_SIMPLE, 489 SubjectAltNames: []string{"SAN"}, 490 }, 491 result: expectedResult{ 492 tlsContext: &tls.UpstreamTlsContext{ 493 CommonTlsContext: &tls.CommonTlsContext{ 494 TlsParams: &tls.TlsParameters{ 495 // if not specified, envoy use TLSv1_2 as default for client. 496 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 497 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 498 }, 499 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 500 }, 501 }, 502 err: nil, 503 }, 504 enableAutoSni: true, 505 }, 506 { 507 name: "tls mode SIMPLE, with AutoSni enabled and sni specified in tls", 508 opts: &buildClusterOpts{ 509 mutable: newTestCluster(), 510 }, 511 tls: &networking.ClientTLSSettings{ 512 Mode: networking.ClientTLSSettings_SIMPLE, 513 SubjectAltNames: []string{"SAN"}, 514 Sni: "some-sni.com", 515 }, 516 result: expectedResult{ 517 tlsContext: &tls.UpstreamTlsContext{ 518 CommonTlsContext: &tls.CommonTlsContext{ 519 TlsParams: &tls.TlsParameters{ 520 // if not specified, envoy use TLSv1_2 as default for client. 521 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 522 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 523 }, 524 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 525 }, 526 Sni: "some-sni.com", 527 }, 528 err: nil, 529 }, 530 enableAutoSni: true, 531 }, 532 { 533 name: "tls mode SIMPLE, with VerifyCert and AutoSni enabled with SubjectAltNames set", 534 opts: &buildClusterOpts{ 535 mutable: newTestCluster(), 536 }, 537 tls: &networking.ClientTLSSettings{ 538 Mode: networking.ClientTLSSettings_SIMPLE, 539 SubjectAltNames: []string{"SAN"}, 540 Sni: "some-sni.com", 541 }, 542 result: expectedResult{ 543 tlsContext: &tls.UpstreamTlsContext{ 544 CommonTlsContext: &tls.CommonTlsContext{ 545 TlsParams: &tls.TlsParameters{ 546 // if not specified, envoy use TLSv1_2 as default for client. 547 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 548 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 549 }, 550 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 551 }, 552 Sni: "some-sni.com", 553 }, 554 err: nil, 555 }, 556 enableAutoSni: true, 557 enableVerifyCertAtClient: true, 558 }, 559 { 560 name: "tls mode SIMPLE, with VerifyCert and AutoSni enabled without SubjectAltNames set", 561 opts: &buildClusterOpts{ 562 mutable: newTestCluster(), 563 }, 564 tls: &networking.ClientTLSSettings{ 565 Mode: networking.ClientTLSSettings_SIMPLE, 566 Sni: "some-sni.com", 567 }, 568 result: expectedResult{ 569 tlsContext: &tls.UpstreamTlsContext{ 570 CommonTlsContext: &tls.CommonTlsContext{ 571 TlsParams: &tls.TlsParameters{ 572 // if not specified, envoy use TLSv1_2 as default for client. 573 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 574 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 575 }, 576 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 577 }, 578 Sni: "some-sni.com", 579 }, 580 err: nil, 581 }, 582 enableAutoSni: true, 583 enableVerifyCertAtClient: true, 584 }, 585 { 586 name: "tls mode SIMPLE, with certs specified in tls", 587 opts: &buildClusterOpts{ 588 mutable: newTestCluster(), 589 }, 590 tls: &networking.ClientTLSSettings{ 591 Mode: networking.ClientTLSSettings_SIMPLE, 592 CaCertificates: rootCert, 593 SubjectAltNames: []string{"SAN"}, 594 Sni: "some-sni.com", 595 }, 596 result: expectedResult{ 597 tlsContext: &tls.UpstreamTlsContext{ 598 CommonTlsContext: &tls.CommonTlsContext{ 599 TlsParams: &tls.TlsParameters{ 600 // if not specified, envoy use TLSv1_2 as default for client. 601 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 602 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 603 }, 604 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 605 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 606 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 607 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 608 Name: fmt.Sprintf("file-root:%s", rootCert), 609 SdsConfig: &core.ConfigSource{ 610 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 611 ApiConfigSource: &core.ApiConfigSource{ 612 ApiType: core.ApiConfigSource_GRPC, 613 SetNodeOnFirstMessageOnly: true, 614 TransportApiVersion: core.ApiVersion_V3, 615 GrpcServices: []*core.GrpcService{ 616 { 617 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 618 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 619 }, 620 }, 621 }, 622 }, 623 }, 624 ResourceApiVersion: core.ApiVersion_V3, 625 }, 626 }, 627 }, 628 }, 629 }, 630 Sni: "some-sni.com", 631 }, 632 err: nil, 633 }, 634 }, 635 { 636 name: "tls mode SIMPLE, with certs specified in tls, with crl", 637 opts: &buildClusterOpts{ 638 mutable: newTestCluster(), 639 }, 640 tls: &networking.ClientTLSSettings{ 641 Mode: networking.ClientTLSSettings_SIMPLE, 642 CaCertificates: rootCert, 643 SubjectAltNames: []string{"SAN"}, 644 Sni: "some-sni.com", 645 CaCrl: "path/to/crl", 646 }, 647 result: expectedResult{ 648 tlsContext: &tls.UpstreamTlsContext{ 649 CommonTlsContext: &tls.CommonTlsContext{ 650 TlsParams: &tls.TlsParameters{ 651 // if not specified, envoy use TLSv1_2 as default for client. 652 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 653 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 654 }, 655 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 656 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 657 DefaultValidationContext: &tls.CertificateValidationContext{ 658 Crl: &core.DataSource{ 659 Specifier: &core.DataSource_Filename{ 660 Filename: "path/to/crl", 661 }, 662 }, 663 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 664 }, 665 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 666 Name: fmt.Sprintf("file-root:%s", rootCert), 667 SdsConfig: &core.ConfigSource{ 668 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 669 ApiConfigSource: &core.ApiConfigSource{ 670 ApiType: core.ApiConfigSource_GRPC, 671 SetNodeOnFirstMessageOnly: true, 672 TransportApiVersion: core.ApiVersion_V3, 673 GrpcServices: []*core.GrpcService{ 674 { 675 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 676 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 677 }, 678 }, 679 }, 680 }, 681 }, 682 ResourceApiVersion: core.ApiVersion_V3, 683 }, 684 }, 685 }, 686 }, 687 }, 688 Sni: "some-sni.com", 689 }, 690 err: nil, 691 }, 692 }, 693 { 694 name: "tls mode SIMPLE, with certs specified in tls with h2", 695 opts: &buildClusterOpts{ 696 mutable: newH2TestCluster(), 697 }, 698 tls: &networking.ClientTLSSettings{ 699 Mode: networking.ClientTLSSettings_SIMPLE, 700 CaCertificates: rootCert, 701 SubjectAltNames: []string{"SAN"}, 702 Sni: "some-sni.com", 703 }, 704 h2: true, 705 result: expectedResult{ 706 tlsContext: &tls.UpstreamTlsContext{ 707 CommonTlsContext: &tls.CommonTlsContext{ 708 TlsParams: &tls.TlsParameters{ 709 // if not specified, envoy use TLSv1_2 as default for client. 710 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 711 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 712 }, 713 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 714 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 715 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 716 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 717 Name: fmt.Sprintf("file-root:%s", rootCert), 718 SdsConfig: &core.ConfigSource{ 719 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 720 ApiConfigSource: &core.ApiConfigSource{ 721 ApiType: core.ApiConfigSource_GRPC, 722 SetNodeOnFirstMessageOnly: true, 723 TransportApiVersion: core.ApiVersion_V3, 724 GrpcServices: []*core.GrpcService{ 725 { 726 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 727 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 728 }, 729 }, 730 }, 731 }, 732 }, 733 ResourceApiVersion: core.ApiVersion_V3, 734 }, 735 }, 736 }, 737 }, 738 AlpnProtocols: util.ALPNH2Only, 739 }, 740 Sni: "some-sni.com", 741 }, 742 err: nil, 743 }, 744 }, 745 { 746 name: "tls mode SIMPLE, with certs specified in tls", 747 opts: &buildClusterOpts{ 748 mutable: newTestCluster(), 749 }, 750 tls: &networking.ClientTLSSettings{ 751 Mode: networking.ClientTLSSettings_SIMPLE, 752 CaCertificates: rootCert, 753 SubjectAltNames: []string{"SAN"}, 754 Sni: "some-sni.com", 755 }, 756 result: expectedResult{ 757 tlsContext: &tls.UpstreamTlsContext{ 758 CommonTlsContext: &tls.CommonTlsContext{ 759 TlsParams: &tls.TlsParameters{ 760 // if not specified, envoy use TLSv1_2 as default for client. 761 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 762 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 763 }, 764 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 765 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 766 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 767 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 768 Name: fmt.Sprintf("file-root:%s", rootCert), 769 SdsConfig: &core.ConfigSource{ 770 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 771 ApiConfigSource: &core.ApiConfigSource{ 772 ApiType: core.ApiConfigSource_GRPC, 773 SetNodeOnFirstMessageOnly: true, 774 TransportApiVersion: core.ApiVersion_V3, 775 GrpcServices: []*core.GrpcService{ 776 { 777 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 778 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 779 }, 780 }, 781 }, 782 }, 783 }, 784 ResourceApiVersion: core.ApiVersion_V3, 785 }, 786 }, 787 }, 788 }, 789 }, 790 Sni: "some-sni.com", 791 }, 792 err: nil, 793 }, 794 }, 795 { 796 name: "tls mode SIMPLE, with SANs specified in service entries", 797 opts: &buildClusterOpts{ 798 mutable: newTestCluster(), 799 serviceAccounts: []string{"se-san.com"}, 800 serviceRegistry: provider.External, 801 }, 802 tls: &networking.ClientTLSSettings{ 803 Mode: networking.ClientTLSSettings_SIMPLE, 804 CaCertificates: rootCert, 805 Sni: "some-sni.com", 806 }, 807 result: expectedResult{ 808 tlsContext: &tls.UpstreamTlsContext{ 809 CommonTlsContext: &tls.CommonTlsContext{ 810 TlsParams: &tls.TlsParameters{ 811 // if not specified, envoy use TLSv1_2 as default for client. 812 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 813 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 814 }, 815 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 816 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 817 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"se-san.com"})}, 818 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 819 Name: fmt.Sprintf("file-root:%s", rootCert), 820 SdsConfig: &core.ConfigSource{ 821 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 822 ApiConfigSource: &core.ApiConfigSource{ 823 ApiType: core.ApiConfigSource_GRPC, 824 SetNodeOnFirstMessageOnly: true, 825 TransportApiVersion: core.ApiVersion_V3, 826 GrpcServices: []*core.GrpcService{ 827 { 828 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 829 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 830 }, 831 }, 832 }, 833 }, 834 }, 835 ResourceApiVersion: core.ApiVersion_V3, 836 }, 837 }, 838 }, 839 }, 840 }, 841 Sni: "some-sni.com", 842 }, 843 err: nil, 844 }, 845 }, 846 { 847 name: "tls mode MUTUAL, with no client certificate", 848 opts: &buildClusterOpts{ 849 mutable: newTestCluster(), 850 }, 851 tls: &networking.ClientTLSSettings{ 852 Mode: networking.ClientTLSSettings_MUTUAL, 853 ClientCertificate: "", 854 PrivateKey: "some-fake-key", 855 }, 856 result: expectedResult{ 857 nil, 858 fmt.Errorf("client cert must be provided"), 859 }, 860 }, 861 { 862 name: "tls mode MUTUAL, with no client key", 863 opts: &buildClusterOpts{ 864 mutable: newTestCluster(), 865 }, 866 tls: &networking.ClientTLSSettings{ 867 Mode: networking.ClientTLSSettings_MUTUAL, 868 ClientCertificate: "some-fake-cert", 869 PrivateKey: "", 870 }, 871 result: expectedResult{ 872 nil, 873 fmt.Errorf("client key must be provided"), 874 }, 875 }, 876 { 877 name: "tls mode MUTUAL, with node metadata sdsEnabled true no root CA specified", 878 opts: &buildClusterOpts{ 879 mutable: newTestCluster(), 880 }, 881 tls: &networking.ClientTLSSettings{ 882 Mode: networking.ClientTLSSettings_MUTUAL, 883 ClientCertificate: clientCert, 884 PrivateKey: clientKey, 885 SubjectAltNames: []string{"SAN"}, 886 Sni: "some-sni.com", 887 }, 888 result: expectedResult{ 889 tlsContext: &tls.UpstreamTlsContext{ 890 CommonTlsContext: &tls.CommonTlsContext{ 891 TlsParams: &tls.TlsParameters{ 892 // if not specified, envoy use TLSv1_2 as default for client. 893 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 894 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 895 }, 896 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 897 { 898 Name: fmt.Sprintf("file-cert:%s~%s", clientCert, clientKey), 899 SdsConfig: &core.ConfigSource{ 900 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 901 ApiConfigSource: &core.ApiConfigSource{ 902 ApiType: core.ApiConfigSource_GRPC, 903 SetNodeOnFirstMessageOnly: true, 904 TransportApiVersion: core.ApiVersion_V3, 905 GrpcServices: []*core.GrpcService{ 906 { 907 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 908 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 909 }, 910 }, 911 }, 912 }, 913 }, 914 ResourceApiVersion: core.ApiVersion_V3, 915 }, 916 }, 917 }, 918 ValidationContextType: &tls.CommonTlsContext_ValidationContext{}, 919 }, 920 Sni: "some-sni.com", 921 }, 922 err: nil, 923 }, 924 }, 925 { 926 name: "tls mode MUTUAL, with node metadata sdsEnabled true", 927 opts: &buildClusterOpts{ 928 mutable: newTestCluster(), 929 }, 930 tls: &networking.ClientTLSSettings{ 931 Mode: networking.ClientTLSSettings_MUTUAL, 932 ClientCertificate: clientCert, 933 PrivateKey: clientKey, 934 CaCertificates: rootCert, 935 SubjectAltNames: []string{"SAN"}, 936 Sni: "some-sni.com", 937 }, 938 result: expectedResult{ 939 tlsContext: &tls.UpstreamTlsContext{ 940 CommonTlsContext: &tls.CommonTlsContext{ 941 TlsParams: &tls.TlsParameters{ 942 // if not specified, envoy use TLSv1_2 as default for client. 943 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 944 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 945 }, 946 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 947 { 948 Name: fmt.Sprintf("file-cert:%s~%s", clientCert, clientKey), 949 SdsConfig: &core.ConfigSource{ 950 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 951 ApiConfigSource: &core.ApiConfigSource{ 952 ApiType: core.ApiConfigSource_GRPC, 953 SetNodeOnFirstMessageOnly: true, 954 TransportApiVersion: core.ApiVersion_V3, 955 GrpcServices: []*core.GrpcService{ 956 { 957 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 958 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 959 }, 960 }, 961 }, 962 }, 963 }, 964 ResourceApiVersion: core.ApiVersion_V3, 965 }, 966 }, 967 }, 968 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 969 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 970 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 971 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 972 Name: fmt.Sprintf("file-root:%s", rootCert), 973 SdsConfig: &core.ConfigSource{ 974 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 975 ApiConfigSource: &core.ApiConfigSource{ 976 ApiType: core.ApiConfigSource_GRPC, 977 SetNodeOnFirstMessageOnly: true, 978 TransportApiVersion: core.ApiVersion_V3, 979 GrpcServices: []*core.GrpcService{ 980 { 981 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 982 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 983 }, 984 }, 985 }, 986 }, 987 }, 988 ResourceApiVersion: core.ApiVersion_V3, 989 }, 990 }, 991 }, 992 }, 993 }, 994 Sni: "some-sni.com", 995 }, 996 err: nil, 997 }, 998 }, 999 { 1000 name: "tls mode MUTUAL, with node metadata sdsEnabled true, with crl", 1001 opts: &buildClusterOpts{ 1002 mutable: newTestCluster(), 1003 }, 1004 tls: &networking.ClientTLSSettings{ 1005 Mode: networking.ClientTLSSettings_MUTUAL, 1006 ClientCertificate: clientCert, 1007 PrivateKey: clientKey, 1008 CaCertificates: rootCert, 1009 CaCrl: "path/to/crl", 1010 SubjectAltNames: []string{"SAN"}, 1011 Sni: "some-sni.com", 1012 }, 1013 result: expectedResult{ 1014 tlsContext: &tls.UpstreamTlsContext{ 1015 CommonTlsContext: &tls.CommonTlsContext{ 1016 TlsParams: &tls.TlsParameters{ 1017 // if not specified, envoy use TLSv1_2 as default for client. 1018 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1019 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1020 }, 1021 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1022 { 1023 Name: fmt.Sprintf("file-cert:%s~%s", clientCert, clientKey), 1024 SdsConfig: &core.ConfigSource{ 1025 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1026 ApiConfigSource: &core.ApiConfigSource{ 1027 ApiType: core.ApiConfigSource_GRPC, 1028 SetNodeOnFirstMessageOnly: true, 1029 TransportApiVersion: core.ApiVersion_V3, 1030 GrpcServices: []*core.GrpcService{ 1031 { 1032 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1033 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 1034 }, 1035 }, 1036 }, 1037 }, 1038 }, 1039 ResourceApiVersion: core.ApiVersion_V3, 1040 }, 1041 }, 1042 }, 1043 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1044 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1045 DefaultValidationContext: &tls.CertificateValidationContext{ 1046 Crl: &core.DataSource{ 1047 Specifier: &core.DataSource_Filename{ 1048 Filename: "path/to/crl", 1049 }, 1050 }, 1051 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1052 }, 1053 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1054 Name: fmt.Sprintf("file-root:%s", rootCert), 1055 SdsConfig: &core.ConfigSource{ 1056 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1057 ApiConfigSource: &core.ApiConfigSource{ 1058 ApiType: core.ApiConfigSource_GRPC, 1059 SetNodeOnFirstMessageOnly: true, 1060 TransportApiVersion: core.ApiVersion_V3, 1061 GrpcServices: []*core.GrpcService{ 1062 { 1063 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1064 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 1065 }, 1066 }, 1067 }, 1068 }, 1069 }, 1070 ResourceApiVersion: core.ApiVersion_V3, 1071 }, 1072 }, 1073 }, 1074 }, 1075 }, 1076 Sni: "some-sni.com", 1077 }, 1078 err: nil, 1079 }, 1080 }, 1081 { 1082 name: "tls mode SIMPLE, with CredentialName specified", 1083 opts: &buildClusterOpts{ 1084 mutable: newTestCluster(), 1085 }, 1086 tls: &networking.ClientTLSSettings{ 1087 Mode: networking.ClientTLSSettings_SIMPLE, 1088 CredentialName: credentialName, 1089 SubjectAltNames: []string{"SAN"}, 1090 Sni: "some-sni.com", 1091 }, 1092 router: true, 1093 result: expectedResult{ 1094 tlsContext: &tls.UpstreamTlsContext{ 1095 CommonTlsContext: &tls.CommonTlsContext{ 1096 TlsParams: &tls.TlsParameters{ 1097 // if not specified, envoy use TLSv1_2 as default for client. 1098 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1099 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1100 }, 1101 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1102 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1103 DefaultValidationContext: &tls.CertificateValidationContext{ 1104 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1105 }, 1106 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1107 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1108 SdsConfig: authn_model.SDSAdsConfig, 1109 }, 1110 }, 1111 }, 1112 }, 1113 Sni: "some-sni.com", 1114 }, 1115 err: nil, 1116 }, 1117 }, 1118 { 1119 name: "tls mode SIMPLE, with CredentialName specified with h2 and no SAN", 1120 opts: &buildClusterOpts{ 1121 mutable: newH2TestCluster(), 1122 }, 1123 tls: &networking.ClientTLSSettings{ 1124 Mode: networking.ClientTLSSettings_SIMPLE, 1125 CredentialName: credentialName, 1126 Sni: "some-sni.com", 1127 }, 1128 h2: true, 1129 router: true, 1130 result: expectedResult{ 1131 tlsContext: &tls.UpstreamTlsContext{ 1132 CommonTlsContext: &tls.CommonTlsContext{ 1133 TlsParams: &tls.TlsParameters{ 1134 // if not specified, envoy use TLSv1_2 as default for client. 1135 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1136 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1137 }, 1138 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1139 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1140 DefaultValidationContext: &tls.CertificateValidationContext{}, 1141 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1142 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1143 SdsConfig: authn_model.SDSAdsConfig, 1144 }, 1145 }, 1146 }, 1147 AlpnProtocols: util.ALPNH2Only, 1148 }, 1149 Sni: "some-sni.com", 1150 }, 1151 err: nil, 1152 }, 1153 }, 1154 { 1155 name: "tls mode MUTUAL, with CredentialName specified", 1156 opts: &buildClusterOpts{ 1157 mutable: newTestCluster(), 1158 }, 1159 tls: &networking.ClientTLSSettings{ 1160 Mode: networking.ClientTLSSettings_MUTUAL, 1161 CredentialName: credentialName, 1162 SubjectAltNames: []string{"SAN"}, 1163 Sni: "some-sni.com", 1164 }, 1165 router: true, 1166 result: expectedResult{ 1167 tlsContext: &tls.UpstreamTlsContext{ 1168 CommonTlsContext: &tls.CommonTlsContext{ 1169 TlsParams: &tls.TlsParameters{ 1170 // if not specified, envoy use TLSv1_2 as default for client. 1171 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1172 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1173 }, 1174 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1175 { 1176 Name: "kubernetes://" + credentialName, 1177 SdsConfig: authn_model.SDSAdsConfig, 1178 }, 1179 }, 1180 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1181 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1182 DefaultValidationContext: &tls.CertificateValidationContext{ 1183 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1184 }, 1185 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1186 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1187 SdsConfig: authn_model.SDSAdsConfig, 1188 }, 1189 }, 1190 }, 1191 }, 1192 Sni: "some-sni.com", 1193 }, 1194 err: nil, 1195 }, 1196 }, 1197 { 1198 name: "tls mode MUTUAL, with CredentialName specified with h2 and no SAN", 1199 opts: &buildClusterOpts{ 1200 mutable: newH2TestCluster(), 1201 }, 1202 tls: &networking.ClientTLSSettings{ 1203 Mode: networking.ClientTLSSettings_MUTUAL, 1204 CredentialName: credentialName, 1205 Sni: "some-sni.com", 1206 }, 1207 h2: true, 1208 router: true, 1209 result: expectedResult{ 1210 tlsContext: &tls.UpstreamTlsContext{ 1211 CommonTlsContext: &tls.CommonTlsContext{ 1212 TlsParams: &tls.TlsParameters{ 1213 // if not specified, envoy use TLSv1_2 as default for client. 1214 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1215 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1216 }, 1217 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1218 { 1219 Name: "kubernetes://" + credentialName, 1220 SdsConfig: authn_model.SDSAdsConfig, 1221 }, 1222 }, 1223 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1224 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1225 DefaultValidationContext: &tls.CertificateValidationContext{}, 1226 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1227 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1228 SdsConfig: authn_model.SDSAdsConfig, 1229 }, 1230 }, 1231 }, 1232 AlpnProtocols: util.ALPNH2Only, 1233 }, 1234 Sni: "some-sni.com", 1235 }, 1236 err: nil, 1237 }, 1238 }, 1239 { 1240 name: "tls mode MUTUAL, credentialName is set with proxy type Sidecar", 1241 opts: &buildClusterOpts{ 1242 mutable: newTestCluster(), 1243 }, 1244 tls: &networking.ClientTLSSettings{ 1245 Mode: networking.ClientTLSSettings_MUTUAL, 1246 CredentialName: "fake-cred", 1247 }, 1248 result: expectedResult{ 1249 nil, 1250 nil, 1251 }, 1252 }, 1253 { 1254 name: "tls mode SIMPLE, credentialName is set with proxy type Sidecar", 1255 opts: &buildClusterOpts{ 1256 mutable: newTestCluster(), 1257 }, 1258 tls: &networking.ClientTLSSettings{ 1259 Mode: networking.ClientTLSSettings_SIMPLE, 1260 CredentialName: "fake-cred", 1261 }, 1262 result: expectedResult{ 1263 nil, 1264 nil, 1265 }, 1266 }, 1267 { 1268 name: "tls mode SIMPLE, CredentialName is set with proxy type Sidecar and destinationRule has workload Selector", 1269 opts: &buildClusterOpts{ 1270 mutable: newTestCluster(), 1271 isDrWithSelector: true, 1272 }, 1273 tls: &networking.ClientTLSSettings{ 1274 Mode: networking.ClientTLSSettings_SIMPLE, 1275 CredentialName: credentialName, 1276 SubjectAltNames: []string{"SAN"}, 1277 Sni: "some-sni.com", 1278 }, 1279 result: expectedResult{ 1280 tlsContext: &tls.UpstreamTlsContext{ 1281 CommonTlsContext: &tls.CommonTlsContext{ 1282 TlsParams: &tls.TlsParameters{ 1283 // if not specified, envoy use TLSv1_2 as default for client. 1284 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1285 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1286 }, 1287 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1288 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1289 DefaultValidationContext: &tls.CertificateValidationContext{ 1290 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1291 }, 1292 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1293 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1294 SdsConfig: authn_model.SDSAdsConfig, 1295 }, 1296 }, 1297 }, 1298 }, 1299 Sni: "some-sni.com", 1300 }, 1301 err: nil, 1302 }, 1303 }, 1304 { 1305 name: "tls mode SIMPLE, with EcdhCurves specified in Mesh Config", 1306 opts: &buildClusterOpts{ 1307 mutable: newTestCluster(), 1308 isDrWithSelector: true, 1309 mesh: &meshconfig.MeshConfig{ 1310 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1311 EcdhCurves: []string{"P-256"}, 1312 }, 1313 }, 1314 }, 1315 tls: &networking.ClientTLSSettings{ 1316 Mode: networking.ClientTLSSettings_SIMPLE, 1317 CredentialName: credentialName, 1318 SubjectAltNames: []string{"SAN"}, 1319 Sni: "some-sni.com", 1320 }, 1321 result: expectedResult{ 1322 tlsContext: &tls.UpstreamTlsContext{ 1323 CommonTlsContext: &tls.CommonTlsContext{ 1324 TlsParams: &tls.TlsParameters{ 1325 // if not specified, envoy use TLSv1_2 as default for client. 1326 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1327 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1328 EcdhCurves: []string{"P-256"}, 1329 }, 1330 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1331 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1332 DefaultValidationContext: &tls.CertificateValidationContext{ 1333 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1334 }, 1335 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1336 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1337 SdsConfig: authn_model.SDSAdsConfig, 1338 }, 1339 }, 1340 }, 1341 }, 1342 Sni: "some-sni.com", 1343 }, 1344 err: nil, 1345 }, 1346 }, 1347 { 1348 name: "tls mode MUTUAL, with EcdhCurves specified in Mesh Config", 1349 opts: &buildClusterOpts{ 1350 mutable: newTestCluster(), 1351 isDrWithSelector: true, 1352 mesh: &meshconfig.MeshConfig{ 1353 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1354 EcdhCurves: []string{"P-256", "P-384"}, 1355 }, 1356 }, 1357 }, 1358 tls: &networking.ClientTLSSettings{ 1359 Mode: networking.ClientTLSSettings_MUTUAL, 1360 CredentialName: credentialName, 1361 SubjectAltNames: []string{"SAN"}, 1362 Sni: "some-sni.com", 1363 }, 1364 result: expectedResult{ 1365 tlsContext: &tls.UpstreamTlsContext{ 1366 CommonTlsContext: &tls.CommonTlsContext{ 1367 TlsParams: &tls.TlsParameters{ 1368 // if not specified, envoy use TLSv1_2 as default for client. 1369 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1370 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1371 EcdhCurves: []string{"P-256", "P-384"}, 1372 }, 1373 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1374 { 1375 Name: "kubernetes://" + credentialName, 1376 SdsConfig: authn_model.SDSAdsConfig, 1377 }, 1378 }, 1379 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1380 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1381 DefaultValidationContext: &tls.CertificateValidationContext{ 1382 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1383 }, 1384 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1385 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1386 SdsConfig: authn_model.SDSAdsConfig, 1387 }, 1388 }, 1389 }, 1390 }, 1391 Sni: "some-sni.com", 1392 }, 1393 err: nil, 1394 }, 1395 }, 1396 // ecdh curves from MeshConfig should be ignored for ISTIO_MUTUAL mode 1397 { 1398 name: "tls mode ISTIO_MUTUAL with EcdhCurves specified in Mesh Config", 1399 opts: &buildClusterOpts{ 1400 mutable: newTestCluster(), 1401 mesh: &meshconfig.MeshConfig{ 1402 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1403 EcdhCurves: []string{"P-256", "P-384"}, 1404 }, 1405 }, 1406 }, 1407 tls: &networking.ClientTLSSettings{ 1408 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 1409 SubjectAltNames: []string{"SAN"}, 1410 Sni: "some-sni.com", 1411 }, 1412 result: expectedResult{ 1413 tlsContext: &tls.UpstreamTlsContext{ 1414 CommonTlsContext: &tls.CommonTlsContext{ 1415 TlsParams: &tls.TlsParameters{ 1416 // if not specified, envoy use TLSv1_2 as default for client. 1417 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1418 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1419 }, 1420 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1421 { 1422 Name: "default", 1423 SdsConfig: &core.ConfigSource{ 1424 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1425 ApiConfigSource: &core.ApiConfigSource{ 1426 ApiType: core.ApiConfigSource_GRPC, 1427 SetNodeOnFirstMessageOnly: true, 1428 TransportApiVersion: core.ApiVersion_V3, 1429 GrpcServices: []*core.GrpcService{ 1430 { 1431 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1432 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 1433 }, 1434 }, 1435 }, 1436 }, 1437 }, 1438 InitialFetchTimeout: durationpb.New(time.Second * 0), 1439 ResourceApiVersion: core.ApiVersion_V3, 1440 }, 1441 }, 1442 }, 1443 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1444 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1445 DefaultValidationContext: &tls.CertificateValidationContext{MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"})}, 1446 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1447 Name: "ROOTCA", 1448 SdsConfig: &core.ConfigSource{ 1449 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1450 ApiConfigSource: &core.ApiConfigSource{ 1451 ApiType: core.ApiConfigSource_GRPC, 1452 SetNodeOnFirstMessageOnly: true, 1453 TransportApiVersion: core.ApiVersion_V3, 1454 GrpcServices: []*core.GrpcService{ 1455 { 1456 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1457 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "sds-grpc"}, 1458 }, 1459 }, 1460 }, 1461 }, 1462 }, 1463 InitialFetchTimeout: durationpb.New(time.Second * 0), 1464 ResourceApiVersion: core.ApiVersion_V3, 1465 }, 1466 }, 1467 }, 1468 }, 1469 AlpnProtocols: util.ALPNInMeshWithMxc, 1470 }, 1471 Sni: "some-sni.com", 1472 }, 1473 err: nil, 1474 }, 1475 }, 1476 { 1477 name: "tls mode MUTUAL, CredentialName is set with proxy type Sidecar and destinationRule has workload Selector", 1478 opts: &buildClusterOpts{ 1479 mutable: newTestCluster(), 1480 isDrWithSelector: true, 1481 }, 1482 tls: &networking.ClientTLSSettings{ 1483 Mode: networking.ClientTLSSettings_MUTUAL, 1484 CredentialName: credentialName, 1485 SubjectAltNames: []string{"SAN"}, 1486 Sni: "some-sni.com", 1487 }, 1488 result: expectedResult{ 1489 tlsContext: &tls.UpstreamTlsContext{ 1490 CommonTlsContext: &tls.CommonTlsContext{ 1491 TlsParams: &tls.TlsParameters{ 1492 // if not specified, envoy use TLSv1_2 as default for client. 1493 TlsMaximumProtocolVersion: tls.TlsParameters_TLSv1_3, 1494 TlsMinimumProtocolVersion: tls.TlsParameters_TLSv1_2, 1495 }, 1496 TlsCertificateSdsSecretConfigs: []*tls.SdsSecretConfig{ 1497 { 1498 Name: "kubernetes://" + credentialName, 1499 SdsConfig: authn_model.SDSAdsConfig, 1500 }, 1501 }, 1502 ValidationContextType: &tls.CommonTlsContext_CombinedValidationContext{ 1503 CombinedValidationContext: &tls.CommonTlsContext_CombinedCertificateValidationContext{ 1504 DefaultValidationContext: &tls.CertificateValidationContext{ 1505 MatchSubjectAltNames: util.StringToExactMatch([]string{"SAN"}), 1506 }, 1507 ValidationContextSdsSecretConfig: &tls.SdsSecretConfig{ 1508 Name: "kubernetes://" + credentialName + authn_model.SdsCaSuffix, 1509 SdsConfig: authn_model.SDSAdsConfig, 1510 }, 1511 }, 1512 }, 1513 }, 1514 Sni: "some-sni.com", 1515 }, 1516 err: nil, 1517 }, 1518 }, 1519 } 1520 for _, tc := range testCases { 1521 t.Run(tc.name, func(t *testing.T) { 1522 test.SetForTest(t, &features.EnableAutoSni, tc.enableAutoSni) 1523 test.SetForTest(t, &features.VerifyCertAtClient, tc.enableVerifyCertAtClient) 1524 var proxy *model.Proxy 1525 if tc.router { 1526 proxy = newGatewayProxy() 1527 } else { 1528 proxy = newSidecarProxy() 1529 } 1530 cb := NewClusterBuilder(proxy, nil, model.DisabledCache{}) 1531 if tc.h2 { 1532 setH2Options(tc.opts.mutable) 1533 } 1534 ret, err := cb.buildUpstreamClusterTLSContext(tc.opts, tc.tls) 1535 if err != nil && tc.result.err == nil || err == nil && tc.result.err != nil { 1536 t.Errorf("expecting:\n err=%v but got err=%v", tc.result.err, err) 1537 } else if diff := cmp.Diff(tc.result.tlsContext, ret, protocmp.Transform()); diff != "" { 1538 t.Errorf("got diff: `%v", diff) 1539 } 1540 if tc.enableAutoSni { 1541 if len(tc.tls.Sni) == 0 { 1542 assert.Equal(t, tc.opts.mutable.httpProtocolOptions.UpstreamHttpProtocolOptions.AutoSni, true) 1543 } 1544 if tc.enableVerifyCertAtClient && len(tc.tls.Sni) == 0 && len(tc.tls.SubjectAltNames) == 0 { 1545 assert.Equal(t, tc.opts.mutable.httpProtocolOptions.UpstreamHttpProtocolOptions.AutoSanValidation, true) 1546 } 1547 } 1548 }) 1549 } 1550 } 1551 1552 func TestBuildAutoMtlsSettings(t *testing.T) { 1553 tlsSettings := &networking.ClientTLSSettings{ 1554 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 1555 SubjectAltNames: []string{"custom.foo.com"}, 1556 Sni: "custom.foo.com", 1557 } 1558 tests := []struct { 1559 name string 1560 tls *networking.ClientTLSSettings 1561 sans []string 1562 sni string 1563 proxy *model.Proxy 1564 autoMTLSEnabled bool 1565 meshExternal bool 1566 serviceMTLSMode model.MutualTLSMode 1567 want *networking.ClientTLSSettings 1568 wantCtxType mtlsContextType 1569 }{ 1570 { 1571 "Destination rule TLS sni and SAN override", 1572 tlsSettings, 1573 []string{"spiffe://foo/serviceaccount/1"}, 1574 "foo.com", 1575 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1576 false, false, model.MTLSUnknown, 1577 tlsSettings, 1578 userSupplied, 1579 }, 1580 { 1581 "Metadata cert path override ISTIO_MUTUAL", 1582 tlsSettings, 1583 []string{"custom.foo.com"}, 1584 "custom.foo.com", 1585 &model.Proxy{Metadata: &model.NodeMetadata{ 1586 TLSClientCertChain: "/custom/chain.pem", 1587 TLSClientKey: "/custom/key.pem", 1588 TLSClientRootCert: "/custom/root.pem", 1589 }}, 1590 false, false, model.MTLSUnknown, 1591 &networking.ClientTLSSettings{ 1592 Mode: networking.ClientTLSSettings_MUTUAL, 1593 PrivateKey: "/custom/key.pem", 1594 ClientCertificate: "/custom/chain.pem", 1595 CaCertificates: "/custom/root.pem", 1596 SubjectAltNames: []string{"custom.foo.com"}, 1597 Sni: "custom.foo.com", 1598 }, 1599 userSupplied, 1600 }, 1601 { 1602 "Auto fill nil settings when mTLS nil for internal service in strict mode", 1603 nil, 1604 []string{"spiffe://foo/serviceaccount/1"}, 1605 "foo.com", 1606 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1607 true, false, model.MTLSStrict, 1608 &networking.ClientTLSSettings{ 1609 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 1610 SubjectAltNames: []string{"spiffe://foo/serviceaccount/1"}, 1611 Sni: "foo.com", 1612 }, 1613 autoDetected, 1614 }, 1615 { 1616 "Auto fill nil settings when mTLS nil for internal service in permissive mode", 1617 nil, 1618 []string{"spiffe://foo/serviceaccount/1"}, 1619 "foo.com", 1620 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1621 true, false, model.MTLSPermissive, 1622 &networking.ClientTLSSettings{ 1623 Mode: networking.ClientTLSSettings_ISTIO_MUTUAL, 1624 SubjectAltNames: []string{"spiffe://foo/serviceaccount/1"}, 1625 Sni: "foo.com", 1626 }, 1627 autoDetected, 1628 }, 1629 { 1630 "Auto fill nil settings when mTLS nil for internal service in plaintext mode", 1631 nil, 1632 []string{"spiffe://foo/serviceaccount/1"}, 1633 "foo.com", 1634 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1635 true, false, model.MTLSDisable, 1636 nil, 1637 userSupplied, 1638 }, 1639 { 1640 "Auto fill nil settings when mTLS nil for internal service in unknown mode", 1641 nil, 1642 []string{"spiffe://foo/serviceaccount/1"}, 1643 "foo.com", 1644 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1645 true, false, model.MTLSUnknown, 1646 nil, 1647 userSupplied, 1648 }, 1649 { 1650 "Do not auto fill nil settings for external", 1651 nil, 1652 []string{"spiffe://foo/serviceaccount/1"}, 1653 "foo.com", 1654 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1655 true, true, model.MTLSUnknown, 1656 nil, 1657 userSupplied, 1658 }, 1659 { 1660 "Do not auto fill nil settings if server mTLS is disabled", 1661 nil, 1662 []string{"spiffe://foo/serviceaccount/1"}, 1663 "foo.com", 1664 &model.Proxy{Metadata: &model.NodeMetadata{}}, 1665 false, false, model.MTLSDisable, 1666 nil, 1667 userSupplied, 1668 }, 1669 { 1670 "TLS nil auto build tls with metadata cert path", 1671 nil, 1672 []string{"spiffe://foo/serviceaccount/1"}, 1673 "foo.com", 1674 &model.Proxy{Metadata: &model.NodeMetadata{ 1675 TLSClientCertChain: "/custom/chain.pem", 1676 TLSClientKey: "/custom/key.pem", 1677 TLSClientRootCert: "/custom/root.pem", 1678 }}, 1679 true, false, model.MTLSPermissive, 1680 &networking.ClientTLSSettings{ 1681 Mode: networking.ClientTLSSettings_MUTUAL, 1682 ClientCertificate: "/custom/chain.pem", 1683 PrivateKey: "/custom/key.pem", 1684 CaCertificates: "/custom/root.pem", 1685 SubjectAltNames: []string{"spiffe://foo/serviceaccount/1"}, 1686 Sni: "foo.com", 1687 }, 1688 autoDetected, 1689 }, 1690 { 1691 "Simple TLS", 1692 &networking.ClientTLSSettings{ 1693 Mode: networking.ClientTLSSettings_SIMPLE, 1694 PrivateKey: "/custom/key.pem", 1695 ClientCertificate: "/custom/chain.pem", 1696 CaCertificates: "/custom/root.pem", 1697 }, 1698 []string{"custom.foo.com"}, 1699 "custom.foo.com", 1700 &model.Proxy{Metadata: &model.NodeMetadata{ 1701 TLSClientCertChain: "/custom/meta/chain.pem", 1702 TLSClientKey: "/custom/meta/key.pem", 1703 TLSClientRootCert: "/custom/meta/root.pem", 1704 }}, 1705 false, false, model.MTLSUnknown, 1706 &networking.ClientTLSSettings{ 1707 Mode: networking.ClientTLSSettings_SIMPLE, 1708 PrivateKey: "/custom/key.pem", 1709 ClientCertificate: "/custom/chain.pem", 1710 CaCertificates: "/custom/root.pem", 1711 }, 1712 userSupplied, 1713 }, 1714 } 1715 1716 for _, tt := range tests { 1717 t.Run(tt.name, func(t *testing.T) { 1718 cb := NewClusterBuilder(tt.proxy, nil, nil) 1719 gotTLS, gotCtxType := cb.buildUpstreamTLSSettings(tt.tls, tt.sans, tt.sni, tt.autoMTLSEnabled, tt.meshExternal, tt.serviceMTLSMode) 1720 if !reflect.DeepEqual(gotTLS, tt.want) { 1721 t.Errorf("cluster TLS does not match expected result want %#v, got %#v", tt.want, gotTLS) 1722 } 1723 if gotCtxType != tt.wantCtxType { 1724 t.Errorf("cluster TLS context type does not match expected result want %#v, got %#v", tt.wantCtxType, gotCtxType) 1725 } 1726 }) 1727 } 1728 }