istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/gateway_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 "reflect" 19 "sort" 20 "testing" 21 "time" 22 23 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 24 route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" 25 hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" 26 auth "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" 27 "github.com/google/go-cmp/cmp" 28 "github.com/google/uuid" 29 "google.golang.org/protobuf/testing/protocmp" 30 "google.golang.org/protobuf/types/known/durationpb" 31 wrappers "google.golang.org/protobuf/types/known/wrapperspb" 32 33 extensions "istio.io/api/extensions/v1alpha1" 34 meshconfig "istio.io/api/mesh/v1alpha1" 35 networking "istio.io/api/networking/v1alpha3" 36 security "istio.io/api/security/v1beta1" 37 telemetry "istio.io/api/telemetry/v1alpha1" 38 "istio.io/istio/pilot/pkg/features" 39 pilot_model "istio.io/istio/pilot/pkg/model" 40 istionetworking "istio.io/istio/pilot/pkg/networking" 41 "istio.io/istio/pilot/pkg/networking/core/listenertest" 42 istio_route "istio.io/istio/pilot/pkg/networking/core/route" 43 "istio.io/istio/pilot/pkg/networking/util" 44 "istio.io/istio/pilot/pkg/security/model" 45 xdsfilters "istio.io/istio/pilot/pkg/xds/filters" 46 "istio.io/istio/pilot/test/xdstest" 47 config "istio.io/istio/pkg/config" 48 "istio.io/istio/pkg/config/host" 49 "istio.io/istio/pkg/config/mesh" 50 "istio.io/istio/pkg/config/protocol" 51 "istio.io/istio/pkg/config/schema/gvk" 52 "istio.io/istio/pkg/config/visibility" 53 "istio.io/istio/pkg/config/xds" 54 "istio.io/istio/pkg/maps" 55 "istio.io/istio/pkg/proto" 56 "istio.io/istio/pkg/slices" 57 "istio.io/istio/pkg/test" 58 "istio.io/istio/pkg/util/sets" 59 "istio.io/istio/pkg/wellknown" 60 ) 61 62 func TestBuildGatewayListenerTlsContext(t *testing.T) { 63 testCases := []struct { 64 name string 65 server *networking.Server 66 result *auth.DownstreamTlsContext 67 transportProtocol istionetworking.TransportProtocol 68 mesh *meshconfig.MeshConfig 69 }{ 70 { 71 name: "mesh SDS enabled, tls mode ISTIO_MUTUAL", 72 server: &networking.Server{ 73 Hosts: []string{"httpbin.example.com"}, 74 Port: &networking.Port{ 75 Protocol: string(protocol.HTTPS), 76 }, 77 Tls: &networking.ServerTLSSettings{ 78 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 79 }, 80 }, 81 result: &auth.DownstreamTlsContext{ 82 CommonTlsContext: &auth.CommonTlsContext{ 83 AlpnProtocols: util.ALPNHttp, 84 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 85 { 86 Name: "default", 87 SdsConfig: &core.ConfigSource{ 88 InitialFetchTimeout: durationpb.New(time.Second * 0), 89 ResourceApiVersion: core.ApiVersion_V3, 90 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 91 ApiConfigSource: &core.ApiConfigSource{ 92 ApiType: core.ApiConfigSource_GRPC, 93 SetNodeOnFirstMessageOnly: true, 94 TransportApiVersion: core.ApiVersion_V3, 95 GrpcServices: []*core.GrpcService{ 96 { 97 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 98 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 99 }, 100 }, 101 }, 102 }, 103 }, 104 }, 105 }, 106 }, 107 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 108 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 109 DefaultValidationContext: &auth.CertificateValidationContext{}, 110 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 111 Name: "ROOTCA", 112 SdsConfig: &core.ConfigSource{ 113 InitialFetchTimeout: durationpb.New(time.Second * 0), 114 ResourceApiVersion: core.ApiVersion_V3, 115 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 116 ApiConfigSource: &core.ApiConfigSource{ 117 ApiType: core.ApiConfigSource_GRPC, 118 SetNodeOnFirstMessageOnly: true, 119 TransportApiVersion: core.ApiVersion_V3, 120 GrpcServices: []*core.GrpcService{ 121 { 122 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 123 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 124 }, 125 }, 126 }, 127 }, 128 }, 129 }, 130 }, 131 }, 132 }, 133 }, 134 RequireClientCertificate: proto.BoolTrue, 135 }, 136 }, 137 { 138 name: "mesh SDS enabled, tls mode ISTIO_MUTUAL, CRL specified", 139 server: &networking.Server{ 140 Hosts: []string{"httpbin.example.com"}, 141 Port: &networking.Port{ 142 Protocol: string(protocol.HTTPS), 143 }, 144 Tls: &networking.ServerTLSSettings{ 145 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 146 CaCrl: "/custom/path/to/crl.pem", 147 }, 148 }, 149 result: &auth.DownstreamTlsContext{ 150 CommonTlsContext: &auth.CommonTlsContext{ 151 AlpnProtocols: util.ALPNHttp, 152 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 153 { 154 Name: "default", 155 SdsConfig: &core.ConfigSource{ 156 InitialFetchTimeout: durationpb.New(time.Second * 0), 157 ResourceApiVersion: core.ApiVersion_V3, 158 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 159 ApiConfigSource: &core.ApiConfigSource{ 160 ApiType: core.ApiConfigSource_GRPC, 161 SetNodeOnFirstMessageOnly: true, 162 TransportApiVersion: core.ApiVersion_V3, 163 GrpcServices: []*core.GrpcService{ 164 { 165 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 166 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 167 }, 168 }, 169 }, 170 }, 171 }, 172 }, 173 }, 174 }, 175 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 176 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 177 DefaultValidationContext: &auth.CertificateValidationContext{ 178 Crl: &core.DataSource{ 179 Specifier: &core.DataSource_Filename{ 180 Filename: "/custom/path/to/crl.pem", 181 }, 182 }, 183 }, 184 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 185 Name: "ROOTCA", 186 SdsConfig: &core.ConfigSource{ 187 InitialFetchTimeout: durationpb.New(time.Second * 0), 188 ResourceApiVersion: core.ApiVersion_V3, 189 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 190 ApiConfigSource: &core.ApiConfigSource{ 191 ApiType: core.ApiConfigSource_GRPC, 192 SetNodeOnFirstMessageOnly: true, 193 TransportApiVersion: core.ApiVersion_V3, 194 GrpcServices: []*core.GrpcService{ 195 { 196 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 197 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 198 }, 199 }, 200 }, 201 }, 202 }, 203 }, 204 }, 205 }, 206 }, 207 }, 208 RequireClientCertificate: proto.BoolTrue, 209 }, 210 }, 211 { 212 // regression test for having both fields set. This is rejected in validation. 213 name: "tls mode ISTIO_MUTUAL, with credentialName", 214 server: &networking.Server{ 215 Hosts: []string{"httpbin.example.com"}, 216 Port: &networking.Port{ 217 Protocol: string(protocol.HTTPS), 218 }, 219 Tls: &networking.ServerTLSSettings{ 220 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 221 CredentialName: "ignored", 222 }, 223 }, 224 result: &auth.DownstreamTlsContext{ 225 CommonTlsContext: &auth.CommonTlsContext{ 226 AlpnProtocols: util.ALPNHttp, 227 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 228 { 229 Name: "default", 230 SdsConfig: &core.ConfigSource{ 231 InitialFetchTimeout: durationpb.New(time.Second * 0), 232 ResourceApiVersion: core.ApiVersion_V3, 233 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 234 ApiConfigSource: &core.ApiConfigSource{ 235 ApiType: core.ApiConfigSource_GRPC, 236 SetNodeOnFirstMessageOnly: true, 237 TransportApiVersion: core.ApiVersion_V3, 238 GrpcServices: []*core.GrpcService{ 239 { 240 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 241 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 242 }, 243 }, 244 }, 245 }, 246 }, 247 }, 248 }, 249 }, 250 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 251 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 252 DefaultValidationContext: &auth.CertificateValidationContext{}, 253 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 254 Name: "ROOTCA", 255 SdsConfig: &core.ConfigSource{ 256 InitialFetchTimeout: durationpb.New(time.Second * 0), 257 ResourceApiVersion: core.ApiVersion_V3, 258 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 259 ApiConfigSource: &core.ApiConfigSource{ 260 ApiType: core.ApiConfigSource_GRPC, 261 SetNodeOnFirstMessageOnly: true, 262 TransportApiVersion: core.ApiVersion_V3, 263 GrpcServices: []*core.GrpcService{ 264 { 265 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 266 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 267 }, 268 }, 269 }, 270 }, 271 }, 272 }, 273 }, 274 }, 275 }, 276 }, 277 RequireClientCertificate: proto.BoolTrue, 278 }, 279 }, 280 { // No credential name is specified, generate file paths for key/cert. 281 name: "no credential name no key no cert tls SIMPLE", 282 server: &networking.Server{ 283 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 284 Port: &networking.Port{ 285 Protocol: string(protocol.HTTPS), 286 }, 287 Tls: &networking.ServerTLSSettings{ 288 Mode: networking.ServerTLSSettings_SIMPLE, 289 }, 290 }, 291 result: &auth.DownstreamTlsContext{ 292 CommonTlsContext: &auth.CommonTlsContext{ 293 AlpnProtocols: util.ALPNHttp, 294 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 295 { 296 Name: "default", 297 SdsConfig: &core.ConfigSource{ 298 InitialFetchTimeout: durationpb.New(time.Second * 0), 299 ResourceApiVersion: core.ApiVersion_V3, 300 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 301 ApiConfigSource: &core.ApiConfigSource{ 302 ApiType: core.ApiConfigSource_GRPC, 303 SetNodeOnFirstMessageOnly: true, 304 TransportApiVersion: core.ApiVersion_V3, 305 GrpcServices: []*core.GrpcService{ 306 { 307 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 308 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 309 }, 310 }, 311 }, 312 }, 313 }, 314 }, 315 }, 316 }, 317 }, 318 RequireClientCertificate: proto.BoolFalse, 319 }, 320 }, 321 { // Credential name is specified, SDS config is generated for fetching key/cert. 322 name: "credential name no key no cert tls SIMPLE", 323 server: &networking.Server{ 324 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 325 Port: &networking.Port{ 326 Protocol: string(protocol.HTTPS), 327 }, 328 Tls: &networking.ServerTLSSettings{ 329 Mode: networking.ServerTLSSettings_SIMPLE, 330 CredentialName: "ingress-sds-resource-name", 331 }, 332 }, 333 result: &auth.DownstreamTlsContext{ 334 CommonTlsContext: &auth.CommonTlsContext{ 335 AlpnProtocols: util.ALPNHttp, 336 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 337 { 338 Name: "kubernetes://ingress-sds-resource-name", 339 SdsConfig: model.SDSAdsConfig, 340 }, 341 }, 342 }, 343 RequireClientCertificate: proto.BoolFalse, 344 }, 345 }, 346 { // Credential name and subject alternative names are specified, generate SDS configs for 347 // key/cert and static validation context config. 348 name: "credential name subject alternative name no key no cert tls SIMPLE", 349 server: &networking.Server{ 350 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 351 Port: &networking.Port{ 352 Protocol: string(protocol.HTTPS), 353 }, 354 Tls: &networking.ServerTLSSettings{ 355 Mode: networking.ServerTLSSettings_SIMPLE, 356 CredentialName: "ingress-sds-resource-name", 357 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 358 }, 359 }, 360 result: &auth.DownstreamTlsContext{ 361 CommonTlsContext: &auth.CommonTlsContext{ 362 AlpnProtocols: util.ALPNHttp, 363 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 364 { 365 Name: "kubernetes://ingress-sds-resource-name", 366 SdsConfig: model.SDSAdsConfig, 367 }, 368 }, 369 ValidationContextType: &auth.CommonTlsContext_ValidationContext{ 370 ValidationContext: &auth.CertificateValidationContext{ 371 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 372 }, 373 }, 374 }, 375 RequireClientCertificate: proto.BoolFalse, 376 }, 377 }, 378 { 379 name: "no credential name key and cert tls SIMPLE", 380 server: &networking.Server{ 381 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 382 Port: &networking.Port{ 383 Protocol: string(protocol.HTTPS), 384 }, 385 Tls: &networking.ServerTLSSettings{ 386 Mode: networking.ServerTLSSettings_SIMPLE, 387 ServerCertificate: "server-cert.crt", 388 PrivateKey: "private-key.key", 389 }, 390 }, 391 result: &auth.DownstreamTlsContext{ 392 CommonTlsContext: &auth.CommonTlsContext{ 393 AlpnProtocols: util.ALPNHttp, 394 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 395 { 396 Name: "file-cert:server-cert.crt~private-key.key", 397 SdsConfig: &core.ConfigSource{ 398 ResourceApiVersion: core.ApiVersion_V3, 399 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 400 ApiConfigSource: &core.ApiConfigSource{ 401 ApiType: core.ApiConfigSource_GRPC, 402 SetNodeOnFirstMessageOnly: true, 403 TransportApiVersion: core.ApiVersion_V3, 404 GrpcServices: []*core.GrpcService{ 405 { 406 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 407 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 408 }, 409 }, 410 }, 411 }, 412 }, 413 }, 414 }, 415 }, 416 }, 417 RequireClientCertificate: proto.BoolFalse, 418 }, 419 }, 420 { 421 name: "no credential name key and cert tls MUTUAL", 422 server: &networking.Server{ 423 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 424 Port: &networking.Port{ 425 Protocol: string(protocol.HTTPS), 426 }, 427 Tls: &networking.ServerTLSSettings{ 428 Mode: networking.ServerTLSSettings_MUTUAL, 429 ServerCertificate: "server-cert.crt", 430 PrivateKey: "private-key.key", 431 CaCertificates: "ca-cert.crt", 432 }, 433 }, 434 result: &auth.DownstreamTlsContext{ 435 CommonTlsContext: &auth.CommonTlsContext{ 436 AlpnProtocols: util.ALPNHttp, 437 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 438 { 439 Name: "file-cert:server-cert.crt~private-key.key", 440 SdsConfig: &core.ConfigSource{ 441 ResourceApiVersion: core.ApiVersion_V3, 442 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 443 ApiConfigSource: &core.ApiConfigSource{ 444 ApiType: core.ApiConfigSource_GRPC, 445 SetNodeOnFirstMessageOnly: true, 446 TransportApiVersion: core.ApiVersion_V3, 447 GrpcServices: []*core.GrpcService{ 448 { 449 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 450 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 451 }, 452 }, 453 }, 454 }, 455 }, 456 }, 457 }, 458 }, 459 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 460 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 461 DefaultValidationContext: &auth.CertificateValidationContext{}, 462 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 463 Name: "file-root:ca-cert.crt", 464 SdsConfig: &core.ConfigSource{ 465 ResourceApiVersion: core.ApiVersion_V3, 466 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 467 ApiConfigSource: &core.ApiConfigSource{ 468 ApiType: core.ApiConfigSource_GRPC, 469 SetNodeOnFirstMessageOnly: true, 470 TransportApiVersion: core.ApiVersion_V3, 471 GrpcServices: []*core.GrpcService{ 472 { 473 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 474 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 475 }, 476 }, 477 }, 478 }, 479 }, 480 }, 481 }, 482 }, 483 }, 484 }, 485 RequireClientCertificate: proto.BoolTrue, 486 }, 487 }, 488 { 489 name: "no credential name key and cert subject alt names tls MUTUAL", 490 server: &networking.Server{ 491 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 492 Port: &networking.Port{ 493 Protocol: string(protocol.HTTPS), 494 }, 495 Tls: &networking.ServerTLSSettings{ 496 Mode: networking.ServerTLSSettings_MUTUAL, 497 ServerCertificate: "server-cert.crt", 498 PrivateKey: "private-key.key", 499 CaCertificates: "ca-cert.crt", 500 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 501 }, 502 }, 503 result: &auth.DownstreamTlsContext{ 504 CommonTlsContext: &auth.CommonTlsContext{ 505 AlpnProtocols: util.ALPNHttp, 506 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 507 { 508 Name: "file-cert:server-cert.crt~private-key.key", 509 SdsConfig: &core.ConfigSource{ 510 ResourceApiVersion: core.ApiVersion_V3, 511 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 512 ApiConfigSource: &core.ApiConfigSource{ 513 ApiType: core.ApiConfigSource_GRPC, 514 SetNodeOnFirstMessageOnly: true, 515 TransportApiVersion: core.ApiVersion_V3, 516 GrpcServices: []*core.GrpcService{ 517 { 518 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 519 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 520 }, 521 }, 522 }, 523 }, 524 }, 525 }, 526 }, 527 }, 528 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 529 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 530 DefaultValidationContext: &auth.CertificateValidationContext{ 531 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 532 }, 533 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 534 Name: "file-root:ca-cert.crt", 535 SdsConfig: &core.ConfigSource{ 536 ResourceApiVersion: core.ApiVersion_V3, 537 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 538 ApiConfigSource: &core.ApiConfigSource{ 539 ApiType: core.ApiConfigSource_GRPC, 540 SetNodeOnFirstMessageOnly: true, 541 TransportApiVersion: core.ApiVersion_V3, 542 GrpcServices: []*core.GrpcService{ 543 { 544 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 545 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 546 }, 547 }, 548 }, 549 }, 550 }, 551 }, 552 }, 553 }, 554 }, 555 }, 556 RequireClientCertificate: proto.BoolTrue, 557 }, 558 }, 559 { 560 name: "no credential name key and cert subject alt names tls MUTUAL", 561 server: &networking.Server{ 562 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 563 Port: &networking.Port{ 564 Protocol: string(protocol.HTTPS), 565 }, 566 Tls: &networking.ServerTLSSettings{ 567 Mode: networking.ServerTLSSettings_MUTUAL, 568 ServerCertificate: "server-cert.crt", 569 PrivateKey: "private-key.key", 570 CaCertificates: "ca-cert.crt", 571 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 572 CaCrl: "/custom/path/to/crl.pem", 573 }, 574 }, 575 result: &auth.DownstreamTlsContext{ 576 CommonTlsContext: &auth.CommonTlsContext{ 577 AlpnProtocols: util.ALPNHttp, 578 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 579 { 580 Name: "file-cert:server-cert.crt~private-key.key", 581 SdsConfig: &core.ConfigSource{ 582 ResourceApiVersion: core.ApiVersion_V3, 583 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 584 ApiConfigSource: &core.ApiConfigSource{ 585 ApiType: core.ApiConfigSource_GRPC, 586 SetNodeOnFirstMessageOnly: true, 587 TransportApiVersion: core.ApiVersion_V3, 588 GrpcServices: []*core.GrpcService{ 589 { 590 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 591 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 592 }, 593 }, 594 }, 595 }, 596 }, 597 }, 598 }, 599 }, 600 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 601 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 602 DefaultValidationContext: &auth.CertificateValidationContext{ 603 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 604 Crl: &core.DataSource{ 605 Specifier: &core.DataSource_Filename{ 606 Filename: "/custom/path/to/crl.pem", 607 }, 608 }, 609 }, 610 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 611 Name: "file-root:ca-cert.crt", 612 SdsConfig: &core.ConfigSource{ 613 ResourceApiVersion: core.ApiVersion_V3, 614 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 615 ApiConfigSource: &core.ApiConfigSource{ 616 ApiType: core.ApiConfigSource_GRPC, 617 SetNodeOnFirstMessageOnly: true, 618 TransportApiVersion: core.ApiVersion_V3, 619 GrpcServices: []*core.GrpcService{ 620 { 621 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 622 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 623 }, 624 }, 625 }, 626 }, 627 }, 628 }, 629 }, 630 }, 631 }, 632 }, 633 RequireClientCertificate: proto.BoolTrue, 634 }, 635 }, 636 { 637 name: "no credential name key and cert subject alt names tls OPTIONAL_MUTUAL", 638 server: &networking.Server{ 639 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 640 Port: &networking.Port{ 641 Protocol: string(protocol.HTTPS), 642 }, 643 Tls: &networking.ServerTLSSettings{ 644 Mode: networking.ServerTLSSettings_OPTIONAL_MUTUAL, 645 ServerCertificate: "server-cert.crt", 646 PrivateKey: "private-key.key", 647 CaCertificates: "ca-cert.crt", 648 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 649 }, 650 }, 651 result: &auth.DownstreamTlsContext{ 652 CommonTlsContext: &auth.CommonTlsContext{ 653 AlpnProtocols: util.ALPNHttp, 654 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 655 { 656 Name: "file-cert:server-cert.crt~private-key.key", 657 SdsConfig: &core.ConfigSource{ 658 ResourceApiVersion: core.ApiVersion_V3, 659 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 660 ApiConfigSource: &core.ApiConfigSource{ 661 ApiType: core.ApiConfigSource_GRPC, 662 SetNodeOnFirstMessageOnly: true, 663 TransportApiVersion: core.ApiVersion_V3, 664 GrpcServices: []*core.GrpcService{ 665 { 666 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 667 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 668 }, 669 }, 670 }, 671 }, 672 }, 673 }, 674 }, 675 }, 676 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 677 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 678 DefaultValidationContext: &auth.CertificateValidationContext{ 679 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 680 }, 681 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 682 Name: "file-root:ca-cert.crt", 683 SdsConfig: &core.ConfigSource{ 684 ResourceApiVersion: core.ApiVersion_V3, 685 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 686 ApiConfigSource: &core.ApiConfigSource{ 687 ApiType: core.ApiConfigSource_GRPC, 688 SetNodeOnFirstMessageOnly: true, 689 TransportApiVersion: core.ApiVersion_V3, 690 GrpcServices: []*core.GrpcService{ 691 { 692 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 693 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 694 }, 695 }, 696 }, 697 }, 698 }, 699 }, 700 }, 701 }, 702 }, 703 }, 704 RequireClientCertificate: proto.BoolFalse, 705 }, 706 }, 707 { 708 name: "no credential name key and cert subject alt names tls OPTIONAL_MUTUAL", 709 server: &networking.Server{ 710 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 711 Port: &networking.Port{ 712 Protocol: string(protocol.HTTPS), 713 }, 714 Tls: &networking.ServerTLSSettings{ 715 Mode: networking.ServerTLSSettings_OPTIONAL_MUTUAL, 716 ServerCertificate: "server-cert.crt", 717 PrivateKey: "private-key.key", 718 CaCertificates: "ca-cert.crt", 719 CaCrl: "/custom/path/to/crl.pem", 720 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 721 }, 722 }, 723 result: &auth.DownstreamTlsContext{ 724 CommonTlsContext: &auth.CommonTlsContext{ 725 AlpnProtocols: util.ALPNHttp, 726 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 727 { 728 Name: "file-cert:server-cert.crt~private-key.key", 729 SdsConfig: &core.ConfigSource{ 730 ResourceApiVersion: core.ApiVersion_V3, 731 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 732 ApiConfigSource: &core.ApiConfigSource{ 733 ApiType: core.ApiConfigSource_GRPC, 734 SetNodeOnFirstMessageOnly: true, 735 TransportApiVersion: core.ApiVersion_V3, 736 GrpcServices: []*core.GrpcService{ 737 { 738 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 739 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 740 }, 741 }, 742 }, 743 }, 744 }, 745 }, 746 }, 747 }, 748 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 749 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 750 DefaultValidationContext: &auth.CertificateValidationContext{ 751 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 752 Crl: &core.DataSource{ 753 Specifier: &core.DataSource_Filename{ 754 Filename: "/custom/path/to/crl.pem", 755 }, 756 }, 757 }, 758 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 759 Name: "file-root:ca-cert.crt", 760 SdsConfig: &core.ConfigSource{ 761 ResourceApiVersion: core.ApiVersion_V3, 762 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 763 ApiConfigSource: &core.ApiConfigSource{ 764 ApiType: core.ApiConfigSource_GRPC, 765 SetNodeOnFirstMessageOnly: true, 766 TransportApiVersion: core.ApiVersion_V3, 767 GrpcServices: []*core.GrpcService{ 768 { 769 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 770 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 771 }, 772 }, 773 }, 774 }, 775 }, 776 }, 777 }, 778 }, 779 }, 780 }, 781 RequireClientCertificate: proto.BoolFalse, 782 }, 783 }, 784 { 785 // Credential name and subject names are specified, SDS configs are generated for fetching 786 // key/cert and root cert. 787 name: "credential name subject alternative name key and cert tls MUTUAL", 788 server: &networking.Server{ 789 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 790 Port: &networking.Port{ 791 Protocol: string(protocol.HTTPS), 792 }, 793 Tls: &networking.ServerTLSSettings{ 794 Mode: networking.ServerTLSSettings_MUTUAL, 795 CredentialName: "ingress-sds-resource-name", 796 ServerCertificate: "server-cert.crt", 797 PrivateKey: "private-key.key", 798 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 799 }, 800 }, 801 result: &auth.DownstreamTlsContext{ 802 CommonTlsContext: &auth.CommonTlsContext{ 803 AlpnProtocols: util.ALPNHttp, 804 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 805 { 806 Name: "kubernetes://ingress-sds-resource-name", 807 SdsConfig: model.SDSAdsConfig, 808 }, 809 }, 810 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 811 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 812 DefaultValidationContext: &auth.CertificateValidationContext{ 813 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 814 }, 815 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 816 Name: "kubernetes://ingress-sds-resource-name-cacert", 817 SdsConfig: model.SDSAdsConfig, 818 }, 819 }, 820 }, 821 }, 822 RequireClientCertificate: proto.BoolTrue, 823 }, 824 }, 825 { 826 // Credential name and subject names are specified, SDS configs are generated for fetching 827 // key/cert and root cert. 828 name: "credential name subject alternative name key and cert tls OPTIONAL_MUTUAL", 829 server: &networking.Server{ 830 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 831 Port: &networking.Port{ 832 Protocol: string(protocol.HTTPS), 833 }, 834 Tls: &networking.ServerTLSSettings{ 835 Mode: networking.ServerTLSSettings_OPTIONAL_MUTUAL, 836 CredentialName: "ingress-sds-resource-name", 837 ServerCertificate: "server-cert.crt", 838 PrivateKey: "private-key.key", 839 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 840 }, 841 }, 842 result: &auth.DownstreamTlsContext{ 843 CommonTlsContext: &auth.CommonTlsContext{ 844 AlpnProtocols: util.ALPNHttp, 845 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 846 { 847 Name: "kubernetes://ingress-sds-resource-name", 848 SdsConfig: model.SDSAdsConfig, 849 }, 850 }, 851 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 852 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 853 DefaultValidationContext: &auth.CertificateValidationContext{ 854 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 855 }, 856 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 857 Name: "kubernetes://ingress-sds-resource-name-cacert", 858 SdsConfig: model.SDSAdsConfig, 859 }, 860 }, 861 }, 862 }, 863 RequireClientCertificate: proto.BoolFalse, 864 }, 865 }, 866 { 867 // Credential name and VerifyCertificateSpki options are specified, SDS configs are generated for fetching 868 // key/cert and root cert 869 name: "credential name verify spki key and cert tls MUTUAL", 870 server: &networking.Server{ 871 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 872 Port: &networking.Port{ 873 Protocol: string(protocol.HTTPS), 874 }, 875 Tls: &networking.ServerTLSSettings{ 876 Mode: networking.ServerTLSSettings_MUTUAL, 877 CredentialName: "ingress-sds-resource-name", 878 VerifyCertificateSpki: []string{"abcdef"}, 879 }, 880 }, 881 result: &auth.DownstreamTlsContext{ 882 CommonTlsContext: &auth.CommonTlsContext{ 883 AlpnProtocols: util.ALPNHttp, 884 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 885 { 886 Name: "kubernetes://ingress-sds-resource-name", 887 SdsConfig: model.SDSAdsConfig, 888 }, 889 }, 890 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 891 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 892 DefaultValidationContext: &auth.CertificateValidationContext{ 893 VerifyCertificateSpki: []string{"abcdef"}, 894 }, 895 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 896 Name: "kubernetes://ingress-sds-resource-name-cacert", 897 SdsConfig: model.SDSAdsConfig, 898 }, 899 }, 900 }, 901 }, 902 RequireClientCertificate: proto.BoolTrue, 903 }, 904 }, 905 { 906 // Credential name and VerifyCertificateHash options are specified, SDS configs are generated for fetching 907 // key/cert and root cert 908 name: "credential name verify hash key and cert tls MUTUAL", 909 server: &networking.Server{ 910 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 911 Port: &networking.Port{ 912 Protocol: string(protocol.HTTPS), 913 }, 914 Tls: &networking.ServerTLSSettings{ 915 Mode: networking.ServerTLSSettings_MUTUAL, 916 CredentialName: "ingress-sds-resource-name", 917 VerifyCertificateHash: []string{"fedcba"}, 918 }, 919 }, 920 result: &auth.DownstreamTlsContext{ 921 CommonTlsContext: &auth.CommonTlsContext{ 922 AlpnProtocols: util.ALPNHttp, 923 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 924 { 925 Name: "kubernetes://ingress-sds-resource-name", 926 SdsConfig: model.SDSAdsConfig, 927 }, 928 }, 929 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 930 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 931 DefaultValidationContext: &auth.CertificateValidationContext{ 932 VerifyCertificateHash: []string{"fedcba"}, 933 }, 934 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 935 Name: "kubernetes://ingress-sds-resource-name-cacert", 936 SdsConfig: model.SDSAdsConfig, 937 }, 938 }, 939 }, 940 }, 941 RequireClientCertificate: proto.BoolTrue, 942 }, 943 }, 944 { 945 name: "no credential name key and cert tls PASSTHROUGH", 946 server: &networking.Server{ 947 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 948 Port: &networking.Port{ 949 Protocol: string(protocol.HTTPS), 950 }, 951 Tls: &networking.ServerTLSSettings{ 952 Mode: networking.ServerTLSSettings_PASSTHROUGH, 953 ServerCertificate: "server-cert.crt", 954 PrivateKey: "private-key.key", 955 }, 956 }, 957 result: nil, 958 }, 959 { 960 name: "Downstream TLS settings for QUIC transport", 961 server: &networking.Server{ 962 Hosts: []string{"httpbin.example.com"}, 963 Port: &networking.Port{ 964 Protocol: string(protocol.HTTPS), 965 }, 966 Tls: &networking.ServerTLSSettings{ 967 Mode: networking.ServerTLSSettings_SIMPLE, 968 CredentialName: "httpbin-cred", 969 }, 970 }, 971 transportProtocol: istionetworking.TransportProtocolQUIC, 972 result: &auth.DownstreamTlsContext{ 973 CommonTlsContext: &auth.CommonTlsContext{ 974 AlpnProtocols: util.ALPNHttp3OverQUIC, 975 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 976 { 977 Name: "kubernetes://httpbin-cred", 978 SdsConfig: model.SDSAdsConfig, 979 }, 980 }, 981 }, 982 RequireClientCertificate: proto.BoolFalse, 983 }, 984 }, 985 { 986 name: "duplicated cipher suites with tls SIMPLE", 987 server: &networking.Server{ 988 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 989 Port: &networking.Port{ 990 Protocol: string(protocol.HTTPS), 991 }, 992 Tls: &networking.ServerTLSSettings{ 993 Mode: networking.ServerTLSSettings_SIMPLE, 994 ServerCertificate: "server-cert.crt", 995 PrivateKey: "private-key.key", 996 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-ECDSA-AES128-SHA"}, 997 }, 998 }, 999 result: &auth.DownstreamTlsContext{ 1000 CommonTlsContext: &auth.CommonTlsContext{ 1001 AlpnProtocols: util.ALPNHttp, 1002 TlsParams: &auth.TlsParameters{ 1003 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"}, 1004 }, 1005 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1006 { 1007 Name: "file-cert:server-cert.crt~private-key.key", 1008 SdsConfig: &core.ConfigSource{ 1009 ResourceApiVersion: core.ApiVersion_V3, 1010 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1011 ApiConfigSource: &core.ApiConfigSource{ 1012 ApiType: core.ApiConfigSource_GRPC, 1013 SetNodeOnFirstMessageOnly: true, 1014 TransportApiVersion: core.ApiVersion_V3, 1015 GrpcServices: []*core.GrpcService{ 1016 { 1017 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1018 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1019 }, 1020 }, 1021 }, 1022 }, 1023 }, 1024 }, 1025 }, 1026 }, 1027 }, 1028 RequireClientCertificate: proto.BoolFalse, 1029 }, 1030 }, 1031 { 1032 name: "ecdh curves and cipher suites specified in mesh config with tls SIMPLE", 1033 server: &networking.Server{ 1034 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 1035 Port: &networking.Port{ 1036 Protocol: string(protocol.HTTPS), 1037 }, 1038 Tls: &networking.ServerTLSSettings{ 1039 Mode: networking.ServerTLSSettings_SIMPLE, 1040 ServerCertificate: "server-cert.crt", 1041 PrivateKey: "private-key.key", 1042 }, 1043 }, 1044 mesh: &meshconfig.MeshConfig{ 1045 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1046 EcdhCurves: []string{"P-256"}, 1047 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"}, 1048 }, 1049 }, 1050 result: &auth.DownstreamTlsContext{ 1051 CommonTlsContext: &auth.CommonTlsContext{ 1052 AlpnProtocols: util.ALPNHttp, 1053 TlsParams: &auth.TlsParameters{ 1054 EcdhCurves: []string{"P-256"}, 1055 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"}, 1056 }, 1057 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1058 { 1059 Name: "file-cert:server-cert.crt~private-key.key", 1060 SdsConfig: &core.ConfigSource{ 1061 ResourceApiVersion: core.ApiVersion_V3, 1062 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1063 ApiConfigSource: &core.ApiConfigSource{ 1064 ApiType: core.ApiConfigSource_GRPC, 1065 SetNodeOnFirstMessageOnly: true, 1066 TransportApiVersion: core.ApiVersion_V3, 1067 GrpcServices: []*core.GrpcService{ 1068 { 1069 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1070 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1071 }, 1072 }, 1073 }, 1074 }, 1075 }, 1076 }, 1077 }, 1078 }, 1079 }, 1080 RequireClientCertificate: proto.BoolFalse, 1081 }, 1082 }, 1083 { 1084 name: "ecdh curves and cipher suites specified in mesh config with, tls mode ISTIO_MUTUAL", 1085 server: &networking.Server{ 1086 Hosts: []string{"httpbin.example.com"}, 1087 Port: &networking.Port{ 1088 Protocol: string(protocol.HTTPS), 1089 }, 1090 Tls: &networking.ServerTLSSettings{ 1091 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1092 }, 1093 }, 1094 mesh: &meshconfig.MeshConfig{ 1095 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1096 EcdhCurves: []string{"P-256"}, 1097 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"}, 1098 }, 1099 }, 1100 result: &auth.DownstreamTlsContext{ 1101 CommonTlsContext: &auth.CommonTlsContext{ 1102 AlpnProtocols: util.ALPNHttp, 1103 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1104 { 1105 Name: "default", 1106 SdsConfig: &core.ConfigSource{ 1107 InitialFetchTimeout: durationpb.New(time.Second * 0), 1108 ResourceApiVersion: core.ApiVersion_V3, 1109 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1110 ApiConfigSource: &core.ApiConfigSource{ 1111 ApiType: core.ApiConfigSource_GRPC, 1112 SetNodeOnFirstMessageOnly: true, 1113 TransportApiVersion: core.ApiVersion_V3, 1114 GrpcServices: []*core.GrpcService{ 1115 { 1116 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1117 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1118 }, 1119 }, 1120 }, 1121 }, 1122 }, 1123 }, 1124 }, 1125 }, 1126 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1127 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1128 DefaultValidationContext: &auth.CertificateValidationContext{}, 1129 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1130 Name: "ROOTCA", 1131 SdsConfig: &core.ConfigSource{ 1132 InitialFetchTimeout: durationpb.New(time.Second * 0), 1133 ResourceApiVersion: core.ApiVersion_V3, 1134 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1135 ApiConfigSource: &core.ApiConfigSource{ 1136 ApiType: core.ApiConfigSource_GRPC, 1137 SetNodeOnFirstMessageOnly: true, 1138 TransportApiVersion: core.ApiVersion_V3, 1139 GrpcServices: []*core.GrpcService{ 1140 { 1141 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1142 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1143 }, 1144 }, 1145 }, 1146 }, 1147 }, 1148 }, 1149 }, 1150 }, 1151 }, 1152 }, 1153 RequireClientCertificate: proto.BoolTrue, 1154 }, 1155 }, 1156 { 1157 name: "ecdh curves and cipher suites specified in mesh config with tls MUTUAL", 1158 server: &networking.Server{ 1159 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 1160 Port: &networking.Port{ 1161 Protocol: string(protocol.HTTPS), 1162 }, 1163 Tls: &networking.ServerTLSSettings{ 1164 Mode: networking.ServerTLSSettings_MUTUAL, 1165 CredentialName: "ingress-sds-resource-name", 1166 ServerCertificate: "server-cert.crt", 1167 PrivateKey: "private-key.key", 1168 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 1169 }, 1170 }, 1171 mesh: &meshconfig.MeshConfig{ 1172 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1173 EcdhCurves: []string{"P-256", "P-384"}, 1174 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"}, 1175 }, 1176 }, 1177 result: &auth.DownstreamTlsContext{ 1178 CommonTlsContext: &auth.CommonTlsContext{ 1179 TlsParams: &auth.TlsParameters{ 1180 EcdhCurves: []string{"P-256", "P-384"}, 1181 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"}, 1182 }, 1183 AlpnProtocols: util.ALPNHttp, 1184 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1185 { 1186 Name: "kubernetes://ingress-sds-resource-name", 1187 SdsConfig: model.SDSAdsConfig, 1188 }, 1189 }, 1190 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1191 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1192 DefaultValidationContext: &auth.CertificateValidationContext{ 1193 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 1194 }, 1195 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1196 Name: "kubernetes://ingress-sds-resource-name-cacert", 1197 SdsConfig: model.SDSAdsConfig, 1198 }, 1199 }, 1200 }, 1201 }, 1202 RequireClientCertificate: proto.BoolTrue, 1203 }, 1204 }, 1205 { 1206 name: "ecdh curves and cipher suites specified in mesh config with tls OPTIONAL MUTUAL", 1207 server: &networking.Server{ 1208 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 1209 Port: &networking.Port{ 1210 Protocol: string(protocol.HTTPS), 1211 }, 1212 Tls: &networking.ServerTLSSettings{ 1213 Mode: networking.ServerTLSSettings_OPTIONAL_MUTUAL, 1214 CredentialName: "ingress-sds-resource-name", 1215 ServerCertificate: "server-cert.crt", 1216 PrivateKey: "private-key.key", 1217 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 1218 }, 1219 }, 1220 mesh: &meshconfig.MeshConfig{ 1221 TlsDefaults: &meshconfig.MeshConfig_TLSConfig{ 1222 EcdhCurves: []string{"P-256", "P-384"}, 1223 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"}, 1224 }, 1225 }, 1226 result: &auth.DownstreamTlsContext{ 1227 CommonTlsContext: &auth.CommonTlsContext{ 1228 TlsParams: &auth.TlsParameters{ 1229 EcdhCurves: []string{"P-256", "P-384"}, 1230 CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"}, 1231 }, 1232 AlpnProtocols: util.ALPNHttp, 1233 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1234 { 1235 Name: "kubernetes://ingress-sds-resource-name", 1236 SdsConfig: model.SDSAdsConfig, 1237 }, 1238 }, 1239 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1240 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1241 DefaultValidationContext: &auth.CertificateValidationContext{ 1242 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 1243 }, 1244 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1245 Name: "kubernetes://ingress-sds-resource-name-cacert", 1246 SdsConfig: model.SDSAdsConfig, 1247 }, 1248 }, 1249 }, 1250 }, 1251 RequireClientCertificate: proto.BoolFalse, 1252 }, 1253 }, 1254 { 1255 // tcp server is non-istio mtls, no istio-peer-exchange in the alpns 1256 name: "tcp server with terminating (non-istio)mutual tls", 1257 server: &networking.Server{ 1258 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 1259 Port: &networking.Port{ 1260 Protocol: string(protocol.TLS), 1261 }, 1262 Tls: &networking.ServerTLSSettings{ 1263 Mode: networking.ServerTLSSettings_MUTUAL, 1264 ServerCertificate: "server-cert.crt", 1265 PrivateKey: "private-key.key", 1266 CaCertificates: "ca-cert.crt", 1267 SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"}, 1268 }, 1269 }, 1270 result: &auth.DownstreamTlsContext{ 1271 CommonTlsContext: &auth.CommonTlsContext{ 1272 AlpnProtocols: util.ALPNHttp, 1273 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1274 { 1275 Name: "file-cert:server-cert.crt~private-key.key", 1276 SdsConfig: &core.ConfigSource{ 1277 ResourceApiVersion: core.ApiVersion_V3, 1278 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1279 ApiConfigSource: &core.ApiConfigSource{ 1280 ApiType: core.ApiConfigSource_GRPC, 1281 SetNodeOnFirstMessageOnly: true, 1282 TransportApiVersion: core.ApiVersion_V3, 1283 GrpcServices: []*core.GrpcService{ 1284 { 1285 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1286 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1287 }, 1288 }, 1289 }, 1290 }, 1291 }, 1292 }, 1293 }, 1294 }, 1295 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1296 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1297 DefaultValidationContext: &auth.CertificateValidationContext{ 1298 MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}), 1299 }, 1300 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1301 Name: "file-root:ca-cert.crt", 1302 SdsConfig: &core.ConfigSource{ 1303 ResourceApiVersion: core.ApiVersion_V3, 1304 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1305 ApiConfigSource: &core.ApiConfigSource{ 1306 ApiType: core.ApiConfigSource_GRPC, 1307 SetNodeOnFirstMessageOnly: true, 1308 TransportApiVersion: core.ApiVersion_V3, 1309 GrpcServices: []*core.GrpcService{ 1310 { 1311 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1312 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1313 }, 1314 }, 1315 }, 1316 }, 1317 }, 1318 }, 1319 }, 1320 }, 1321 }, 1322 }, 1323 RequireClientCertificate: proto.BoolTrue, 1324 }, 1325 }, 1326 { 1327 // tcp server is istio mtls, istio-peer-exchange in the alpns 1328 name: "mesh SDS enabled, tcp server, tls mode ISTIO_MUTUAL", 1329 server: &networking.Server{ 1330 Hosts: []string{"httpbin.example.com"}, 1331 Port: &networking.Port{ 1332 Protocol: string(protocol.TLS), 1333 }, 1334 Tls: &networking.ServerTLSSettings{ 1335 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1336 }, 1337 }, 1338 result: &auth.DownstreamTlsContext{ 1339 CommonTlsContext: &auth.CommonTlsContext{ 1340 AlpnProtocols: util.ALPNDownstreamWithMxc, 1341 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1342 { 1343 Name: "default", 1344 SdsConfig: &core.ConfigSource{ 1345 InitialFetchTimeout: durationpb.New(time.Second * 0), 1346 ResourceApiVersion: core.ApiVersion_V3, 1347 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1348 ApiConfigSource: &core.ApiConfigSource{ 1349 ApiType: core.ApiConfigSource_GRPC, 1350 SetNodeOnFirstMessageOnly: true, 1351 TransportApiVersion: core.ApiVersion_V3, 1352 GrpcServices: []*core.GrpcService{ 1353 { 1354 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1355 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1356 }, 1357 }, 1358 }, 1359 }, 1360 }, 1361 }, 1362 }, 1363 }, 1364 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1365 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1366 DefaultValidationContext: &auth.CertificateValidationContext{}, 1367 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1368 Name: "ROOTCA", 1369 SdsConfig: &core.ConfigSource{ 1370 InitialFetchTimeout: durationpb.New(time.Second * 0), 1371 ResourceApiVersion: core.ApiVersion_V3, 1372 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1373 ApiConfigSource: &core.ApiConfigSource{ 1374 ApiType: core.ApiConfigSource_GRPC, 1375 SetNodeOnFirstMessageOnly: true, 1376 TransportApiVersion: core.ApiVersion_V3, 1377 GrpcServices: []*core.GrpcService{ 1378 { 1379 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1380 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1381 }, 1382 }, 1383 }, 1384 }, 1385 }, 1386 }, 1387 }, 1388 }, 1389 }, 1390 }, 1391 RequireClientCertificate: proto.BoolTrue, 1392 }, 1393 }, 1394 { 1395 // tcp server is simple tls, no istio-peer-exchange in the alpns 1396 name: "tcp server, tls SIMPLE", 1397 server: &networking.Server{ 1398 Hosts: []string{"httpbin.example.com", "bookinfo.example.com"}, 1399 Port: &networking.Port{ 1400 Protocol: string(protocol.TLS), 1401 }, 1402 Tls: &networking.ServerTLSSettings{ 1403 Mode: networking.ServerTLSSettings_SIMPLE, 1404 CredentialName: "ingress-sds-resource-name", 1405 }, 1406 }, 1407 result: &auth.DownstreamTlsContext{ 1408 CommonTlsContext: &auth.CommonTlsContext{ 1409 AlpnProtocols: util.ALPNHttp, 1410 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1411 { 1412 Name: "kubernetes://ingress-sds-resource-name", 1413 SdsConfig: model.SDSAdsConfig, 1414 }, 1415 }, 1416 }, 1417 RequireClientCertificate: proto.BoolFalse, 1418 }, 1419 }, 1420 } 1421 1422 for _, tc := range testCases { 1423 t.Run(tc.name, func(t *testing.T) { 1424 ret := buildGatewayListenerTLSContext(tc.mesh, tc.server, &pilot_model.Proxy{ 1425 Metadata: &pilot_model.NodeMetadata{}, 1426 }, tc.transportProtocol) 1427 if diff := cmp.Diff(tc.result, ret, protocmp.Transform()); diff != "" { 1428 t.Errorf("got diff: %v", diff) 1429 } 1430 }) 1431 } 1432 } 1433 1434 func TestCreateGatewayHTTPFilterChainOpts(t *testing.T) { 1435 cg := NewConfigGenTest(t, TestOptions{}) 1436 testCases := []struct { 1437 name string 1438 node *pilot_model.Proxy 1439 server *networking.Server 1440 routeName string 1441 proxyConfig *meshconfig.ProxyConfig 1442 result *filterChainOpts 1443 transportProtocol istionetworking.TransportProtocol 1444 }{ 1445 { 1446 name: "HTTP1.0 mode enabled", 1447 node: &pilot_model.Proxy{ 1448 Metadata: &pilot_model.NodeMetadata{HTTP10: "1"}, 1449 }, 1450 server: &networking.Server{ 1451 Port: &networking.Port{ 1452 Protocol: protocol.HTTP.String(), 1453 }, 1454 }, 1455 routeName: "some-route", 1456 proxyConfig: nil, 1457 result: &filterChainOpts{ 1458 sniHosts: nil, 1459 tlsContext: nil, 1460 httpOpts: &httpListenerOpts{ 1461 rds: "some-route", 1462 useRemoteAddress: true, 1463 connectionManager: &hcm.HttpConnectionManager{ 1464 XffNumTrustedHops: 0, 1465 ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET, 1466 SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{ 1467 Subject: proto.BoolTrue, 1468 Cert: true, 1469 Uri: true, 1470 Dns: true, 1471 }, 1472 ServerName: EnvoyServerName, 1473 HttpProtocolOptions: &core.Http1ProtocolOptions{ 1474 AcceptHttp_10: true, 1475 }, 1476 Proxy_100Continue: true, 1477 }, 1478 class: istionetworking.ListenerClassGateway, 1479 protocol: protocol.HTTP, 1480 }, 1481 }, 1482 }, 1483 { 1484 name: "Duplicate hosts in TLS filterChain", 1485 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1486 server: &networking.Server{ 1487 Port: &networking.Port{ 1488 Protocol: "HTTPS", 1489 }, 1490 Hosts: []string{"example.org", "example.org"}, 1491 Tls: &networking.ServerTLSSettings{ 1492 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1493 }, 1494 }, 1495 routeName: "some-route", 1496 proxyConfig: nil, 1497 result: &filterChainOpts{ 1498 sniHosts: []string{"example.org"}, 1499 tlsContext: &auth.DownstreamTlsContext{ 1500 CommonTlsContext: &auth.CommonTlsContext{ 1501 AlpnProtocols: util.ALPNHttp, 1502 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1503 { 1504 Name: "default", 1505 SdsConfig: &core.ConfigSource{ 1506 ResourceApiVersion: core.ApiVersion_V3, 1507 InitialFetchTimeout: durationpb.New(time.Second * 0), 1508 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1509 ApiConfigSource: &core.ApiConfigSource{ 1510 ApiType: core.ApiConfigSource_GRPC, 1511 SetNodeOnFirstMessageOnly: true, 1512 TransportApiVersion: core.ApiVersion_V3, 1513 GrpcServices: []*core.GrpcService{ 1514 { 1515 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1516 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1517 }, 1518 }, 1519 }, 1520 }, 1521 }, 1522 }, 1523 }, 1524 }, 1525 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1526 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1527 DefaultValidationContext: &auth.CertificateValidationContext{}, 1528 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1529 Name: "ROOTCA", 1530 SdsConfig: &core.ConfigSource{ 1531 ResourceApiVersion: core.ApiVersion_V3, 1532 InitialFetchTimeout: durationpb.New(time.Second * 0), 1533 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1534 ApiConfigSource: &core.ApiConfigSource{ 1535 ApiType: core.ApiConfigSource_GRPC, 1536 SetNodeOnFirstMessageOnly: true, 1537 TransportApiVersion: core.ApiVersion_V3, 1538 GrpcServices: []*core.GrpcService{ 1539 { 1540 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1541 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1542 }, 1543 }, 1544 }, 1545 }, 1546 }, 1547 }, 1548 }, 1549 }, 1550 }, 1551 }, 1552 RequireClientCertificate: proto.BoolTrue, 1553 }, 1554 httpOpts: &httpListenerOpts{ 1555 rds: "some-route", 1556 useRemoteAddress: true, 1557 connectionManager: &hcm.HttpConnectionManager{ 1558 XffNumTrustedHops: 0, 1559 ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET, 1560 SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{ 1561 Subject: proto.BoolTrue, 1562 Cert: true, 1563 Uri: true, 1564 Dns: true, 1565 }, 1566 ServerName: EnvoyServerName, 1567 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1568 Proxy_100Continue: true, 1569 }, 1570 class: istionetworking.ListenerClassGateway, 1571 protocol: protocol.HTTPS, 1572 }, 1573 }, 1574 }, 1575 { 1576 name: "Unique hosts in TLS filterChain", 1577 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1578 server: &networking.Server{ 1579 Port: &networking.Port{ 1580 Protocol: "HTTPS", 1581 }, 1582 Hosts: []string{"example.org", "test.org"}, 1583 Tls: &networking.ServerTLSSettings{ 1584 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1585 }, 1586 }, 1587 routeName: "some-route", 1588 proxyConfig: nil, 1589 result: &filterChainOpts{ 1590 sniHosts: []string{"example.org", "test.org"}, 1591 tlsContext: &auth.DownstreamTlsContext{ 1592 CommonTlsContext: &auth.CommonTlsContext{ 1593 AlpnProtocols: util.ALPNHttp, 1594 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1595 { 1596 Name: "default", 1597 SdsConfig: &core.ConfigSource{ 1598 ResourceApiVersion: core.ApiVersion_V3, 1599 InitialFetchTimeout: durationpb.New(time.Second * 0), 1600 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1601 ApiConfigSource: &core.ApiConfigSource{ 1602 ApiType: core.ApiConfigSource_GRPC, 1603 SetNodeOnFirstMessageOnly: true, 1604 TransportApiVersion: core.ApiVersion_V3, 1605 GrpcServices: []*core.GrpcService{ 1606 { 1607 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1608 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1609 }, 1610 }, 1611 }, 1612 }, 1613 }, 1614 }, 1615 }, 1616 }, 1617 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1618 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1619 DefaultValidationContext: &auth.CertificateValidationContext{}, 1620 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1621 Name: "ROOTCA", 1622 SdsConfig: &core.ConfigSource{ 1623 ResourceApiVersion: core.ApiVersion_V3, 1624 InitialFetchTimeout: durationpb.New(time.Second * 0), 1625 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1626 ApiConfigSource: &core.ApiConfigSource{ 1627 ApiType: core.ApiConfigSource_GRPC, 1628 SetNodeOnFirstMessageOnly: true, 1629 TransportApiVersion: core.ApiVersion_V3, 1630 GrpcServices: []*core.GrpcService{ 1631 { 1632 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1633 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1634 }, 1635 }, 1636 }, 1637 }, 1638 }, 1639 }, 1640 }, 1641 }, 1642 }, 1643 }, 1644 RequireClientCertificate: proto.BoolTrue, 1645 }, 1646 httpOpts: &httpListenerOpts{ 1647 rds: "some-route", 1648 useRemoteAddress: true, 1649 connectionManager: &hcm.HttpConnectionManager{ 1650 XffNumTrustedHops: 0, 1651 ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET, 1652 SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{ 1653 Subject: proto.BoolTrue, 1654 Cert: true, 1655 Uri: true, 1656 Dns: true, 1657 }, 1658 ServerName: EnvoyServerName, 1659 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1660 Proxy_100Continue: true, 1661 }, 1662 class: istionetworking.ListenerClassGateway, 1663 protocol: protocol.HTTPS, 1664 }, 1665 }, 1666 }, 1667 { 1668 name: "Wildcard hosts in TLS filterChain are not duplicates", 1669 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1670 server: &networking.Server{ 1671 Port: &networking.Port{ 1672 Protocol: "HTTPS", 1673 }, 1674 Hosts: []string{"*.example.org", "example.org"}, 1675 Tls: &networking.ServerTLSSettings{ 1676 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1677 }, 1678 }, 1679 routeName: "some-route", 1680 proxyConfig: nil, 1681 result: &filterChainOpts{ 1682 sniHosts: []string{"*.example.org", "example.org"}, 1683 tlsContext: &auth.DownstreamTlsContext{ 1684 CommonTlsContext: &auth.CommonTlsContext{ 1685 AlpnProtocols: util.ALPNHttp, 1686 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1687 { 1688 Name: "default", 1689 SdsConfig: &core.ConfigSource{ 1690 ResourceApiVersion: core.ApiVersion_V3, 1691 InitialFetchTimeout: durationpb.New(time.Second * 0), 1692 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1693 ApiConfigSource: &core.ApiConfigSource{ 1694 ApiType: core.ApiConfigSource_GRPC, 1695 SetNodeOnFirstMessageOnly: true, 1696 TransportApiVersion: core.ApiVersion_V3, 1697 GrpcServices: []*core.GrpcService{ 1698 { 1699 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1700 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1701 }, 1702 }, 1703 }, 1704 }, 1705 }, 1706 }, 1707 }, 1708 }, 1709 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1710 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1711 DefaultValidationContext: &auth.CertificateValidationContext{}, 1712 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1713 Name: "ROOTCA", 1714 SdsConfig: &core.ConfigSource{ 1715 ResourceApiVersion: core.ApiVersion_V3, 1716 InitialFetchTimeout: durationpb.New(time.Second * 0), 1717 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1718 ApiConfigSource: &core.ApiConfigSource{ 1719 ApiType: core.ApiConfigSource_GRPC, 1720 SetNodeOnFirstMessageOnly: true, 1721 TransportApiVersion: core.ApiVersion_V3, 1722 GrpcServices: []*core.GrpcService{ 1723 { 1724 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1725 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1726 }, 1727 }, 1728 }, 1729 }, 1730 }, 1731 }, 1732 }, 1733 }, 1734 }, 1735 }, 1736 RequireClientCertificate: proto.BoolTrue, 1737 }, 1738 httpOpts: &httpListenerOpts{ 1739 rds: "some-route", 1740 useRemoteAddress: true, 1741 connectionManager: &hcm.HttpConnectionManager{ 1742 XffNumTrustedHops: 0, 1743 ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET, 1744 SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{ 1745 Subject: proto.BoolTrue, 1746 Cert: true, 1747 Uri: true, 1748 Dns: true, 1749 }, 1750 ServerName: EnvoyServerName, 1751 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1752 Proxy_100Continue: true, 1753 }, 1754 class: istionetworking.ListenerClassGateway, 1755 protocol: protocol.HTTPS, 1756 }, 1757 }, 1758 }, 1759 { 1760 name: "Topology HTTP Protocol", 1761 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1762 server: &networking.Server{ 1763 Port: &networking.Port{ 1764 Protocol: protocol.HTTP.String(), 1765 }, 1766 }, 1767 routeName: "some-route", 1768 proxyConfig: &meshconfig.ProxyConfig{ 1769 GatewayTopology: &meshconfig.Topology{ 1770 NumTrustedProxies: 2, 1771 ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_APPEND_FORWARD, 1772 }, 1773 }, 1774 result: &filterChainOpts{ 1775 sniHosts: nil, 1776 tlsContext: nil, 1777 httpOpts: &httpListenerOpts{ 1778 rds: "some-route", 1779 useRemoteAddress: true, 1780 connectionManager: &hcm.HttpConnectionManager{ 1781 XffNumTrustedHops: 2, 1782 ForwardClientCertDetails: hcm.HttpConnectionManager_APPEND_FORWARD, 1783 SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{ 1784 Subject: proto.BoolTrue, 1785 Cert: true, 1786 Uri: true, 1787 Dns: true, 1788 }, 1789 ServerName: EnvoyServerName, 1790 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1791 Proxy_100Continue: true, 1792 }, 1793 class: istionetworking.ListenerClassGateway, 1794 protocol: protocol.HTTP, 1795 }, 1796 }, 1797 }, 1798 { 1799 name: "Topology HTTPS Protocol", 1800 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1801 server: &networking.Server{ 1802 Port: &networking.Port{ 1803 Protocol: "HTTPS", 1804 }, 1805 Hosts: []string{"example.org"}, 1806 Tls: &networking.ServerTLSSettings{ 1807 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1808 }, 1809 }, 1810 routeName: "some-route", 1811 proxyConfig: &meshconfig.ProxyConfig{ 1812 GatewayTopology: &meshconfig.Topology{ 1813 NumTrustedProxies: 3, 1814 ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY, 1815 }, 1816 }, 1817 result: &filterChainOpts{ 1818 sniHosts: []string{"example.org"}, 1819 tlsContext: &auth.DownstreamTlsContext{ 1820 CommonTlsContext: &auth.CommonTlsContext{ 1821 AlpnProtocols: util.ALPNHttp, 1822 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1823 { 1824 Name: "default", 1825 SdsConfig: &core.ConfigSource{ 1826 ResourceApiVersion: core.ApiVersion_V3, 1827 InitialFetchTimeout: durationpb.New(time.Second * 0), 1828 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1829 ApiConfigSource: &core.ApiConfigSource{ 1830 ApiType: core.ApiConfigSource_GRPC, 1831 SetNodeOnFirstMessageOnly: true, 1832 TransportApiVersion: core.ApiVersion_V3, 1833 GrpcServices: []*core.GrpcService{ 1834 { 1835 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1836 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1837 }, 1838 }, 1839 }, 1840 }, 1841 }, 1842 }, 1843 }, 1844 }, 1845 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1846 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1847 DefaultValidationContext: &auth.CertificateValidationContext{}, 1848 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1849 Name: "ROOTCA", 1850 SdsConfig: &core.ConfigSource{ 1851 ResourceApiVersion: core.ApiVersion_V3, 1852 InitialFetchTimeout: durationpb.New(time.Second * 0), 1853 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1854 ApiConfigSource: &core.ApiConfigSource{ 1855 ApiType: core.ApiConfigSource_GRPC, 1856 SetNodeOnFirstMessageOnly: true, 1857 TransportApiVersion: core.ApiVersion_V3, 1858 GrpcServices: []*core.GrpcService{ 1859 { 1860 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1861 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1862 }, 1863 }, 1864 }, 1865 }, 1866 }, 1867 }, 1868 }, 1869 }, 1870 }, 1871 }, 1872 RequireClientCertificate: proto.BoolTrue, 1873 }, 1874 httpOpts: &httpListenerOpts{ 1875 rds: "some-route", 1876 useRemoteAddress: true, 1877 connectionManager: &hcm.HttpConnectionManager{ 1878 XffNumTrustedHops: 3, 1879 ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY, 1880 ServerName: EnvoyServerName, 1881 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1882 Proxy_100Continue: true, 1883 }, 1884 class: istionetworking.ListenerClassGateway, 1885 protocol: protocol.HTTPS, 1886 }, 1887 }, 1888 }, 1889 { 1890 name: "HTTPS Protocol with server name", 1891 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1892 server: &networking.Server{ 1893 Name: "server1", 1894 Port: &networking.Port{ 1895 Protocol: "HTTPS", 1896 }, 1897 Hosts: []string{"example.org"}, 1898 Tls: &networking.ServerTLSSettings{ 1899 Mode: networking.ServerTLSSettings_ISTIO_MUTUAL, 1900 }, 1901 }, 1902 routeName: "some-route", 1903 proxyConfig: &meshconfig.ProxyConfig{ 1904 GatewayTopology: &meshconfig.Topology{ 1905 NumTrustedProxies: 3, 1906 ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY, 1907 }, 1908 }, 1909 result: &filterChainOpts{ 1910 sniHosts: []string{"example.org"}, 1911 tlsContext: &auth.DownstreamTlsContext{ 1912 RequireClientCertificate: proto.BoolTrue, 1913 CommonTlsContext: &auth.CommonTlsContext{ 1914 AlpnProtocols: util.ALPNHttp, 1915 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 1916 { 1917 Name: "default", 1918 SdsConfig: &core.ConfigSource{ 1919 ResourceApiVersion: core.ApiVersion_V3, 1920 InitialFetchTimeout: durationpb.New(time.Second * 0), 1921 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1922 ApiConfigSource: &core.ApiConfigSource{ 1923 ApiType: core.ApiConfigSource_GRPC, 1924 SetNodeOnFirstMessageOnly: true, 1925 TransportApiVersion: core.ApiVersion_V3, 1926 GrpcServices: []*core.GrpcService{ 1927 { 1928 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1929 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1930 }, 1931 }, 1932 }, 1933 }, 1934 }, 1935 }, 1936 }, 1937 }, 1938 ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{ 1939 CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{ 1940 DefaultValidationContext: &auth.CertificateValidationContext{}, 1941 ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{ 1942 Name: "ROOTCA", 1943 SdsConfig: &core.ConfigSource{ 1944 ResourceApiVersion: core.ApiVersion_V3, 1945 InitialFetchTimeout: durationpb.New(time.Second * 0), 1946 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 1947 ApiConfigSource: &core.ApiConfigSource{ 1948 ApiType: core.ApiConfigSource_GRPC, 1949 SetNodeOnFirstMessageOnly: true, 1950 TransportApiVersion: core.ApiVersion_V3, 1951 GrpcServices: []*core.GrpcService{ 1952 { 1953 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 1954 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName}, 1955 }, 1956 }, 1957 }, 1958 }, 1959 }, 1960 }, 1961 }, 1962 }, 1963 }, 1964 }, 1965 }, 1966 httpOpts: &httpListenerOpts{ 1967 rds: "some-route", 1968 useRemoteAddress: true, 1969 connectionManager: &hcm.HttpConnectionManager{ 1970 XffNumTrustedHops: 3, 1971 ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY, 1972 ServerName: EnvoyServerName, 1973 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 1974 Proxy_100Continue: true, 1975 }, 1976 statPrefix: "server1", 1977 class: istionetworking.ListenerClassGateway, 1978 protocol: protocol.HTTPS, 1979 }, 1980 }, 1981 }, 1982 { 1983 name: "QUIC protocol with server name", 1984 node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}}, 1985 transportProtocol: istionetworking.TransportProtocolQUIC, 1986 server: &networking.Server{ 1987 Name: "server1", 1988 Port: &networking.Port{ 1989 Name: "https-app", 1990 Number: 443, 1991 Protocol: "HTTPS", 1992 }, 1993 Hosts: []string{"example.org"}, 1994 Tls: &networking.ServerTLSSettings{ 1995 Mode: networking.ServerTLSSettings_SIMPLE, 1996 ServerCertificate: "/etc/cert/example.crt", 1997 PrivateKey: "/etc/cert/example.key", 1998 }, 1999 }, 2000 routeName: "some-route", 2001 proxyConfig: &meshconfig.ProxyConfig{ 2002 GatewayTopology: &meshconfig.Topology{ 2003 NumTrustedProxies: 3, 2004 ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY, 2005 }, 2006 }, 2007 result: &filterChainOpts{ 2008 sniHosts: []string{"example.org"}, 2009 tlsContext: &auth.DownstreamTlsContext{ 2010 RequireClientCertificate: proto.BoolFalse, 2011 CommonTlsContext: &auth.CommonTlsContext{ 2012 AlpnProtocols: util.ALPNHttp3OverQUIC, 2013 TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{ 2014 { 2015 Name: "file-cert:/etc/cert/example.crt~/etc/cert/example.key", 2016 SdsConfig: &core.ConfigSource{ 2017 ResourceApiVersion: core.ApiVersion_V3, 2018 ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{ 2019 ApiConfigSource: &core.ApiConfigSource{ 2020 ApiType: core.ApiConfigSource_GRPC, 2021 GrpcServices: []*core.GrpcService{ 2022 { 2023 TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ 2024 EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ 2025 ClusterName: "sds-grpc", 2026 }, 2027 }, 2028 }, 2029 }, 2030 SetNodeOnFirstMessageOnly: true, 2031 TransportApiVersion: core.ApiVersion_V3, 2032 }, 2033 }, 2034 }, 2035 }, 2036 }, 2037 }, 2038 }, 2039 httpOpts: &httpListenerOpts{ 2040 rds: "some-route", 2041 http3Only: true, 2042 connectionManager: &hcm.HttpConnectionManager{ 2043 XffNumTrustedHops: 3, 2044 ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY, 2045 ServerName: EnvoyServerName, 2046 HttpProtocolOptions: &core.Http1ProtocolOptions{}, 2047 Http3ProtocolOptions: &core.Http3ProtocolOptions{}, 2048 CodecType: hcm.HttpConnectionManager_HTTP3, 2049 Proxy_100Continue: true, 2050 }, 2051 useRemoteAddress: true, 2052 statPrefix: "server1", 2053 class: istionetworking.ListenerClassGateway, 2054 protocol: protocol.HTTPS, 2055 }, 2056 }, 2057 }, 2058 } 2059 2060 for _, tc := range testCases { 2061 t.Run(tc.name, func(t *testing.T) { 2062 cgi := NewConfigGenerator(&pilot_model.DisabledCache{}) 2063 tc.node.MergedGateway = &pilot_model.MergedGateway{TLSServerInfo: map[*networking.Server]*pilot_model.TLSServerInfo{ 2064 tc.server: {SNIHosts: pilot_model.GetSNIHostsForServer(tc.server)}, 2065 }} 2066 ret := cgi.createGatewayHTTPFilterChainOpts(tc.node, tc.server.Port, tc.server, 2067 tc.routeName, tc.proxyConfig, tc.transportProtocol, cg.PushContext()) 2068 if diff := cmp.Diff(tc.result.tlsContext, ret.tlsContext, protocmp.Transform()); diff != "" { 2069 t.Errorf("got diff in tls context: %v", diff) 2070 } 2071 if !reflect.DeepEqual(tc.result.httpOpts, ret.httpOpts) { 2072 t.Errorf("expecting httpopts:\n %+v \nbut got:\n %+v", tc.result.httpOpts, ret.httpOpts) 2073 } 2074 if !reflect.DeepEqual(tc.result.sniHosts, ret.sniHosts) { 2075 t.Errorf("expecting snihosts %+v but got %+v", tc.result.sniHosts, ret.sniHosts) 2076 } 2077 }) 2078 } 2079 } 2080 2081 func TestGatewayHTTPRouteConfig(t *testing.T) { 2082 httpRedirectGateway := config.Config{ 2083 Meta: config.Meta{ 2084 Name: "gateway-redirect", 2085 Namespace: "default", 2086 GroupVersionKind: gvk.Gateway, 2087 }, 2088 Spec: &networking.Gateway{ 2089 Selector: map[string]string{"istio": "ingressgateway"}, 2090 Servers: []*networking.Server{ 2091 { 2092 Hosts: []string{"example.org"}, 2093 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2094 Tls: &networking.ServerTLSSettings{HttpsRedirect: true}, 2095 }, 2096 }, 2097 }, 2098 } 2099 httpRedirectGatewayWithoutVS := config.Config{ 2100 Meta: config.Meta{ 2101 Name: "gateway-redirect-noroutes", 2102 Namespace: "default", 2103 GroupVersionKind: gvk.Gateway, 2104 }, 2105 Spec: &networking.Gateway{ 2106 Selector: map[string]string{"istio": "ingressgateway"}, 2107 Servers: []*networking.Server{ 2108 { 2109 Hosts: []string{"example.org"}, 2110 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2111 Tls: &networking.ServerTLSSettings{HttpsRedirect: true}, 2112 }, 2113 }, 2114 }, 2115 } 2116 httpGateway := config.Config{ 2117 Meta: config.Meta{ 2118 Name: "gateway", 2119 Namespace: "default", 2120 GroupVersionKind: gvk.Gateway, 2121 }, 2122 Spec: &networking.Gateway{ 2123 Selector: map[string]string{"istio": "ingressgateway"}, 2124 Servers: []*networking.Server{ 2125 { 2126 Hosts: []string{"example.org"}, 2127 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2128 }, 2129 }, 2130 }, 2131 } 2132 httpCaseInSensitiveGateway := config.Config{ 2133 Meta: config.Meta{ 2134 Name: "case-insensitive-gateway", 2135 Namespace: "default", 2136 GroupVersionKind: gvk.Gateway, 2137 }, 2138 Spec: &networking.Gateway{ 2139 Selector: map[string]string{"istio": "ingressgateway"}, 2140 Servers: []*networking.Server{ 2141 { 2142 Hosts: []string{"Example.org"}, 2143 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2144 }, 2145 }, 2146 }, 2147 } 2148 httpsGateway := config.Config{ 2149 Meta: config.Meta{ 2150 Name: "gateway-https", 2151 Namespace: "default", 2152 GroupVersionKind: gvk.Gateway, 2153 }, 2154 Spec: &networking.Gateway{ 2155 Selector: map[string]string{"istio": "ingressgateway"}, 2156 Servers: []*networking.Server{ 2157 { 2158 Hosts: []string{"example.org"}, 2159 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2160 Tls: &networking.ServerTLSSettings{HttpsRedirect: true}, 2161 }, 2162 { 2163 Hosts: []string{"example.org"}, 2164 Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"}, 2165 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_TLSmode(networking.ClientTLSSettings_SIMPLE)}, 2166 }, 2167 }, 2168 }, 2169 } 2170 httpsGatewayRedirect := config.Config{ 2171 Meta: config.Meta{ 2172 Name: "gateway-https", 2173 Namespace: "default", 2174 GroupVersionKind: gvk.Gateway, 2175 }, 2176 Spec: &networking.Gateway{ 2177 Selector: map[string]string{"istio": "ingressgateway"}, 2178 Servers: []*networking.Server{ 2179 { 2180 Hosts: []string{"example.org"}, 2181 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2182 Tls: &networking.ServerTLSSettings{HttpsRedirect: true}, 2183 }, 2184 { 2185 Hosts: []string{"example.org"}, 2186 Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"}, 2187 Tls: &networking.ServerTLSSettings{HttpsRedirect: true, Mode: networking.ServerTLSSettings_TLSmode(networking.ClientTLSSettings_SIMPLE)}, 2188 }, 2189 }, 2190 }, 2191 } 2192 httpGatewayWildcard := config.Config{ 2193 Meta: config.Meta{ 2194 Name: "gateway", 2195 Namespace: "default", 2196 GroupVersionKind: gvk.Gateway, 2197 }, 2198 Spec: &networking.Gateway{ 2199 Selector: map[string]string{"istio": "ingressgateway"}, 2200 Servers: []*networking.Server{ 2201 { 2202 Hosts: []string{"*"}, 2203 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2204 }, 2205 }, 2206 }, 2207 } 2208 virtualServiceSpec := &networking.VirtualService{ 2209 Hosts: []string{"example.org"}, 2210 Gateways: []string{"gateway", "gateway-redirect"}, 2211 Http: []*networking.HTTPRoute{ 2212 { 2213 Route: []*networking.HTTPRouteDestination{ 2214 { 2215 Destination: &networking.Destination{ 2216 Host: "example.org", 2217 Port: &networking.PortSelector{ 2218 Number: 80, 2219 }, 2220 }, 2221 }, 2222 }, 2223 }, 2224 }, 2225 } 2226 virtualServiceCaseInsensitiveSpec := &networking.VirtualService{ 2227 Hosts: []string{"Example.org"}, 2228 Gateways: []string{"case-insensitive-gateway", "gateway-redirect"}, 2229 Http: []*networking.HTTPRoute{ 2230 { 2231 Route: []*networking.HTTPRouteDestination{ 2232 { 2233 Destination: &networking.Destination{ 2234 Host: "example.org", 2235 Port: &networking.PortSelector{ 2236 Number: 80, 2237 }, 2238 }, 2239 }, 2240 }, 2241 }, 2242 }, 2243 } 2244 virtualServiceHTTPSMatchSpec := &networking.VirtualService{ 2245 Hosts: []string{"example.org"}, 2246 Gateways: []string{"gateway-https"}, 2247 Http: []*networking.HTTPRoute{ 2248 { 2249 Match: []*networking.HTTPMatchRequest{ 2250 { 2251 Port: 443, 2252 }, 2253 }, 2254 Route: []*networking.HTTPRouteDestination{ 2255 { 2256 Destination: &networking.Destination{ 2257 Host: "example.default.svc.cluster.local", 2258 Port: &networking.PortSelector{ 2259 Number: 8080, 2260 }, 2261 }, 2262 }, 2263 }, 2264 }, 2265 }, 2266 } 2267 virtualService := config.Config{ 2268 Meta: config.Meta{ 2269 GroupVersionKind: gvk.VirtualService, 2270 Name: "virtual-service", 2271 Namespace: "default", 2272 }, 2273 Spec: virtualServiceSpec, 2274 } 2275 virtualServiceCaseInsensitive := config.Config{ 2276 Meta: config.Meta{ 2277 GroupVersionKind: gvk.VirtualService, 2278 Name: "virtual-service-case-insensitive", 2279 Namespace: "default", 2280 }, 2281 Spec: virtualServiceCaseInsensitiveSpec, 2282 } 2283 virtualServiceHTTPS := config.Config{ 2284 Meta: config.Meta{ 2285 GroupVersionKind: gvk.VirtualService, 2286 Name: "virtual-service-https", 2287 Namespace: "default", 2288 }, 2289 Spec: virtualServiceHTTPSMatchSpec, 2290 } 2291 virtualServiceCopy := config.Config{ 2292 Meta: config.Meta{ 2293 GroupVersionKind: gvk.VirtualService, 2294 Name: "virtual-service-copy", 2295 Namespace: "default", 2296 }, 2297 Spec: virtualServiceSpec, 2298 } 2299 virtualServiceWildcard := config.Config{ 2300 Meta: config.Meta{ 2301 GroupVersionKind: gvk.VirtualService, 2302 Name: "virtual-service-wildcard", 2303 Namespace: "default", 2304 }, 2305 Spec: &networking.VirtualService{ 2306 Hosts: []string{"*.org"}, 2307 Gateways: []string{"gateway", "gateway-redirect"}, 2308 Http: []*networking.HTTPRoute{ 2309 { 2310 Route: []*networking.HTTPRouteDestination{ 2311 { 2312 Destination: &networking.Destination{ 2313 Host: "example.org", 2314 Port: &networking.PortSelector{ 2315 Number: 80, 2316 }, 2317 }, 2318 }, 2319 }, 2320 }, 2321 }, 2322 }, 2323 } 2324 cases := []struct { 2325 name string 2326 virtualServices []config.Config 2327 gateways []config.Config 2328 routeName string 2329 expectedVirtualHosts map[string][]string 2330 expectedVirtualHostsHostPortStrip map[string][]string 2331 expectedHTTPRoutes map[string]int 2332 redirect bool 2333 expectStatefulSession bool 2334 }{ 2335 { 2336 name: "404 when no services", 2337 virtualServices: []config.Config{}, 2338 gateways: []config.Config{httpGateway}, 2339 routeName: "http.80", 2340 expectedVirtualHosts: map[string][]string{ 2341 "blackhole:80": { 2342 "*", 2343 }, 2344 }, 2345 expectedVirtualHostsHostPortStrip: map[string][]string{ 2346 "blackhole:80": { 2347 "*", 2348 }, 2349 }, 2350 expectedHTTPRoutes: map[string]int{"blackhole:80": 0}, 2351 expectStatefulSession: false, 2352 }, 2353 { 2354 name: "tls redirect without virtual services", 2355 virtualServices: []config.Config{virtualService}, 2356 gateways: []config.Config{httpRedirectGatewayWithoutVS}, 2357 routeName: "http.80", 2358 expectedVirtualHosts: map[string][]string{ 2359 "example.org:80": { 2360 "example.org", 2361 }, 2362 }, 2363 expectedVirtualHostsHostPortStrip: map[string][]string{ 2364 "example.org:80": {"example.org"}, 2365 }, 2366 // We will setup a VHost which just redirects; no routes 2367 expectedHTTPRoutes: map[string]int{"example.org:80": 0}, 2368 redirect: true, 2369 expectStatefulSession: false, 2370 }, 2371 { 2372 name: "virtual services with tls redirect", 2373 virtualServices: []config.Config{virtualService}, 2374 gateways: []config.Config{httpRedirectGateway}, 2375 routeName: "http.80", 2376 expectedVirtualHosts: map[string][]string{ 2377 "example.org:80": { 2378 "example.org", 2379 }, 2380 }, 2381 expectedVirtualHostsHostPortStrip: map[string][]string{ 2382 "example.org:80": {"example.org"}, 2383 }, 2384 expectedHTTPRoutes: map[string]int{"example.org:80": 1}, 2385 redirect: true, 2386 expectStatefulSession: true, 2387 }, 2388 { 2389 name: "merging of virtual services when tls redirect is set", 2390 virtualServices: []config.Config{virtualService, virtualServiceCopy}, 2391 gateways: []config.Config{httpRedirectGateway, httpGateway}, 2392 routeName: "http.80", 2393 expectedVirtualHosts: map[string][]string{ 2394 "example.org:80": { 2395 "example.org", 2396 }, 2397 }, 2398 expectedVirtualHostsHostPortStrip: map[string][]string{ 2399 "example.org:80": {"example.org"}, 2400 }, 2401 expectedHTTPRoutes: map[string]int{"example.org:80": 4}, 2402 redirect: true, 2403 expectStatefulSession: true, 2404 }, 2405 { 2406 name: "reverse merging of virtual services when tls redirect is set", 2407 virtualServices: []config.Config{virtualService, virtualServiceCopy}, 2408 gateways: []config.Config{httpGateway, httpRedirectGateway}, 2409 routeName: "http.80", 2410 expectedVirtualHosts: map[string][]string{ 2411 "example.org:80": { 2412 "example.org", 2413 }, 2414 }, 2415 expectedVirtualHostsHostPortStrip: map[string][]string{ 2416 "example.org:80": {"example.org"}, 2417 }, 2418 expectedHTTPRoutes: map[string]int{"example.org:80": 4}, 2419 redirect: true, 2420 expectStatefulSession: true, 2421 }, 2422 { 2423 name: "merging of virtual services when tls redirect is set without VS", 2424 virtualServices: []config.Config{virtualService, virtualServiceCopy}, 2425 gateways: []config.Config{httpGateway, httpRedirectGatewayWithoutVS}, 2426 routeName: "http.80", 2427 expectedVirtualHosts: map[string][]string{ 2428 "example.org:80": { 2429 "example.org", 2430 }, 2431 }, 2432 expectedVirtualHostsHostPortStrip: map[string][]string{ 2433 "example.org:80": {"example.org"}, 2434 }, 2435 expectedHTTPRoutes: map[string]int{"example.org:80": 2}, 2436 redirect: true, 2437 expectStatefulSession: true, 2438 }, 2439 { 2440 name: "reverse merging of virtual services when tls redirect is set without VS", 2441 virtualServices: []config.Config{virtualService, virtualServiceCopy}, 2442 gateways: []config.Config{httpRedirectGatewayWithoutVS, httpGateway}, 2443 routeName: "http.80", 2444 expectedVirtualHosts: map[string][]string{ 2445 "example.org:80": { 2446 "example.org", 2447 }, 2448 }, 2449 expectedVirtualHostsHostPortStrip: map[string][]string{ 2450 "example.org:80": {"example.org"}, 2451 }, 2452 expectedHTTPRoutes: map[string]int{"example.org:80": 2}, 2453 redirect: true, 2454 expectStatefulSession: false, 2455 }, 2456 { 2457 name: "add a route for a virtual service", 2458 virtualServices: []config.Config{virtualService}, 2459 gateways: []config.Config{httpGateway}, 2460 routeName: "http.80", 2461 expectedVirtualHosts: map[string][]string{ 2462 "example.org:80": { 2463 "example.org", 2464 }, 2465 }, 2466 expectedVirtualHostsHostPortStrip: map[string][]string{ 2467 "example.org:80": {"example.org"}, 2468 }, 2469 expectedHTTPRoutes: map[string]int{"example.org:80": 1}, 2470 }, 2471 { 2472 name: "duplicate virtual service should merge", 2473 virtualServices: []config.Config{virtualService, virtualServiceCopy}, 2474 gateways: []config.Config{httpGateway}, 2475 routeName: "http.80", 2476 expectedVirtualHosts: map[string][]string{ 2477 "example.org:80": { 2478 "example.org", 2479 }, 2480 }, 2481 expectedVirtualHostsHostPortStrip: map[string][]string{ 2482 "example.org:80": {"example.org"}, 2483 }, 2484 expectedHTTPRoutes: map[string]int{"example.org:80": 2}, 2485 }, 2486 { 2487 name: "duplicate virtual service case insensitive", 2488 virtualServices: []config.Config{virtualService, virtualServiceCaseInsensitive}, 2489 gateways: []config.Config{httpGateway, httpCaseInSensitiveGateway}, 2490 routeName: "http.80", 2491 expectedVirtualHosts: map[string][]string{ 2492 "example.org:80": { 2493 "example.org", 2494 }, 2495 }, 2496 expectedVirtualHostsHostPortStrip: map[string][]string{ 2497 "example.org:80": {"example.org"}, 2498 }, 2499 expectedHTTPRoutes: map[string]int{"example.org:80": 2}, 2500 }, 2501 { 2502 name: "duplicate by wildcard should merge", 2503 virtualServices: []config.Config{virtualService, virtualServiceWildcard}, 2504 gateways: []config.Config{httpGateway}, 2505 routeName: "http.80", 2506 expectedVirtualHosts: map[string][]string{ 2507 "example.org:80": { 2508 "example.org", 2509 }, 2510 }, 2511 expectedVirtualHostsHostPortStrip: map[string][]string{ 2512 "example.org:80": {"example.org"}, 2513 }, 2514 expectedHTTPRoutes: map[string]int{"example.org:80": 2}, 2515 }, 2516 { 2517 name: "wildcard virtual service", 2518 virtualServices: []config.Config{virtualServiceWildcard}, 2519 gateways: []config.Config{httpGatewayWildcard}, 2520 routeName: "http.80", 2521 expectedVirtualHosts: map[string][]string{ 2522 "*.org:80": {"*.org"}, 2523 }, 2524 expectedVirtualHostsHostPortStrip: map[string][]string{ 2525 "*.org:80": {"*.org"}, 2526 }, 2527 expectedHTTPRoutes: map[string]int{"*.org:80": 1}, 2528 expectStatefulSession: false, 2529 }, 2530 { 2531 name: "http redirection not working when virtualservice not match http port", 2532 virtualServices: []config.Config{virtualServiceHTTPS}, 2533 gateways: []config.Config{httpsGateway}, 2534 routeName: "https.443.https.gateway-https.default", 2535 expectedVirtualHosts: map[string][]string{ 2536 "example.org:443": {"example.org"}, 2537 }, 2538 expectedVirtualHostsHostPortStrip: map[string][]string{ 2539 "example.org:443": {"example.org"}, 2540 }, 2541 expectedHTTPRoutes: map[string]int{"example.org:443": 1}, 2542 expectStatefulSession: false, 2543 }, 2544 { 2545 name: "http redirection not working when virtualservice not match http port", 2546 virtualServices: []config.Config{virtualServiceHTTPS}, 2547 gateways: []config.Config{httpsGateway}, 2548 routeName: "http.80", 2549 expectedVirtualHosts: map[string][]string{ 2550 "example.org:80": {"example.org"}, 2551 }, 2552 expectedVirtualHostsHostPortStrip: map[string][]string{ 2553 "example.org:80": {"example.org"}, 2554 }, 2555 // We will setup a VHost which just redirects; no routes 2556 expectedHTTPRoutes: map[string]int{"example.org:80": 0}, 2557 redirect: true, 2558 expectStatefulSession: false, 2559 }, 2560 { 2561 name: "http & https redirection not working when virtualservice not match http port", 2562 virtualServices: []config.Config{virtualServiceHTTPS}, 2563 gateways: []config.Config{httpsGatewayRedirect}, 2564 routeName: "https.443.https.gateway-https.default", 2565 expectedVirtualHosts: map[string][]string{ 2566 "example.org:443": {"example.org"}, 2567 }, 2568 expectedVirtualHostsHostPortStrip: map[string][]string{ 2569 "example.org:443": {"example.org"}, 2570 }, 2571 expectedHTTPRoutes: map[string]int{"example.org:443": 1}, 2572 redirect: true, 2573 expectStatefulSession: false, 2574 }, 2575 { 2576 name: "http & https redirection not working when virtualservice not match http port", 2577 virtualServices: []config.Config{virtualServiceHTTPS}, 2578 gateways: []config.Config{httpsGatewayRedirect}, 2579 routeName: "http.80", 2580 expectedVirtualHosts: map[string][]string{ 2581 "example.org:80": {"example.org"}, 2582 }, 2583 expectedVirtualHostsHostPortStrip: map[string][]string{ 2584 "example.org:80": {"example.org"}, 2585 }, 2586 // We will setup a VHost which just redirects; no routes 2587 expectedHTTPRoutes: map[string]int{"example.org:80": 0}, 2588 redirect: true, 2589 expectStatefulSession: false, 2590 }, 2591 } 2592 exampleService := &pilot_model.Service{ 2593 Hostname: host.Name("example.org"), 2594 Ports: []*pilot_model.Port{{ 2595 Name: "http", 2596 Protocol: "HTTP", 2597 Port: 80, 2598 }}, 2599 Attributes: pilot_model.ServiceAttributes{ 2600 Namespace: "default", 2601 Labels: map[string]string{"istio.io/persistent-session": "session-cookie"}, 2602 }, 2603 } 2604 2605 for _, tt := range cases { 2606 t.Run(tt.name, func(t *testing.T) { 2607 cfgs := tt.gateways 2608 cfgs = append(cfgs, tt.virtualServices...) 2609 cg := NewConfigGenTest(t, TestOptions{ 2610 Configs: cfgs, 2611 Services: []*pilot_model.Service{ 2612 exampleService, 2613 }, 2614 }) 2615 r := cg.ConfigGen.buildGatewayHTTPRouteConfig(cg.SetupProxy(&proxyGateway), cg.PushContext(), tt.routeName) 2616 if r == nil { 2617 t.Fatal("got an empty route configuration") 2618 } 2619 if r.MaxDirectResponseBodySizeBytes != istio_route.DefaultMaxDirectResponseBodySizeBytes { 2620 t.Errorf("expected MaxDirectResponseBodySizeBytes %v, got %v", 2621 istio_route.DefaultMaxDirectResponseBodySizeBytes, r.MaxDirectResponseBodySizeBytes) 2622 } 2623 vh := make(map[string][]string) 2624 hr := make(map[string]int) 2625 for _, h := range r.VirtualHosts { 2626 vh[h.Name] = h.Domains 2627 hr[h.Name] = len(h.Routes) 2628 if h.Name != "blackhole:80" && !h.IncludeRequestAttemptCount { 2629 t.Errorf("expected attempt count to be set in virtual host, but not found") 2630 } 2631 if tt.redirect != (h.RequireTls == route.VirtualHost_ALL) { 2632 t.Errorf("expected redirect %v, got %v", tt.redirect, h.RequireTls) 2633 } 2634 if tt.expectStatefulSession && h.TypedPerFilterConfig[util.StatefulSessionFilter] == nil { 2635 t.Errorf("expected per filter config for stateful session filter, but not found") 2636 } 2637 } 2638 2639 if !maps.EqualFunc(tt.expectedVirtualHosts, vh, slices.Equal) { 2640 t.Errorf("got unexpected virtual hosts. Expected: %v, Got: %v", tt.expectedVirtualHosts, vh) 2641 } 2642 if !maps.Equal(tt.expectedHTTPRoutes, hr) { 2643 t.Errorf("got unexpected number of http routes. Expected: %v, Got: %v", tt.expectedHTTPRoutes, hr) 2644 } 2645 }) 2646 } 2647 } 2648 2649 func TestBuildGatewayListeners(t *testing.T) { 2650 cases := []struct { 2651 name string 2652 node *pilot_model.Proxy 2653 gateways []config.Config 2654 virtualServices []config.Config 2655 expectedListeners []string 2656 }{ 2657 { 2658 "targetPort overrides service port", 2659 &pilot_model.Proxy{ 2660 ServiceTargets: []pilot_model.ServiceTarget{ 2661 { 2662 Service: &pilot_model.Service{ 2663 Hostname: "test", 2664 }, 2665 Port: pilot_model.ServiceInstancePort{ 2666 ServicePort: &pilot_model.Port{ 2667 Port: 80, 2668 }, 2669 TargetPort: 8080, 2670 }, 2671 }, 2672 }, 2673 }, 2674 []config.Config{ 2675 { 2676 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2677 Spec: &networking.Gateway{ 2678 Servers: []*networking.Server{ 2679 { 2680 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2681 }, 2682 }, 2683 }, 2684 }, 2685 }, 2686 nil, 2687 []string{"0.0.0.0_8080"}, 2688 }, 2689 { 2690 "multiple ports", 2691 &pilot_model.Proxy{}, 2692 []config.Config{ 2693 { 2694 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2695 Spec: &networking.Gateway{ 2696 Servers: []*networking.Server{ 2697 { 2698 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2699 }, 2700 { 2701 Port: &networking.Port{Name: "http", Number: 801, Protocol: "HTTP"}, 2702 }, 2703 }, 2704 }, 2705 }, 2706 }, 2707 nil, 2708 []string{"0.0.0.0_80", "0.0.0.0_801"}, 2709 }, 2710 { 2711 "privileged port on unprivileged pod", 2712 &pilot_model.Proxy{ 2713 Metadata: &pilot_model.NodeMetadata{ 2714 UnprivilegedPod: "true", 2715 }, 2716 }, 2717 []config.Config{ 2718 { 2719 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2720 Spec: &networking.Gateway{ 2721 Servers: []*networking.Server{ 2722 { 2723 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2724 }, 2725 { 2726 Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"}, 2727 }, 2728 }, 2729 }, 2730 }, 2731 }, 2732 nil, 2733 []string{"0.0.0.0_8080"}, 2734 }, 2735 { 2736 "privileged port on privileged pod when empty env var is set", 2737 &pilot_model.Proxy{ 2738 Metadata: &pilot_model.NodeMetadata{ 2739 UnprivilegedPod: "", 2740 }, 2741 }, 2742 []config.Config{ 2743 { 2744 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2745 Spec: &networking.Gateway{ 2746 Servers: []*networking.Server{ 2747 { 2748 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2749 }, 2750 { 2751 Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"}, 2752 }, 2753 }, 2754 }, 2755 }, 2756 }, 2757 nil, 2758 []string{"0.0.0.0_80", "0.0.0.0_8080"}, 2759 }, 2760 { 2761 "privileged port on privileged pod", 2762 &pilot_model.Proxy{}, 2763 []config.Config{ 2764 { 2765 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2766 Spec: &networking.Gateway{ 2767 Servers: []*networking.Server{ 2768 { 2769 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2770 }, 2771 { 2772 Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"}, 2773 }, 2774 }, 2775 }, 2776 }, 2777 }, 2778 nil, 2779 []string{"0.0.0.0_80", "0.0.0.0_8080"}, 2780 }, 2781 { 2782 "gateway with bind", 2783 &pilot_model.Proxy{}, 2784 []config.Config{ 2785 { 2786 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2787 Spec: &networking.Gateway{ 2788 Servers: []*networking.Server{ 2789 { 2790 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2791 }, 2792 { 2793 Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"}, 2794 Hosts: []string{"externalgatewayclient.com"}, 2795 }, 2796 { 2797 Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"}, 2798 Bind: "127.0.0.1", 2799 Hosts: []string{"internalmesh.svc.cluster.local"}, 2800 }, 2801 }, 2802 }, 2803 }, 2804 }, 2805 nil, 2806 []string{"0.0.0.0_80", "0.0.0.0_8080", "127.0.0.1_8080"}, 2807 }, 2808 { 2809 "gateway with simple and passthrough", 2810 &pilot_model.Proxy{}, 2811 []config.Config{ 2812 { 2813 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway}, 2814 Spec: &networking.Gateway{ 2815 Servers: []*networking.Server{ 2816 { 2817 Port: &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"}, 2818 Hosts: []string{"*.example.com"}, 2819 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2820 }, 2821 { 2822 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2823 Hosts: []string{"foo.example.com"}, 2824 }, 2825 }, 2826 }, 2827 }, 2828 { 2829 Meta: config.Meta{Name: "passthrough-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2830 Spec: &networking.Gateway{ 2831 Servers: []*networking.Server{ 2832 { 2833 Port: &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"}, 2834 Hosts: []string{"*.example.com"}, 2835 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2836 }, 2837 { 2838 Port: &networking.Port{Name: "tcp", Number: 9443, Protocol: "TLS"}, 2839 Hosts: []string{"barone.example.com"}, 2840 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_PASSTHROUGH}, 2841 }, 2842 { 2843 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2844 Hosts: []string{"bar.example.com"}, 2845 }, 2846 }, 2847 }, 2848 }, 2849 }, 2850 []config.Config{ 2851 { 2852 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 2853 Spec: &networking.VirtualService{ 2854 Gateways: []string{"testns/passthrough-gateway"}, 2855 Hosts: []string{"barone.example.com"}, 2856 Tls: []*networking.TLSRoute{ 2857 { 2858 Match: []*networking.TLSMatchAttributes{ 2859 { 2860 Port: 9443, 2861 SniHosts: []string{"barone.example.com"}, 2862 }, 2863 }, 2864 Route: []*networking.RouteDestination{ 2865 { 2866 Destination: &networking.Destination{ 2867 Host: "foo.com", 2868 }, 2869 }, 2870 }, 2871 }, 2872 }, 2873 }, 2874 }, 2875 }, 2876 []string{"0.0.0.0_443", "0.0.0.0_80", "0.0.0.0_9443"}, 2877 }, 2878 { 2879 "gateway with multiple http servers", 2880 &pilot_model.Proxy{}, 2881 []config.Config{ 2882 { 2883 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2884 Spec: &networking.Gateway{ 2885 Servers: []*networking.Server{ 2886 { 2887 Port: &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"}, 2888 Hosts: []string{"*.example.com"}, 2889 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2890 }, 2891 { 2892 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2893 Hosts: []string{"foo.example.com"}, 2894 }, 2895 }, 2896 }, 2897 }, 2898 { 2899 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2900 Spec: &networking.Gateway{ 2901 Servers: []*networking.Server{ 2902 { 2903 Port: &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"}, 2904 Hosts: []string{"*.exampleone.com"}, 2905 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2906 }, 2907 { 2908 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 2909 Hosts: []string{"bar.example.com"}, 2910 }, 2911 }, 2912 }, 2913 }, 2914 }, 2915 nil, 2916 []string{"0.0.0.0_443", "0.0.0.0_80"}, 2917 }, 2918 { 2919 "gateway with multiple TLS HTTPS TCP servers", 2920 &pilot_model.Proxy{}, 2921 []config.Config{ 2922 { 2923 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2924 Spec: &networking.Gateway{ 2925 Servers: []*networking.Server{ 2926 { 2927 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "TLS"}, 2928 Hosts: []string{"*.example.com"}, 2929 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2930 }, 2931 { 2932 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"}, 2933 Hosts: []string{"https.example.com"}, 2934 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2935 }, 2936 { 2937 Port: &networking.Port{Name: "tcp", Number: 9443, Protocol: "TCP"}, 2938 Hosts: []string{"tcp.example.com"}, 2939 }, 2940 }, 2941 }, 2942 }, 2943 { 2944 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2945 Spec: &networking.Gateway{ 2946 Servers: []*networking.Server{ 2947 { 2948 Port: &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"}, 2949 Hosts: []string{"*.exampleone.com"}, 2950 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2951 }, 2952 { 2953 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "TLS"}, 2954 Hosts: []string{"*.exampleone.com"}, 2955 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 2956 }, 2957 }, 2958 }, 2959 }, 2960 }, 2961 []config.Config{ 2962 { 2963 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 2964 Spec: &networking.VirtualService{ 2965 Gateways: []string{"testns/gateway1"}, 2966 Hosts: []string{"tcp.example.com"}, 2967 Tcp: []*networking.TCPRoute{ 2968 { 2969 Match: []*networking.L4MatchAttributes{ 2970 { 2971 Port: 9443, 2972 }, 2973 }, 2974 Route: []*networking.RouteDestination{ 2975 { 2976 Destination: &networking.Destination{ 2977 Host: "foo.com", 2978 }, 2979 }, 2980 }, 2981 }, 2982 }, 2983 }, 2984 }, 2985 }, 2986 []string{"0.0.0.0_443", "0.0.0.0_9443"}, 2987 }, 2988 { 2989 "gateway with multiple TCP/HTTPS servers with bind", 2990 &pilot_model.Proxy{}, 2991 []config.Config{ 2992 { 2993 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 2994 Spec: &networking.Gateway{ 2995 Servers: []*networking.Server{ 2996 { 2997 Port: &networking.Port{Name: "tcp", Number: 8000, Protocol: "TCP"}, 2998 Hosts: []string{"*"}, 2999 Bind: "10.0.0.1", 3000 }, 3001 }, 3002 }, 3003 }, 3004 { 3005 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3006 Spec: &networking.Gateway{ 3007 Servers: []*networking.Server{ 3008 { 3009 Port: &networking.Port{Name: "tcp", Number: 8000, Protocol: "TCP"}, 3010 Hosts: []string{"*"}, 3011 Bind: "10.0.0.2", 3012 }, 3013 }, 3014 }, 3015 }, 3016 { 3017 Meta: config.Meta{Name: "gateway3", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3018 Spec: &networking.Gateway{ 3019 Servers: []*networking.Server{ 3020 { 3021 Port: &networking.Port{Name: "https", Number: 8000, Protocol: "HTTPS"}, 3022 Hosts: []string{"*"}, 3023 Bind: "10.0.0.3", 3024 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3025 }, 3026 }, 3027 }, 3028 }, 3029 }, 3030 []config.Config{ 3031 { 3032 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3033 Spec: &networking.VirtualService{ 3034 Gateways: []string{"testns/gateway1"}, 3035 Hosts: []string{"*"}, 3036 Tcp: []*networking.TCPRoute{ 3037 { 3038 Match: []*networking.L4MatchAttributes{ 3039 { 3040 Port: 8000, 3041 }, 3042 }, 3043 Route: []*networking.RouteDestination{ 3044 { 3045 Destination: &networking.Destination{ 3046 Host: "foo.com", 3047 }, 3048 }, 3049 }, 3050 }, 3051 }, 3052 }, 3053 }, 3054 { 3055 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3056 Spec: &networking.VirtualService{ 3057 Gateways: []string{"testns/gateway2"}, 3058 Hosts: []string{"*"}, 3059 Tcp: []*networking.TCPRoute{ 3060 { 3061 Match: []*networking.L4MatchAttributes{ 3062 { 3063 Port: 8000, 3064 }, 3065 }, 3066 Route: []*networking.RouteDestination{ 3067 { 3068 Destination: &networking.Destination{ 3069 Host: "foo.com", 3070 }, 3071 }, 3072 }, 3073 }, 3074 }, 3075 }, 3076 }, 3077 { 3078 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3079 Spec: &networking.VirtualService{ 3080 Gateways: []string{"testns/gateway3"}, 3081 Hosts: []string{"*"}, 3082 Http: []*networking.HTTPRoute{ 3083 { 3084 Route: []*networking.HTTPRouteDestination{ 3085 { 3086 Destination: &networking.Destination{ 3087 Host: "grpc.example.org", 3088 Port: &networking.PortSelector{ 3089 Number: 80, 3090 }, 3091 }, 3092 }, 3093 }, 3094 }, 3095 }, 3096 }, 3097 }, 3098 }, 3099 []string{"10.0.0.1_8000", "10.0.0.2_8000", "10.0.0.3_8000"}, 3100 }, 3101 { 3102 "gateway with HTTPS/GRPC servers with bind", 3103 &pilot_model.Proxy{}, 3104 []config.Config{ 3105 { 3106 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3107 Spec: &networking.Gateway{ 3108 Servers: []*networking.Server{ 3109 { 3110 Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"}, 3111 Hosts: []string{"*"}, 3112 Bind: "10.0.0.1", 3113 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3114 }, 3115 }, 3116 }, 3117 }, 3118 { 3119 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3120 Spec: &networking.Gateway{ 3121 Servers: []*networking.Server{ 3122 { 3123 Port: &networking.Port{Name: "grpc", Number: 443, Protocol: "GRPC"}, 3124 Bind: "10.0.0.2", 3125 Hosts: []string{"*"}, 3126 }, 3127 }, 3128 }, 3129 }, 3130 { 3131 Meta: config.Meta{Name: "gateway3", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3132 Spec: &networking.Gateway{ 3133 Servers: []*networking.Server{ 3134 { 3135 Port: &networking.Port{Name: "grpc", Number: 443, Protocol: "GRPC"}, 3136 Hosts: []string{"grpc.example.org"}, 3137 }, 3138 }, 3139 }, 3140 }, 3141 }, 3142 []config.Config{ 3143 { 3144 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3145 Spec: &networking.VirtualService{ 3146 Gateways: []string{"testns/gateway1"}, 3147 Hosts: []string{"*"}, 3148 Http: []*networking.HTTPRoute{ 3149 { 3150 Route: []*networking.HTTPRouteDestination{ 3151 { 3152 Destination: &networking.Destination{ 3153 Host: "example.org", 3154 Port: &networking.PortSelector{ 3155 Number: 80, 3156 }, 3157 }, 3158 }, 3159 }, 3160 }, 3161 }, 3162 }, 3163 }, 3164 { 3165 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3166 Spec: &networking.VirtualService{ 3167 Gateways: []string{"testns/gateway2"}, 3168 Hosts: []string{"*"}, 3169 Http: []*networking.HTTPRoute{ 3170 { 3171 Route: []*networking.HTTPRouteDestination{ 3172 { 3173 Destination: &networking.Destination{ 3174 Host: "grpc.example.org", 3175 Port: &networking.PortSelector{ 3176 Number: 80, 3177 }, 3178 }, 3179 }, 3180 }, 3181 }, 3182 }, 3183 }, 3184 }, 3185 { 3186 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3187 Spec: &networking.VirtualService{ 3188 Gateways: []string{"testns/gateway3"}, 3189 Hosts: []string{"grpc.example.org"}, 3190 Http: []*networking.HTTPRoute{ 3191 { 3192 Route: []*networking.HTTPRouteDestination{ 3193 { 3194 Destination: &networking.Destination{ 3195 Host: "grpc.example.org", 3196 Port: &networking.PortSelector{ 3197 Number: 80, 3198 }, 3199 }, 3200 }, 3201 }, 3202 }, 3203 }, 3204 }, 3205 }, 3206 }, 3207 []string{"10.0.0.1_443", "10.0.0.2_443", "0.0.0.0_443"}, 3208 }, 3209 { 3210 "gateway with HTTPS/TCP invalid configuration", 3211 &pilot_model.Proxy{}, 3212 []config.Config{ 3213 { 3214 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3215 Spec: &networking.Gateway{ 3216 Servers: []*networking.Server{ 3217 { 3218 Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"}, 3219 Hosts: []string{"*.1.example.com"}, 3220 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3221 }, 3222 { 3223 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "TCP"}, 3224 Hosts: []string{"*.1.example.com"}, 3225 }, 3226 }, 3227 }, 3228 }, 3229 { 3230 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3231 Spec: &networking.Gateway{ 3232 Servers: []*networking.Server{ 3233 { 3234 Port: &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"}, 3235 Hosts: []string{"*.2.example.com"}, 3236 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3237 }, 3238 { 3239 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "TCP"}, 3240 Hosts: []string{"*.2.example.com"}, 3241 }, 3242 }, 3243 }, 3244 }, 3245 }, 3246 []config.Config{ 3247 { 3248 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3249 Spec: &networking.VirtualService{ 3250 Gateways: []string{"testns/gateway1"}, 3251 Hosts: []string{"*"}, 3252 Tcp: []*networking.TCPRoute{{ 3253 Route: []*networking.RouteDestination{{Destination: &networking.Destination{Host: "example.com"}}}, 3254 }}, 3255 }, 3256 }, 3257 { 3258 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3259 Spec: &networking.VirtualService{ 3260 Gateways: []string{"testns/gateway2"}, 3261 Hosts: []string{"*"}, 3262 Tcp: []*networking.TCPRoute{{ 3263 Route: []*networking.RouteDestination{{Destination: &networking.Destination{Host: "example.com"}}}, 3264 }}, 3265 }, 3266 }, 3267 }, 3268 []string{"0.0.0.0_443"}, 3269 }, 3270 { 3271 "gateway with multiple HTTPS servers with bind and same host", 3272 &pilot_model.Proxy{}, 3273 []config.Config{ 3274 { 3275 Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3276 Spec: &networking.Gateway{ 3277 Servers: []*networking.Server{ 3278 { 3279 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"}, 3280 Hosts: []string{"*"}, 3281 Bind: "10.0.0.1", 3282 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3283 }, 3284 }, 3285 }, 3286 }, 3287 { 3288 Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3289 Spec: &networking.Gateway{ 3290 Servers: []*networking.Server{ 3291 { 3292 Port: &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"}, 3293 Hosts: []string{"*"}, 3294 Bind: "10.0.0.2", 3295 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3296 }, 3297 }, 3298 }, 3299 }, 3300 }, 3301 []config.Config{ 3302 { 3303 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3304 Spec: &networking.VirtualService{ 3305 Gateways: []string{"testns/gateway1"}, 3306 Hosts: []string{"*"}, 3307 Tcp: []*networking.TCPRoute{ 3308 { 3309 Match: []*networking.L4MatchAttributes{ 3310 { 3311 Port: 9443, 3312 }, 3313 }, 3314 Route: []*networking.RouteDestination{ 3315 { 3316 Destination: &networking.Destination{ 3317 Host: "foo.com", 3318 }, 3319 }, 3320 }, 3321 }, 3322 }, 3323 }, 3324 }, 3325 { 3326 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3327 Spec: &networking.VirtualService{ 3328 Gateways: []string{"testns/gateway2"}, 3329 Hosts: []string{"*"}, 3330 Tcp: []*networking.TCPRoute{ 3331 { 3332 Match: []*networking.L4MatchAttributes{ 3333 { 3334 Port: 9443, 3335 }, 3336 }, 3337 Route: []*networking.RouteDestination{ 3338 { 3339 Destination: &networking.Destination{ 3340 Host: "foo.com", 3341 }, 3342 }, 3343 }, 3344 }, 3345 }, 3346 }, 3347 }, 3348 }, 3349 []string{"10.0.0.1_443", "10.0.0.2_443"}, 3350 }, 3351 } 3352 3353 for _, tt := range cases { 3354 t.Run(tt.name, func(t *testing.T) { 3355 Configs := make([]config.Config, 0) 3356 Configs = append(Configs, tt.gateways...) 3357 Configs = append(Configs, tt.virtualServices...) 3358 cg := NewConfigGenTest(t, TestOptions{ 3359 Configs: Configs, 3360 }) 3361 cg.MemRegistry.WantGetProxyServiceTargets = tt.node.ServiceTargets 3362 proxy := cg.SetupProxy(&proxyGateway) 3363 if tt.node.Metadata != nil { 3364 proxy.Metadata = tt.node.Metadata 3365 } else { 3366 proxy.Metadata = &proxyGatewayMetadata 3367 } 3368 3369 builder := cg.ConfigGen.buildGatewayListeners(NewListenerBuilder(proxy, cg.PushContext())) 3370 listeners := xdstest.ExtractListenerNames(builder.gatewayListeners) 3371 sort.Strings(listeners) 3372 sort.Strings(tt.expectedListeners) 3373 if !reflect.DeepEqual(listeners, tt.expectedListeners) { 3374 t.Fatalf("Expected listeners: %v, got: %v\n%v", tt.expectedListeners, listeners, proxyGateway.MergedGateway.MergedServers) 3375 } 3376 xdstest.ValidateListeners(t, builder.gatewayListeners) 3377 3378 // gateways bind to port, but exact_balance can still be used 3379 for _, l := range builder.gatewayListeners { 3380 if l.ConnectionBalanceConfig != nil { 3381 t.Fatalf("expected connection balance config to be empty, found %v", l.ConnectionBalanceConfig) 3382 } 3383 } 3384 }) 3385 } 3386 } 3387 3388 func TestBuildNameToServiceMapForHttpRoutes(t *testing.T) { 3389 virtualServiceSpec := &networking.VirtualService{ 3390 Hosts: []string{"*"}, 3391 Http: []*networking.HTTPRoute{ 3392 { 3393 Route: []*networking.HTTPRouteDestination{ 3394 { 3395 Destination: &networking.Destination{ 3396 Host: "foo.example.org", 3397 }, 3398 }, 3399 { 3400 Destination: &networking.Destination{ 3401 Host: "bar.example.org", 3402 }, 3403 }, 3404 }, 3405 Mirror: &networking.Destination{ 3406 Host: "baz.example.org", 3407 }, 3408 Mirrors: []*networking.HTTPMirrorPolicy{ 3409 { 3410 Destination: &networking.Destination{ 3411 Host: "bazs.example.org", 3412 }, 3413 }, 3414 { 3415 Destination: &networking.Destination{ 3416 Host: "bazs2.example.org", 3417 }, 3418 }, 3419 }, 3420 }, 3421 }, 3422 } 3423 virtualService := config.Config{ 3424 Meta: config.Meta{ 3425 GroupVersionKind: gvk.VirtualService, 3426 Name: "virtual-service", 3427 Namespace: "test", 3428 }, 3429 Spec: virtualServiceSpec, 3430 } 3431 3432 fooHostName := host.Name("foo.example.org") 3433 fooServiceInTestNamespace := &pilot_model.Service{ 3434 Hostname: fooHostName, 3435 Ports: []*pilot_model.Port{{ 3436 Name: "http", 3437 Protocol: "HTTP", 3438 Port: 80, 3439 }}, 3440 Attributes: pilot_model.ServiceAttributes{ 3441 Namespace: "test", 3442 ExportTo: sets.New(visibility.Private), 3443 }, 3444 } 3445 3446 barHostName := host.Name("bar.example.org") 3447 barServiceInDefaultNamespace := &pilot_model.Service{ 3448 Hostname: barHostName, 3449 Ports: []*pilot_model.Port{{ 3450 Name: "http", 3451 Protocol: "HTTP", 3452 Port: 8080, 3453 }}, 3454 Attributes: pilot_model.ServiceAttributes{ 3455 Namespace: "default", 3456 ExportTo: sets.New(visibility.Public), 3457 }, 3458 } 3459 3460 bazHostName := host.Name("baz.example.org") 3461 bazServiceInDefaultNamespace := &pilot_model.Service{ 3462 Hostname: bazHostName, 3463 Ports: []*pilot_model.Port{{ 3464 Name: "http", 3465 Protocol: "HTTP", 3466 Port: 8090, 3467 }}, 3468 Attributes: pilot_model.ServiceAttributes{ 3469 Namespace: "default", 3470 ExportTo: sets.New(visibility.Private), 3471 }, 3472 } 3473 3474 bazsHostName := host.Name("bazs.example.org") 3475 bazsServiceInDefaultNamespace := &pilot_model.Service{ 3476 Hostname: bazsHostName, 3477 Ports: []*pilot_model.Port{{ 3478 Name: "http", 3479 Protocol: "HTTP", 3480 Port: 8091, 3481 }}, 3482 Attributes: pilot_model.ServiceAttributes{ 3483 Namespace: "default", 3484 ExportTo: sets.New(visibility.Private), 3485 }, 3486 } 3487 bazs2HostName := host.Name("bazs2.example.org") 3488 bazs2ServiceInDefaultNamespace := &pilot_model.Service{ 3489 Hostname: bazs2HostName, 3490 Ports: []*pilot_model.Port{{ 3491 Name: "http", 3492 Protocol: "HTTP", 3493 Port: 8092, 3494 }}, 3495 Attributes: pilot_model.ServiceAttributes{ 3496 Namespace: "default", 3497 ExportTo: sets.New(visibility.Private), 3498 }, 3499 } 3500 3501 cg := NewConfigGenTest(t, TestOptions{ 3502 Configs: []config.Config{virtualService}, 3503 Services: []*pilot_model.Service{ 3504 fooServiceInTestNamespace, barServiceInDefaultNamespace, bazServiceInDefaultNamespace, bazsServiceInDefaultNamespace, bazs2ServiceInDefaultNamespace, 3505 }, 3506 }) 3507 proxy := &pilot_model.Proxy{ 3508 Type: pilot_model.Router, 3509 ConfigNamespace: "test", 3510 } 3511 proxy = cg.SetupProxy(proxy) 3512 3513 nameToServiceMap := buildNameToServiceMapForHTTPRoutes(proxy, cg.env.PushContext(), virtualService) 3514 3515 if len(nameToServiceMap) != 5 { 3516 t.Errorf("The length of nameToServiceMap is wrong.") 3517 } 3518 3519 if service, exist := nameToServiceMap[fooHostName]; !exist || service == nil { 3520 t.Errorf("The service of %s not found or should be not nil.", fooHostName) 3521 } else { 3522 if service.Ports[0].Port != 80 { 3523 t.Errorf("The port of %s is wrong.", fooHostName) 3524 } 3525 3526 if service.Attributes.Namespace != "test" { 3527 t.Errorf("The namespace of %s is wrong.", fooHostName) 3528 } 3529 } 3530 3531 if service, exist := nameToServiceMap[barHostName]; !exist || service == nil { 3532 t.Errorf("The service of %s not found or should be not nil", barHostName) 3533 } else { 3534 if service.Ports[0].Port != 8080 { 3535 t.Errorf("The port of %s is wrong.", barHostName) 3536 } 3537 3538 if service.Attributes.Namespace != "default" { 3539 t.Errorf("The namespace of %s is wrong.", barHostName) 3540 } 3541 } 3542 3543 if service, exist := nameToServiceMap[bazHostName]; !exist || service != nil { 3544 t.Errorf("The value of hostname %s mapping must be exist and it should be nil.", bazHostName) 3545 } 3546 } 3547 3548 func TestBuildGatewayListenersFilters(t *testing.T) { 3549 cases := []struct { 3550 name string 3551 configs []config.Config 3552 proxyConfig *pilot_model.NodeMetaProxyConfig 3553 expectedListener listenertest.ListenerTest 3554 }{ 3555 { 3556 name: "http server", 3557 configs: []config.Config{ 3558 { 3559 Meta: config.Meta{Name: "http-server", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3560 Spec: &networking.Gateway{ 3561 Servers: []*networking.Server{ 3562 { 3563 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 3564 }, 3565 }, 3566 }, 3567 }, 3568 }, 3569 expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{ 3570 { 3571 NetworkFilters: []string{ 3572 wellknown.HTTPConnectionManager, 3573 }, 3574 HTTPFilters: []string{ 3575 xdsfilters.MxFilterName, 3576 xdsfilters.Alpn.GetName(), 3577 xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router, 3578 }, 3579 }, 3580 }}, 3581 }, 3582 { 3583 name: "passthrough server", 3584 configs: []config.Config{ 3585 { 3586 Meta: config.Meta{Name: "passthrough-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3587 Spec: &networking.Gateway{ 3588 Servers: []*networking.Server{ 3589 { 3590 Port: &networking.Port{Name: "tls", Number: 9443, Protocol: "TLS"}, 3591 Hosts: []string{"barone.example.com"}, 3592 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 3593 }, 3594 }, 3595 }, 3596 }, 3597 { 3598 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3599 Spec: &networking.VirtualService{ 3600 Gateways: []string{"testns/passthrough-gateway"}, 3601 Hosts: []string{"barone.example.com"}, 3602 Tls: []*networking.TLSRoute{ 3603 { 3604 Match: []*networking.TLSMatchAttributes{ 3605 { 3606 Port: 9443, 3607 SniHosts: []string{"barone.example.com"}, 3608 }, 3609 }, 3610 Route: []*networking.RouteDestination{ 3611 { 3612 Destination: &networking.Destination{ 3613 Host: "foo.com", 3614 }, 3615 }, 3616 }, 3617 }, 3618 }, 3619 }, 3620 }, 3621 }, 3622 expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{ 3623 { 3624 NetworkFilters: []string{ 3625 wellknown.TCPProxy, 3626 }, 3627 HTTPFilters: []string{}, 3628 TotalMatch: true, 3629 }, 3630 }}, 3631 }, 3632 { 3633 name: "terminated-tls server", 3634 configs: []config.Config{ 3635 { 3636 Meta: config.Meta{Name: "terminated-tls-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3637 Spec: &networking.Gateway{ 3638 Servers: []*networking.Server{ 3639 { 3640 Port: &networking.Port{Name: "tls", Number: 5678, Protocol: "TLS"}, 3641 Hosts: []string{"barone.example.com"}, 3642 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3643 }, 3644 }, 3645 }, 3646 }, 3647 { 3648 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3649 Spec: &networking.VirtualService{ 3650 Gateways: []string{"testns/terminated-tls-gateway"}, 3651 Hosts: []string{"barone.example.com"}, 3652 Tcp: []*networking.TCPRoute{ 3653 { 3654 Match: []*networking.L4MatchAttributes{ 3655 { 3656 Port: 5678, 3657 }, 3658 }, 3659 Route: []*networking.RouteDestination{ 3660 { 3661 Destination: &networking.Destination{ 3662 Host: "foo.com", 3663 }, 3664 }, 3665 }, 3666 }, 3667 }, 3668 }, 3669 }, 3670 }, 3671 expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{ 3672 { 3673 NetworkFilters: []string{ 3674 wellknown.TCPProxy, 3675 }, 3676 HTTPFilters: []string{}, 3677 TotalMatch: true, 3678 }, 3679 }}, 3680 }, 3681 { 3682 name: "non-http istio-mtls server", 3683 configs: []config.Config{ 3684 { 3685 Meta: config.Meta{Name: "non-http-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3686 Spec: &networking.Gateway{ 3687 Servers: []*networking.Server{ 3688 { 3689 Port: &networking.Port{Name: "mtls", Number: 15443, Protocol: "TLS"}, 3690 Hosts: []string{"barone.example.com"}, 3691 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL}, 3692 }, 3693 }, 3694 }, 3695 }, 3696 { 3697 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3698 Spec: &networking.VirtualService{ 3699 Gateways: []string{"testns/non-http-gateway"}, 3700 Hosts: []string{"barone.example.com"}, 3701 Tcp: []*networking.TCPRoute{ 3702 { 3703 Match: []*networking.L4MatchAttributes{ 3704 { 3705 Port: 15443, 3706 }, 3707 }, 3708 Route: []*networking.RouteDestination{ 3709 { 3710 Destination: &networking.Destination{ 3711 Host: "foo.com", 3712 }, 3713 }, 3714 }, 3715 }, 3716 }, 3717 }, 3718 }, 3719 }, 3720 expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{ 3721 { 3722 NetworkFilters: []string{ 3723 xdsfilters.TCPListenerMx.GetName(), 3724 wellknown.TCPProxy, 3725 }, 3726 HTTPFilters: []string{}, 3727 TotalMatch: true, 3728 }, 3729 }}, 3730 }, 3731 { 3732 name: "http and tcp istio-mtls server", 3733 configs: []config.Config{ 3734 { 3735 Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3736 Spec: &networking.Gateway{ 3737 Servers: []*networking.Server{ 3738 { 3739 Port: &networking.Port{Name: "mtls", Number: 15443, Protocol: "HTTPS"}, 3740 Hosts: []string{"www.example.com"}, 3741 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL}, 3742 }, 3743 { 3744 Port: &networking.Port{Name: "mtls", Number: 15443, Protocol: "TLS"}, 3745 Hosts: []string{"tcp.example.com"}, 3746 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL}, 3747 }, 3748 }, 3749 }, 3750 }, 3751 { 3752 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3753 Spec: &networking.VirtualService{ 3754 Gateways: []string{"testns/gateway"}, 3755 Hosts: []string{"www.example.com"}, 3756 Http: []*networking.HTTPRoute{ 3757 { 3758 Match: []*networking.HTTPMatchRequest{ 3759 { 3760 Port: 15443, 3761 }, 3762 }, 3763 Route: []*networking.HTTPRouteDestination{ 3764 { 3765 Destination: &networking.Destination{ 3766 Host: "http.com", 3767 }, 3768 }, 3769 }, 3770 }, 3771 }, 3772 }, 3773 }, 3774 { 3775 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3776 Spec: &networking.VirtualService{ 3777 Gateways: []string{"testns/gateway"}, 3778 Hosts: []string{"tcp.example.com"}, 3779 Tcp: []*networking.TCPRoute{ 3780 { 3781 Match: []*networking.L4MatchAttributes{ 3782 { 3783 Port: 15443, 3784 }, 3785 }, 3786 Route: []*networking.RouteDestination{ 3787 { 3788 Destination: &networking.Destination{ 3789 Host: "tcp.com", 3790 }, 3791 }, 3792 }, 3793 }, 3794 }, 3795 }, 3796 }, 3797 }, 3798 expectedListener: listenertest.ListenerTest{ 3799 TotalMatch: true, 3800 FilterChains: []listenertest.FilterChainTest{ 3801 { 3802 TotalMatch: true, // there must be only 1 `istio_authn` network filter 3803 NetworkFilters: []string{ 3804 wellknown.HTTPConnectionManager, 3805 }, 3806 HTTPFilters: []string{ 3807 xdsfilters.MxFilterName, 3808 xdsfilters.GrpcStats.GetName(), 3809 xdsfilters.Alpn.GetName(), 3810 xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router, 3811 }, 3812 }, 3813 { 3814 TotalMatch: true, // there must be only 1 `istio_authn` network filter 3815 NetworkFilters: []string{ 3816 xdsfilters.TCPListenerMx.GetName(), 3817 wellknown.TCPProxy, 3818 }, 3819 HTTPFilters: []string{}, 3820 }, 3821 }, 3822 }, 3823 }, 3824 { 3825 name: "http server with proxy proto", 3826 configs: []config.Config{ 3827 { 3828 Meta: config.Meta{Name: "http-server", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3829 Spec: &networking.Gateway{ 3830 Servers: []*networking.Server{ 3831 { 3832 Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, 3833 }, 3834 }, 3835 }, 3836 }, 3837 }, 3838 proxyConfig: &pilot_model.NodeMetaProxyConfig{ 3839 GatewayTopology: &meshconfig.Topology{ProxyProtocol: &meshconfig.Topology_ProxyProtocolConfiguration{}}, 3840 }, 3841 expectedListener: listenertest.ListenerTest{ 3842 FilterChains: []listenertest.FilterChainTest{ 3843 { 3844 NetworkFilters: []string{ 3845 wellknown.HTTPConnectionManager, 3846 }, 3847 HTTPFilters: []string{ 3848 xdsfilters.MxFilterName, 3849 wellknown.HTTPGRPCStats, 3850 xdsfilters.Alpn.GetName(), 3851 xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router, 3852 }, 3853 TotalMatch: true, 3854 }, 3855 }, 3856 Filters: []string{wellknown.ProxyProtocol}, 3857 }, 3858 }, 3859 { 3860 name: "terminated-tls server with proxy proto", 3861 configs: []config.Config{ 3862 { 3863 Meta: config.Meta{Name: "terminated-tls-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3864 Spec: &networking.Gateway{ 3865 Servers: []*networking.Server{ 3866 { 3867 Port: &networking.Port{Name: "tls", Number: 5678, Protocol: "TLS"}, 3868 Hosts: []string{"barone.example.com"}, 3869 Tls: &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE}, 3870 }, 3871 }, 3872 }, 3873 }, 3874 { 3875 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3876 Spec: &networking.VirtualService{ 3877 Gateways: []string{"testns/terminated-tls-gateway"}, 3878 Hosts: []string{"barone.example.com"}, 3879 Tcp: []*networking.TCPRoute{ 3880 { 3881 Match: []*networking.L4MatchAttributes{ 3882 { 3883 Port: 5678, 3884 }, 3885 }, 3886 Route: []*networking.RouteDestination{ 3887 { 3888 Destination: &networking.Destination{ 3889 Host: "foo.com", 3890 }, 3891 }, 3892 }, 3893 }, 3894 }, 3895 }, 3896 }, 3897 }, 3898 proxyConfig: &pilot_model.NodeMetaProxyConfig{ 3899 GatewayTopology: &meshconfig.Topology{ProxyProtocol: &meshconfig.Topology_ProxyProtocolConfiguration{}}, 3900 }, 3901 expectedListener: listenertest.ListenerTest{ 3902 FilterChains: []listenertest.FilterChainTest{ 3903 { 3904 NetworkFilters: []string{ 3905 wellknown.TCPProxy, 3906 }, 3907 HTTPFilters: []string{}, 3908 TotalMatch: true, 3909 }, 3910 }, 3911 Filters: []string{wellknown.ProxyProtocol}, 3912 }, 3913 }, 3914 { 3915 name: "TCP RBAC and Stats", 3916 configs: []config.Config{ 3917 { 3918 Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3919 Spec: &networking.Gateway{ 3920 Servers: []*networking.Server{ 3921 { 3922 Port: &networking.Port{Name: "tcp", Number: 100, Protocol: "TCP"}, 3923 Hosts: []string{"www.example.com"}, 3924 }, 3925 }, 3926 }, 3927 }, 3928 { 3929 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3930 Spec: &networking.VirtualService{ 3931 Gateways: []string{"testns/gateway"}, 3932 Hosts: []string{"www.example.com"}, 3933 Tcp: []*networking.TCPRoute{ 3934 { 3935 Route: []*networking.RouteDestination{ 3936 { 3937 Destination: &networking.Destination{ 3938 Host: "http.com", 3939 }, 3940 }, 3941 }, 3942 }, 3943 }, 3944 }, 3945 }, 3946 { 3947 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy}, 3948 Spec: &security.AuthorizationPolicy{}, 3949 }, 3950 { 3951 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry}, 3952 Spec: &telemetry.Telemetry{ 3953 Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}}, 3954 }, 3955 }, 3956 }, 3957 expectedListener: listenertest.ListenerTest{ 3958 TotalMatch: true, 3959 FilterChains: []listenertest.FilterChainTest{ 3960 { 3961 TotalMatch: true, 3962 NetworkFilters: []string{ 3963 wellknown.RoleBasedAccessControl, 3964 xds.StatsFilterName, 3965 wellknown.TCPProxy, 3966 }, 3967 }, 3968 }, 3969 }, 3970 }, 3971 { 3972 name: "mTLS, RBAC, WASM, and Stats", 3973 configs: []config.Config{ 3974 { 3975 Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 3976 Spec: &networking.Gateway{ 3977 Servers: []*networking.Server{ 3978 { 3979 Port: &networking.Port{Name: "tcp", Number: 100, Protocol: "TCP"}, 3980 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL}, 3981 Hosts: []string{"www.example.com"}, 3982 }, 3983 }, 3984 }, 3985 }, 3986 { 3987 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 3988 Spec: &networking.VirtualService{ 3989 Gateways: []string{"testns/gateway"}, 3990 Hosts: []string{"www.example.com"}, 3991 Tcp: []*networking.TCPRoute{ 3992 { 3993 Route: []*networking.RouteDestination{ 3994 { 3995 Destination: &networking.Destination{ 3996 Host: "http.com", 3997 }, 3998 }, 3999 }, 4000 }, 4001 }, 4002 }, 4003 }, 4004 { 4005 Meta: config.Meta{Name: "wasm-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4006 Spec: &extensions.WasmPlugin{ 4007 Phase: extensions.PluginPhase_AUTHZ, 4008 Type: extensions.PluginType_NETWORK, 4009 }, 4010 }, 4011 { 4012 Meta: config.Meta{Name: "wasm-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4013 Spec: &extensions.WasmPlugin{ 4014 Phase: extensions.PluginPhase_AUTHN, 4015 Type: extensions.PluginType_NETWORK, 4016 }, 4017 }, 4018 { 4019 Meta: config.Meta{Name: "wasm-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4020 Spec: &extensions.WasmPlugin{ 4021 Phase: extensions.PluginPhase_STATS, 4022 Type: extensions.PluginType_NETWORK, 4023 }, 4024 }, 4025 { 4026 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy}, 4027 Spec: &security.AuthorizationPolicy{}, 4028 }, 4029 { 4030 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy}, 4031 Spec: &security.AuthorizationPolicy{ 4032 Action: security.AuthorizationPolicy_CUSTOM, 4033 ActionDetail: &security.AuthorizationPolicy_Provider{Provider: &security.AuthorizationPolicy_ExtensionProvider{Name: "extauthz"}}, 4034 }, 4035 }, 4036 { 4037 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry}, 4038 Spec: &telemetry.Telemetry{ 4039 Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}}, 4040 }, 4041 }, 4042 }, 4043 expectedListener: listenertest.ListenerTest{ 4044 TotalMatch: true, 4045 FilterChains: []listenertest.FilterChainTest{ 4046 { 4047 TotalMatch: true, 4048 NetworkFilters: []string{ 4049 xdsfilters.MxFilterName, 4050 // Ext auth makes 2 filters 4051 wellknown.RoleBasedAccessControl, 4052 wellknown.ExternalAuthorization, 4053 "extenstions.istio.io/wasmplugin/istio-system.wasm-authn", 4054 "extenstions.istio.io/wasmplugin/istio-system.wasm-authz", 4055 wellknown.RoleBasedAccessControl, 4056 "extenstions.istio.io/wasmplugin/istio-system.wasm-stats", 4057 xds.StatsFilterName, 4058 wellknown.TCPProxy, 4059 }, 4060 }, 4061 }, 4062 }, 4063 }, 4064 { 4065 name: "HTTP RBAC, WASM, and Stats", 4066 configs: []config.Config{ 4067 { 4068 Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 4069 Spec: &networking.Gateway{ 4070 Servers: []*networking.Server{ 4071 { 4072 Port: &networking.Port{Name: "http", Number: 200, Protocol: "HTTP"}, 4073 Hosts: []string{"www.example.com"}, 4074 }, 4075 }, 4076 }, 4077 }, 4078 { 4079 Meta: config.Meta{Name: "wasm-network-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4080 Spec: &extensions.WasmPlugin{ 4081 Phase: extensions.PluginPhase_AUTHZ, 4082 Type: extensions.PluginType_NETWORK, 4083 }, 4084 }, 4085 { 4086 Meta: config.Meta{Name: "wasm-network-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4087 Spec: &extensions.WasmPlugin{ 4088 Phase: extensions.PluginPhase_AUTHN, 4089 Type: extensions.PluginType_NETWORK, 4090 }, 4091 }, 4092 { 4093 Meta: config.Meta{Name: "wasm-network-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4094 Spec: &extensions.WasmPlugin{ 4095 Phase: extensions.PluginPhase_STATS, 4096 Type: extensions.PluginType_NETWORK, 4097 }, 4098 }, 4099 { 4100 Meta: config.Meta{Name: "wasm-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4101 Spec: &extensions.WasmPlugin{ 4102 Phase: extensions.PluginPhase_AUTHZ, 4103 }, 4104 }, 4105 { 4106 Meta: config.Meta{Name: "wasm-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4107 Spec: &extensions.WasmPlugin{ 4108 Phase: extensions.PluginPhase_AUTHN, 4109 }, 4110 }, 4111 { 4112 Meta: config.Meta{Name: "wasm-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin}, 4113 Spec: &extensions.WasmPlugin{ 4114 Phase: extensions.PluginPhase_STATS, 4115 }, 4116 }, 4117 { 4118 Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService}, 4119 Spec: &networking.VirtualService{ 4120 Gateways: []string{"testns/gateway"}, 4121 Hosts: []string{"www.example.com"}, 4122 Http: []*networking.HTTPRoute{ 4123 { 4124 Route: []*networking.HTTPRouteDestination{ 4125 { 4126 Destination: &networking.Destination{ 4127 Host: "http.com", 4128 }, 4129 }, 4130 }, 4131 }, 4132 }, 4133 }, 4134 }, 4135 { 4136 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy}, 4137 Spec: &security.AuthorizationPolicy{ 4138 Action: security.AuthorizationPolicy_CUSTOM, 4139 ActionDetail: &security.AuthorizationPolicy_Provider{Provider: &security.AuthorizationPolicy_ExtensionProvider{Name: "extauthz"}}, 4140 }, 4141 }, 4142 { 4143 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy}, 4144 Spec: &security.AuthorizationPolicy{}, 4145 }, 4146 { 4147 Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry}, 4148 Spec: &telemetry.Telemetry{ 4149 Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}}, 4150 }, 4151 }, 4152 }, 4153 expectedListener: listenertest.ListenerTest{ 4154 TotalMatch: true, 4155 FilterChains: []listenertest.FilterChainTest{ 4156 { 4157 TotalMatch: true, 4158 NetworkFilters: []string{ 4159 "extenstions.istio.io/wasmplugin/istio-system.wasm-network-authn", 4160 "extenstions.istio.io/wasmplugin/istio-system.wasm-network-authz", 4161 "extenstions.istio.io/wasmplugin/istio-system.wasm-network-stats", 4162 wellknown.HTTPConnectionManager, 4163 }, 4164 HTTPFilters: []string{ 4165 xdsfilters.MxFilterName, 4166 // Ext auth makes 2 filters 4167 wellknown.HTTPRoleBasedAccessControl, 4168 wellknown.HTTPExternalAuthorization, 4169 "extenstions.istio.io/wasmplugin/istio-system.wasm-authn", 4170 "extenstions.istio.io/wasmplugin/istio-system.wasm-authz", 4171 wellknown.HTTPRoleBasedAccessControl, 4172 "extenstions.istio.io/wasmplugin/istio-system.wasm-stats", 4173 wellknown.HTTPGRPCStats, 4174 xdsfilters.Alpn.Name, 4175 xdsfilters.Fault.Name, 4176 xdsfilters.Cors.Name, 4177 xds.StatsFilterName, 4178 wellknown.Router, 4179 }, 4180 }, 4181 }, 4182 }, 4183 }, 4184 } 4185 for _, tt := range cases { 4186 t.Run(tt.name, func(t *testing.T) { 4187 mc := mesh.DefaultMeshConfig() 4188 mc.ExtensionProviders = append(mc.ExtensionProviders, &meshconfig.MeshConfig_ExtensionProvider{ 4189 Name: "extauthz", 4190 Provider: &meshconfig.MeshConfig_ExtensionProvider_EnvoyExtAuthzGrpc{ 4191 EnvoyExtAuthzGrpc: &meshconfig.MeshConfig_ExtensionProvider_EnvoyExternalAuthorizationGrpcProvider{ 4192 Service: "foo/example.local", 4193 Port: 1234, 4194 }, 4195 }, 4196 }) 4197 4198 cg := NewConfigGenTest(t, TestOptions{ 4199 Configs: tt.configs, 4200 MeshConfig: mc, 4201 }) 4202 cg.PushContext().ServiceIndex.HostnameAndNamespace = map[host.Name]map[string]*pilot_model.Service{ 4203 "example.local": { 4204 "foo": &pilot_model.Service{ 4205 Hostname: "example.local", 4206 }, 4207 }, 4208 } 4209 proxy := cg.SetupProxy(&proxyGateway) 4210 metadata := proxyGatewayMetadata 4211 metadata.ProxyConfig = tt.proxyConfig 4212 proxy.Metadata = &metadata 4213 4214 lb := NewListenerBuilder(proxy, cg.PushContext()) 4215 builder := cg.ConfigGen.buildGatewayListeners(lb) 4216 listenertest.VerifyListeners(t, builder.gatewayListeners, listenertest.ListenersTest{ 4217 Listener: tt.expectedListener, 4218 }) 4219 }) 4220 } 4221 } 4222 4223 func TestGatewayFilterChainSNIOverlap(t *testing.T) { 4224 cases := []struct { 4225 name string 4226 gateways []config.Config 4227 virtualServices []config.Config 4228 }{ 4229 { 4230 name: "no sni overlap", 4231 gateways: []config.Config{ 4232 { 4233 Meta: config.Meta{Name: "gw", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 4234 Spec: &networking.Gateway{ 4235 Servers: []*networking.Server{ 4236 { 4237 Port: &networking.Port{Name: "example", Number: 443, Protocol: "TLS"}, 4238 Hosts: []string{"example.com"}, 4239 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 4240 }, 4241 }, 4242 }, 4243 }, 4244 }, 4245 virtualServices: []config.Config{ 4246 { 4247 Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService}, 4248 Spec: &networking.VirtualService{ 4249 Gateways: []string{"testns/gw"}, 4250 Hosts: []string{"example.com"}, 4251 Tls: []*networking.TLSRoute{ 4252 { 4253 Match: []*networking.TLSMatchAttributes{ 4254 { 4255 SniHosts: []string{"example.com"}, 4256 }, 4257 }, 4258 Route: []*networking.RouteDestination{ 4259 { 4260 Destination: &networking.Destination{ 4261 Host: "example", 4262 }, 4263 }, 4264 }, 4265 }, 4266 }, 4267 }, 4268 }, 4269 }, 4270 }, 4271 { 4272 name: "sni overlap in one gateway", 4273 gateways: []config.Config{ 4274 { 4275 Meta: config.Meta{Name: "gw", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 4276 Spec: &networking.Gateway{ 4277 Servers: []*networking.Server{ 4278 { 4279 Port: &networking.Port{Name: "example", Number: 443, Protocol: "TLS"}, 4280 Hosts: []string{"example.com"}, 4281 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 4282 }, 4283 { 4284 Port: &networking.Port{Name: "wildcard-tls", Number: 443, Protocol: "HTTPS"}, 4285 Hosts: []string{"*"}, 4286 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 4287 }, 4288 }, 4289 }, 4290 }, 4291 }, 4292 virtualServices: []config.Config{ 4293 { 4294 Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService}, 4295 Spec: &networking.VirtualService{ 4296 Gateways: []string{"testns/gw"}, 4297 Hosts: []string{"example.com"}, 4298 Tls: []*networking.TLSRoute{ 4299 { 4300 Match: []*networking.TLSMatchAttributes{ 4301 { 4302 SniHosts: []string{"example.com"}, 4303 }, 4304 }, 4305 Route: []*networking.RouteDestination{ 4306 { 4307 Destination: &networking.Destination{ 4308 Host: "example", 4309 }, 4310 }, 4311 }, 4312 }, 4313 }, 4314 }, 4315 }, 4316 }, 4317 }, 4318 { 4319 name: "sni overlap in two gateways", 4320 gateways: []config.Config{ 4321 { 4322 Meta: config.Meta{Name: "gw1", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 4323 Spec: &networking.Gateway{ 4324 Servers: []*networking.Server{ 4325 { 4326 Port: &networking.Port{Name: "example", Number: 443, Protocol: "TLS"}, 4327 Hosts: []string{"example.com"}, 4328 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 4329 }, 4330 }, 4331 }, 4332 }, 4333 { 4334 Meta: config.Meta{Name: "gw2", Namespace: "testns", GroupVersionKind: gvk.Gateway}, 4335 Spec: &networking.Gateway{ 4336 Servers: []*networking.Server{ 4337 { 4338 Port: &networking.Port{Name: "wildcard-tls", Number: 443, Protocol: "HTTPS"}, 4339 Hosts: []string{"*"}, 4340 Tls: &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH}, 4341 }, 4342 }, 4343 }, 4344 }, 4345 }, 4346 virtualServices: []config.Config{ 4347 { 4348 Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService}, 4349 Spec: &networking.VirtualService{ 4350 Gateways: []string{"testns/gw2"}, 4351 Hosts: []string{"example.com"}, 4352 Tls: []*networking.TLSRoute{ 4353 { 4354 Match: []*networking.TLSMatchAttributes{ 4355 { 4356 SniHosts: []string{"example.com"}, 4357 }, 4358 }, 4359 Route: []*networking.RouteDestination{ 4360 { 4361 Destination: &networking.Destination{ 4362 Host: "example", 4363 }, 4364 }, 4365 }, 4366 }, 4367 }, 4368 }, 4369 }, 4370 }, 4371 }, 4372 } 4373 4374 for _, tt := range cases { 4375 t.Run(tt.name, func(t *testing.T) { 4376 configs := make([]config.Config, 0) 4377 configs = append(configs, tt.gateways...) 4378 configs = append(configs, tt.virtualServices...) 4379 cg := NewConfigGenTest(t, TestOptions{ 4380 Configs: configs, 4381 }) 4382 proxy := cg.SetupProxy(&proxyGateway) 4383 proxy.Metadata = &proxyGatewayMetadata 4384 4385 builder := cg.ConfigGen.buildGatewayListeners(NewListenerBuilder(proxy, cg.PushContext())) 4386 xdstest.ValidateListeners(t, builder.gatewayListeners) 4387 }) 4388 } 4389 } 4390 4391 func TestGatewayHCMInternalAddressConfig(t *testing.T) { 4392 cg := NewConfigGenTest(t, TestOptions{}) 4393 proxy := &pilot_model.Proxy{ 4394 Type: pilot_model.Router, 4395 ConfigNamespace: "test", 4396 } 4397 proxy = cg.SetupProxy(proxy) 4398 test.SetForTest(t, &features.EnableHCMInternalNetworks, true) 4399 push := cg.PushContext() 4400 cases := []struct { 4401 name string 4402 networks *meshconfig.MeshNetworks 4403 expectedconfig *hcm.HttpConnectionManager_InternalAddressConfig 4404 }{ 4405 { 4406 name: "nil networks", 4407 expectedconfig: nil, 4408 }, 4409 { 4410 name: "empty networks", 4411 networks: &meshconfig.MeshNetworks{}, 4412 expectedconfig: nil, 4413 }, 4414 { 4415 name: "networks populated", 4416 networks: &meshconfig.MeshNetworks{ 4417 Networks: map[string]*meshconfig.Network{ 4418 "default": { 4419 Endpoints: []*meshconfig.Network_NetworkEndpoints{ 4420 { 4421 Ne: &meshconfig.Network_NetworkEndpoints_FromCidr{ 4422 FromCidr: "192.168.0.0/16", 4423 }, 4424 }, 4425 { 4426 Ne: &meshconfig.Network_NetworkEndpoints_FromCidr{ 4427 FromCidr: "172.16.0.0/12", 4428 }, 4429 }, 4430 }, 4431 }, 4432 }, 4433 }, 4434 expectedconfig: &hcm.HttpConnectionManager_InternalAddressConfig{ 4435 CidrRanges: []*core.CidrRange{ 4436 { 4437 AddressPrefix: "192.168.0.0", 4438 PrefixLen: &wrappers.UInt32Value{Value: 16}, 4439 }, 4440 { 4441 AddressPrefix: "172.16.0.0", 4442 PrefixLen: &wrappers.UInt32Value{Value: 12}, 4443 }, 4444 }, 4445 }, 4446 }, 4447 } 4448 for _, tt := range cases { 4449 t.Run(tt.name, func(t *testing.T) { 4450 push.Networks = tt.networks 4451 httpConnManager := buildGatewayConnectionManager(&meshconfig.ProxyConfig{}, proxy, false, push) 4452 if !reflect.DeepEqual(tt.expectedconfig, httpConnManager.InternalAddressConfig) { 4453 t.Errorf("unexpected internal address config, expected: %v, got :%v", tt.expectedconfig, httpConnManager.InternalAddressConfig) 4454 } 4455 }) 4456 } 4457 }