go.temporal.io/server@v1.23.0/common/rpc/test/rpc_localstore_tls_test.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package rpc 26 27 import ( 28 "crypto/tls" 29 "crypto/x509" 30 "os" 31 "testing" 32 "time" 33 34 "github.com/golang/mock/gomock" 35 "github.com/stretchr/testify/require" 36 "github.com/stretchr/testify/suite" 37 "google.golang.org/grpc" 38 "google.golang.org/grpc/credentials" 39 40 "go.temporal.io/server/common/config" 41 "go.temporal.io/server/common/log" 42 "go.temporal.io/server/common/metrics" 43 "go.temporal.io/server/common/rpc" 44 "go.temporal.io/server/common/rpc/encryption" 45 "go.temporal.io/server/tests/testutils" 46 ) 47 48 const ( 49 internodeServerCertSerialNumber = 100 50 frontendServerCertSerialNumber = 150 51 ) 52 53 var ( 54 frontendURL = "dummy://" // not needed for test 55 noExtraInterceptors = []grpc.UnaryClientInterceptor{} 56 ) 57 58 type localStoreRPCSuite struct { 59 *require.Assertions 60 *suite.Suite 61 62 controller *gomock.Controller 63 64 logger log.Logger 65 66 insecureRPCFactory *TestFactory 67 internodeMutualTLSRPCFactory *TestFactory 68 internodeServerTLSRPCFactory *TestFactory 69 internodeAltMutualTLSRPCFactory *TestFactory 70 frontendMutualTLSRPCFactory *TestFactory 71 frontendServerTLSRPCFactory *TestFactory 72 frontendSystemWorkerMutualTLSRPCFactory *TestFactory 73 frontendDynamicTLSFactory *TestFactory 74 internodeDynamicTLSFactory *TestFactory 75 internodeMutualTLSRPCRefreshFactory *TestFactory 76 frontendMutualTLSRPCRefreshFactory *TestFactory 77 remoteClusterMutualTLSRPCFactory *TestFactory 78 frontendConfigRootCAForceTLSFactory *TestFactory 79 80 internodeCertDir string 81 frontendCertDir string 82 frontendAltCertDir string 83 frontendRollingCertDir string 84 internodeRefreshCertDir string 85 frontendRefreshCertDir string 86 87 internodeChain testutils.CertChain 88 frontendChain testutils.CertChain 89 frontendAltChain testutils.CertChain 90 frontendRollingCerts []*tls.Certificate 91 internodeRefreshChain testutils.CertChain 92 internodeRefreshCA *tls.Certificate 93 frontendRefreshChain testutils.CertChain 94 frontendRefreshCA *tls.Certificate 95 96 frontendClientCertDir string 97 frontendClientChain testutils.CertChain 98 99 membershipConfig config.Membership 100 frontendConfigServerTLS config.GroupTLS 101 frontendConfigMutualTLS config.GroupTLS 102 frontendConfigPerHostOverrides config.GroupTLS 103 frontendConfigRootCAOnly config.GroupTLS 104 frontendConfigRootCAForceTLS config.GroupTLS 105 frontendConfigAltRootCAOnly config.GroupTLS 106 systemWorkerOnly config.WorkerTLS 107 frontendConfigSystemWorker config.WorkerTLS 108 frontendConfigMutualTLSRefresh config.GroupTLS 109 110 internodeConfigMutualTLS config.GroupTLS 111 internodeConfigServerTLS config.GroupTLS 112 internodeConfigAltMutualTLS config.GroupTLS 113 internodeConfigMutualTLSRefresh config.GroupTLS 114 115 dynamicCACertPool *x509.CertPool 116 wrongCACertPool *x509.CertPool 117 118 dynamicConfigProvider *encryption.TestDynamicTLSConfigProvider 119 } 120 121 func TestLocalStoreTLSSuite(t *testing.T) { 122 suite.Run(t, &localStoreRPCSuite{ 123 Suite: &suite.Suite{}, 124 }) 125 } 126 127 func (s *localStoreRPCSuite) TearDownSuite() { 128 _ = os.RemoveAll(s.internodeCertDir) 129 _ = os.RemoveAll(s.frontendCertDir) 130 } 131 132 func (s *localStoreRPCSuite) SetupSuite() { 133 s.Assertions = require.New(s.T()) 134 s.logger = log.NewTestLogger() 135 136 provider, err := encryption.NewTLSConfigProviderFromConfig(serverCfgInsecure.TLS, metrics.NoopMetricsHandler, s.logger, nil) 137 s.NoError(err) 138 insecureFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, nil, noExtraInterceptors) 139 s.NotNil(insecureFactory) 140 s.insecureRPCFactory = i(insecureFactory) 141 142 s.frontendCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontend") 143 s.NoError(err) 144 s.frontendChain, err = testutils.GenerateTestChain(s.frontendCertDir, localhostIPv4) 145 s.NoError(err) 146 147 s.internodeCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteInternode") 148 s.NoError(err) 149 s.internodeChain, err = testutils.GenerateTestChain(s.internodeCertDir, localhostIPv4) 150 s.NoError(err) 151 152 s.frontendAltCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendAlt") 153 s.NoError(err) 154 s.frontendAltChain, err = testutils.GenerateTestChain(s.frontendAltCertDir, localhost) 155 s.NoError(err) 156 157 s.frontendClientCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendClient") 158 s.NoError(err) 159 s.frontendClientChain, err = testutils.GenerateTestChain(s.frontendClientCertDir, localhostIPv4) 160 s.NoError(err) 161 162 s.frontendRollingCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendRolling") 163 s.NoError(err) 164 s.frontendRollingCerts, s.dynamicCACertPool, s.wrongCACertPool, err = testutils.GenerateTestCerts(s.frontendRollingCertDir, localhostIPv4, 2) 165 s.NoError(err) 166 167 s.internodeRefreshCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteInternodeRefresh") 168 s.NoError(err) 169 s.internodeRefreshChain, s.internodeRefreshCA, err = testutils.GenerateTestChainWithSN(s.internodeRefreshCertDir, localhostIPv4, internodeServerCertSerialNumber) 170 s.NoError(err) 171 172 s.frontendRefreshCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendRefresh") 173 s.NoError(err) 174 s.frontendRefreshChain, s.frontendRefreshCA, err = testutils.GenerateTestChainWithSN(s.frontendRefreshCertDir, localhostIPv4, frontendServerCertSerialNumber) 175 s.NoError(err) 176 177 s.membershipConfig = config.Membership{ 178 MaxJoinDuration: 5, 179 BroadcastAddress: localhostIPv4, 180 } 181 182 frontendConfigBase := config.GroupTLS{ 183 Server: config.ServerTLS{ 184 CertFile: s.frontendChain.CertPubFile, 185 KeyFile: s.frontendChain.CertKeyFile, 186 }, 187 } 188 189 s.frontendConfigServerTLS = frontendConfigBase 190 s.frontendConfigServerTLS.Client = config.ClientTLS{RootCAFiles: []string{s.frontendChain.CaPubFile}} 191 192 s.frontendConfigMutualTLS = frontendConfigBase 193 s.frontendConfigMutualTLS.Server.ClientCAFiles = []string{s.frontendClientChain.CaPubFile} 194 s.frontendConfigMutualTLS.Server.RequireClientAuth = true 195 196 s.frontendConfigPerHostOverrides = s.frontendConfigServerTLS 197 s.frontendConfigPerHostOverrides.PerHostOverrides = map[string]config.ServerTLS{ 198 localhost: { 199 CertFile: s.frontendAltChain.CertPubFile, 200 KeyFile: s.frontendAltChain.CertKeyFile, 201 ClientCAFiles: []string{s.frontendAltChain.CaPubFile}, 202 RequireClientAuth: true, 203 }, 204 } 205 s.frontendConfigRootCAOnly = config.GroupTLS{ 206 Client: config.ClientTLS{ 207 RootCAData: []string{testutils.ConvertFileToBase64(s.frontendChain.CaPubFile)}, 208 }, 209 } 210 s.frontendConfigRootCAForceTLS = s.frontendConfigRootCAOnly 211 s.frontendConfigRootCAForceTLS.Client.ForceTLS = true 212 213 s.frontendConfigAltRootCAOnly = config.GroupTLS{ 214 Server: config.ServerTLS{ 215 RequireClientAuth: true, 216 }, 217 Client: config.ClientTLS{ 218 RootCAData: []string{testutils.ConvertFileToBase64(s.frontendAltChain.CaPubFile)}, 219 }, 220 } 221 s.systemWorkerOnly = config.WorkerTLS{ 222 CertFile: s.frontendClientChain.CertPubFile, 223 KeyFile: s.frontendClientChain.CertKeyFile, 224 } 225 s.frontendConfigSystemWorker = s.systemWorkerOnly 226 s.frontendConfigSystemWorker.Client = config.ClientTLS{ 227 RootCAFiles: []string{s.frontendChain.CaPubFile}, 228 } 229 230 s.internodeConfigMutualTLS = config.GroupTLS{ 231 Server: config.ServerTLS{ 232 CertFile: s.internodeChain.CertPubFile, 233 KeyFile: s.internodeChain.CertKeyFile, 234 ClientCAFiles: []string{s.internodeChain.CaPubFile}, 235 RequireClientAuth: true, 236 }, 237 Client: config.ClientTLS{ 238 RootCAFiles: []string{s.internodeChain.CaPubFile}, 239 }, 240 } 241 s.internodeConfigServerTLS = config.GroupTLS{ 242 Server: config.ServerTLS{ 243 CertData: testutils.ConvertFileToBase64(s.internodeChain.CertPubFile), 244 KeyData: testutils.ConvertFileToBase64(s.internodeChain.CertKeyFile), 245 }, 246 Client: config.ClientTLS{ 247 RootCAData: []string{testutils.ConvertFileToBase64(s.internodeChain.CaPubFile)}, 248 }, 249 } 250 s.internodeConfigAltMutualTLS = config.GroupTLS{ 251 Server: config.ServerTLS{ 252 CertFile: s.frontendAltChain.CertPubFile, 253 KeyFile: s.frontendAltChain.CertKeyFile, 254 ClientCAFiles: []string{s.frontendAltChain.CaPubFile}, 255 RequireClientAuth: true, 256 }, 257 Client: config.ClientTLS{ 258 RootCAFiles: []string{s.frontendAltChain.CaPubFile}, 259 }, 260 } 261 262 s.internodeConfigMutualTLSRefresh = mutualGroupTLSFromChain(s.internodeRefreshChain) 263 s.frontendConfigMutualTLSRefresh = mutualGroupTLSFromChain(s.frontendRefreshChain) 264 } 265 266 func mutualGroupTLSFromChain(chain testutils.CertChain) config.GroupTLS { 267 return config.GroupTLS{ 268 Server: config.ServerTLS{ 269 CertFile: chain.CertPubFile, 270 KeyFile: chain.CertKeyFile, 271 ClientCAFiles: []string{chain.CaPubFile}, 272 RequireClientAuth: true, 273 }, 274 Client: config.ClientTLS{ 275 RootCAFiles: []string{chain.CaPubFile}, 276 }, 277 } 278 } 279 280 func (s *localStoreRPCSuite) SetupTest() { 281 s.controller = gomock.NewController(s.T()) 282 283 s.setupInternode() 284 s.setupFrontend() 285 } 286 287 func (s *localStoreRPCSuite) TearDownTest() { 288 s.controller.Finish() 289 } 290 291 func (s *localStoreRPCSuite) setupFrontend() { 292 localStoreServerTLS := &config.Global{ 293 Membership: s.membershipConfig, 294 TLS: config.RootTLS{ 295 Frontend: s.frontendConfigServerTLS, 296 }, 297 } 298 299 localStoreMutualTLS := &config.Global{ 300 Membership: s.membershipConfig, 301 TLS: config.RootTLS{ 302 Frontend: s.frontendConfigPerHostOverrides, 303 }, 304 } 305 306 localStoreMutualTLSSystemWorker := &config.Global{ 307 Membership: s.membershipConfig, 308 TLS: config.RootTLS{ 309 Internode: s.internodeConfigMutualTLS, 310 Frontend: s.frontendConfigMutualTLS, 311 SystemWorker: s.frontendConfigSystemWorker, 312 }, 313 } 314 315 localStoreMutualTLSWithRefresh := &config.Global{ 316 Membership: s.membershipConfig, 317 TLS: config.RootTLS{ 318 Frontend: s.frontendConfigMutualTLSRefresh, 319 Internode: s.frontendConfigMutualTLSRefresh, 320 RefreshInterval: time.Second, 321 ExpirationChecks: config.CertExpirationValidation{ 322 WarningWindow: time.Hour * 24 * 14, 323 ErrorWindow: time.Hour * 24 * 7, 324 CheckInterval: time.Second, 325 }, 326 }, 327 } 328 329 localStoreRootCAForceTLS := &config.Global{ 330 Membership: s.membershipConfig, 331 TLS: config.RootTLS{ 332 Frontend: s.frontendConfigRootCAForceTLS, 333 }, 334 } 335 336 localStoreMutualTLSRemoteCluster := &config.Global{ 337 Membership: s.membershipConfig, 338 TLS: config.RootTLS{ 339 Frontend: s.frontendConfigPerHostOverrides, 340 RemoteClusters: map[string]config.GroupTLS{localhostIPv4: s.frontendConfigPerHostOverrides}, 341 }, 342 } 343 344 provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 345 s.NoError(err) 346 tlsConfig, err := provider.GetFrontendClientConfig() 347 s.NoError(err) 348 frontendMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 349 s.NotNil(frontendMutualTLSFactory) 350 351 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreServerTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 352 s.NoError(err) 353 frontendServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, nil, noExtraInterceptors) 354 s.NotNil(frontendServerTLSFactory) 355 356 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSSystemWorker.TLS, metrics.NoopMetricsHandler, s.logger, nil) 357 s.NoError(err) 358 tlsConfig, err = provider.GetFrontendClientConfig() 359 s.NoError(err) 360 frontendSystemWorkerMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 361 s.NotNil(frontendSystemWorkerMutualTLSFactory) 362 363 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSWithRefresh.TLS, metrics.NoopMetricsHandler, s.logger, nil) 364 s.NoError(err) 365 tlsConfig, err = provider.GetFrontendClientConfig() 366 s.NoError(err) 367 frontendMutualTLSRefreshFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 368 s.NotNil(frontendMutualTLSRefreshFactory) 369 370 s.frontendMutualTLSRPCFactory = f(frontendMutualTLSFactory) 371 s.frontendServerTLSRPCFactory = f(frontendServerTLSFactory) 372 s.frontendSystemWorkerMutualTLSRPCFactory = f(frontendSystemWorkerMutualTLSFactory) 373 374 s.dynamicConfigProvider, err = encryption.NewTestDynamicTLSConfigProvider( 375 &localStoreMutualTLS.TLS, 376 s.frontendRollingCerts, 377 s.dynamicCACertPool, 378 s.frontendRollingCerts, 379 s.dynamicCACertPool, 380 s.wrongCACertPool) 381 s.NoError(err) 382 tlsConfig, err = s.dynamicConfigProvider.GetFrontendClientConfig() 383 s.NoError(err) 384 dynamicServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, s.dynamicConfigProvider, frontendURL, tlsConfig, noExtraInterceptors) 385 s.frontendDynamicTLSFactory = f(dynamicServerTLSFactory) 386 s.internodeDynamicTLSFactory = i(dynamicServerTLSFactory) 387 388 s.frontendMutualTLSRPCRefreshFactory = f(frontendMutualTLSRefreshFactory) 389 390 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreRootCAForceTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 391 s.NoError(err) 392 tlsConfig, err = provider.GetFrontendClientConfig() 393 s.NoError(err) 394 frontendRootCAForceTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 395 s.NotNil(frontendServerTLSFactory) 396 s.frontendConfigRootCAForceTLSFactory = f(frontendRootCAForceTLSFactory) 397 398 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSRemoteCluster.TLS, metrics.NoopMetricsHandler, s.logger, nil) 399 s.NoError(err) 400 tlsConfig, err = provider.GetFrontendClientConfig() 401 s.NoError(err) 402 remoteClusterMutualTLSRPCFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 403 s.NotNil(remoteClusterMutualTLSRPCFactory) 404 s.remoteClusterMutualTLSRPCFactory = r(remoteClusterMutualTLSRPCFactory) 405 } 406 407 func (s *localStoreRPCSuite) setupInternode() { 408 localStoreServerTLS := &config.Global{ 409 Membership: s.membershipConfig, 410 TLS: config.RootTLS{ 411 Internode: s.internodeConfigServerTLS, 412 Frontend: s.frontendConfigRootCAOnly, 413 }, 414 } 415 416 localStoreMutualTLS := &config.Global{ 417 Membership: s.membershipConfig, 418 TLS: config.RootTLS{ 419 Internode: s.internodeConfigMutualTLS, 420 Frontend: s.frontendConfigRootCAOnly, 421 }, 422 } 423 424 localStoreAltMutualTLS := &config.Global{ 425 Membership: s.membershipConfig, 426 TLS: config.RootTLS{ 427 Internode: s.internodeConfigAltMutualTLS, 428 Frontend: s.frontendConfigAltRootCAOnly, 429 }, 430 } 431 432 localStoreMutualTLSWithRefresh := *localStoreMutualTLS 433 localStoreMutualTLSWithRefresh.TLS.Internode = s.internodeConfigMutualTLSRefresh 434 localStoreMutualTLSWithRefresh.TLS.RefreshInterval = time.Second 435 436 provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 437 s.NoError(err) 438 tlsConfig, err := provider.GetFrontendClientConfig() 439 s.NoError(err) 440 internodeMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 441 s.NotNil(internodeMutualTLSFactory) 442 443 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreServerTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 444 s.NoError(err) 445 tlsConfig, err = provider.GetFrontendClientConfig() 446 s.NoError(err) 447 internodeServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 448 s.NotNil(internodeServerTLSFactory) 449 450 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreAltMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil) 451 s.NoError(err) 452 tlsConfig, err = provider.GetFrontendClientConfig() 453 s.NoError(err) 454 internodeMutualAltTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 455 s.NotNil(internodeMutualAltTLSFactory) 456 457 provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSWithRefresh.TLS, metrics.NoopMetricsHandler, s.logger, nil) 458 s.NoError(err) 459 tlsConfig, err = provider.GetFrontendClientConfig() 460 s.NoError(err) 461 internodeMutualTLSRefreshFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors) 462 s.NotNil(internodeMutualTLSRefreshFactory) 463 464 s.internodeMutualTLSRPCFactory = i(internodeMutualTLSFactory) 465 s.internodeServerTLSRPCFactory = i(internodeServerTLSFactory) 466 s.internodeAltMutualTLSRPCFactory = i(internodeMutualAltTLSFactory) 467 s.internodeMutualTLSRPCRefreshFactory = i(internodeMutualTLSRefreshFactory) 468 } 469 470 func f(r *rpc.RPCFactory) *TestFactory { 471 return &TestFactory{serverUsage: Frontend, RPCFactory: r} 472 } 473 474 func i(r *rpc.RPCFactory) *TestFactory { 475 return &TestFactory{serverUsage: Internode, RPCFactory: r} 476 } 477 478 func r(r *rpc.RPCFactory) *TestFactory { 479 return &TestFactory{serverUsage: RemoteCluster, RPCFactory: r} 480 } 481 482 func (s *localStoreRPCSuite) TestServerTLS() { 483 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.internodeServerTLSRPCFactory, true) 484 } 485 486 func (s *localStoreRPCSuite) TestServerTLSFrontendToFrontend() { 487 runHelloWorldTest(s.Suite, localhostIPv4, s.frontendServerTLSRPCFactory, s.frontendServerTLSRPCFactory, true) 488 } 489 490 func (s *localStoreRPCSuite) TestMutualTLS() { 491 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.internodeMutualTLSRPCFactory, true) 492 } 493 494 func (s *localStoreRPCSuite) TestMutualTLSFrontendToFrontend() { 495 runHelloWorldTest(s.Suite, localhostIPv4, s.frontendMutualTLSRPCFactory, s.frontendMutualTLSRPCFactory, true) 496 } 497 498 func (s *localStoreRPCSuite) TestMutualTLSFrontendToRemoteCluster() { 499 runHelloWorldTest(s.Suite, localhostIPv4, s.remoteClusterMutualTLSRPCFactory, s.remoteClusterMutualTLSRPCFactory, true) 500 } 501 502 func (s *localStoreRPCSuite) TestMutualTLSButClientInsecure() { 503 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.insecureRPCFactory, false) 504 } 505 506 func (s *localStoreRPCSuite) TestServerTLSButClientInsecure() { 507 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.insecureRPCFactory, false) 508 } 509 510 func (s *localStoreRPCSuite) TestMutualTLSButClientNoCert() { 511 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.internodeServerTLSRPCFactory, false) 512 } 513 514 func (s *localStoreRPCSuite) TestServerTLSButClientAddsCert() { 515 runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.internodeMutualTLSRPCFactory, true) 516 } 517 518 func (s *localStoreRPCSuite) TestMutualTLSSystemWorker() { 519 runHelloWorldTest(s.Suite, localhostIPv4, s.frontendSystemWorkerMutualTLSRPCFactory, s.frontendSystemWorkerMutualTLSRPCFactory, true) 520 } 521 522 func (s *localStoreRPCSuite) TestDynamicServerTLSFrontend() { 523 s.testDynamicServerTLS(localhostIPv4, true) 524 } 525 526 func (s *localStoreRPCSuite) TestDynamicServerTLSInternode() { 527 s.testDynamicServerTLS(localhostIPv4, false) 528 } 529 530 func (s *localStoreRPCSuite) TestDynamicServerTLSOverrideFrontend() { 531 s.testDynamicServerTLS(localhost, true) 532 } 533 534 func (s *localStoreRPCSuite) TestDynamicServerTLSOverrideInternode() { 535 s.testDynamicServerTLS(localhost, false) 536 } 537 538 func (s *localStoreRPCSuite) testDynamicServerTLS(host string, frontend bool) { 539 server, client := s.getTestFactory(frontend) 540 var index int 541 s.dynamicConfigProvider.InternodeClientCertProvider.SetServerName(host) 542 s.dynamicConfigProvider.FrontendClientCertProvider.SetServerName(host) 543 runHelloWorldMultipleDials(s.Suite, host, server, client, 5, 544 func(tlsInfo *credentials.TLSInfo, err error) { 545 s.validateTLSInfo(tlsInfo, err, int64((index+1)%2+100)) 546 index++ 547 }) 548 } 549 550 func (s *localStoreRPCSuite) TestDynamicRootCAFrontend() { 551 s.testDynamicRootCA(localhostIPv4, true) 552 } 553 554 func (s *localStoreRPCSuite) TestDynamicRootCAInternode() { 555 s.testDynamicRootCA(localhostIPv4, true) 556 } 557 558 func (s *localStoreRPCSuite) TestDynamicRootCAOverrideFrontend() { 559 s.testDynamicRootCA(localhost, true) 560 } 561 562 func (s *localStoreRPCSuite) TestDynamicRootCAOverrideInternode() { 563 s.testDynamicRootCA(localhost, true) 564 } 565 566 func (s *localStoreRPCSuite) TestCertExpiration() { 567 sixHours := time.Hour * 6 568 s.testCertExpiration(s.insecureRPCFactory, sixHours, 0) 569 s.testCertExpiration(s.internodeMutualTLSRPCFactory, sixHours, 0) 570 s.testCertExpiration(s.internodeServerTLSRPCFactory, sixHours, 0) 571 s.testCertExpiration(s.internodeAltMutualTLSRPCFactory, sixHours, 0) 572 s.testCertExpiration(s.frontendMutualTLSRPCFactory, sixHours, 0) 573 s.testCertExpiration(s.frontendServerTLSRPCFactory, sixHours, 0) 574 s.testCertExpiration(s.frontendSystemWorkerMutualTLSRPCFactory, sixHours, 0) 575 576 twoDays := time.Hour * 48 577 s.testCertExpiration(s.insecureRPCFactory, twoDays, 0) 578 s.testCertExpiration(s.internodeMutualTLSRPCFactory, twoDays, 3) 579 s.testCertExpiration(s.internodeServerTLSRPCFactory, twoDays, 3) 580 s.testCertExpiration(s.internodeAltMutualTLSRPCFactory, twoDays, 2) 581 s.testCertExpiration(s.frontendMutualTLSRPCFactory, twoDays, 4) 582 s.testCertExpiration(s.frontendServerTLSRPCFactory, twoDays, 2) 583 s.testCertExpiration(s.frontendSystemWorkerMutualTLSRPCFactory, twoDays, 6) 584 } 585 586 func (s *localStoreRPCSuite) testCertExpiration(factory *TestFactory, timeWindow time.Duration, nExpiring int) { 587 expiring, expired, err := factory.GetTLSConfigProvider().GetExpiringCerts(timeWindow) 588 s.NotNil(expiring) 589 s.Empty(expired) 590 s.NoError(err) 591 s.Equal(nExpiring, len(expiring)) 592 } 593 594 func (s *localStoreRPCSuite) testDynamicRootCA(host string, frontend bool) { 595 server, client := s.getTestFactory(frontend) 596 var index int 597 valid := true 598 runHelloWorldMultipleDials(s.Suite, host, server, client, 5, 599 func(tlsInfo *credentials.TLSInfo, err error) { 600 if valid { 601 s.NoError(err) 602 } else { 603 s.Error(err) 604 } 605 index++ 606 if index == 2 { 607 s.dynamicConfigProvider.InternodeClientCertProvider.SwitchToWrongServerRootCACerts() 608 s.dynamicConfigProvider.FrontendClientCertProvider.SwitchToWrongServerRootCACerts() 609 valid = false 610 } 611 }) 612 } 613 614 func (s *localStoreRPCSuite) getTestFactory(frontend bool) (server *TestFactory, client *TestFactory) { 615 if frontend { 616 server = s.frontendDynamicTLSFactory 617 client = s.frontendDynamicTLSFactory 618 } else { 619 server = s.internodeDynamicTLSFactory 620 client = s.internodeDynamicTLSFactory 621 } 622 return server, client 623 } 624 625 func (s *localStoreRPCSuite) TestServerTLSRefreshInternode() { 626 s.testServerTLSRefresh(s.internodeMutualTLSRPCRefreshFactory, s.internodeRefreshCA, s.internodeRefreshCertDir, internodeServerCertSerialNumber) 627 } 628 629 func (s *localStoreRPCSuite) TestServerTLSRefreshFrontend() { 630 s.testServerTLSRefresh(s.frontendMutualTLSRPCRefreshFactory, s.frontendRefreshCA, s.frontendRefreshCertDir, frontendServerCertSerialNumber) 631 } 632 633 func (s *localStoreRPCSuite) testServerTLSRefresh(factory *TestFactory, ca *tls.Certificate, certDir string, serialNumber int64) { 634 server, port := startHelloWorldServer(s.Suite, factory) 635 defer server.Stop() 636 637 host := localhostIPv4 + ":" + port 638 tlsInfo, err := dialHelloAndGetTLSInfo(s.Suite, host, factory, factory.serverUsage) 639 s.validateTLSInfo(tlsInfo, err, serialNumber) // serial number of server cert before refresh 640 641 srvrCert, err := testutils.GenerateServerCert(ca, localhostIPv4, serialNumber+100, testutils.CertFilePath(certDir), testutils.KeyFilePath(certDir)) 642 s.NoError(err) 643 s.NotNil(srvrCert) 644 645 time.Sleep(time.Second * 2) // let server refresh certs 646 647 tlsInfo, err = dialHelloAndGetTLSInfo(s.Suite, host, factory, factory.serverUsage) 648 s.validateTLSInfo(tlsInfo, err, serialNumber+100) // serial number of server cert after refresh 649 } 650 651 func (s *localStoreRPCSuite) validateTLSInfo(tlsInfo *credentials.TLSInfo, err error, serialNumber int64) { 652 s.NoError(err) 653 s.NotNil(tlsInfo) 654 s.NotNil(tlsInfo.State.PeerCertificates) 655 sn := (*tlsInfo.State.PeerCertificates[0].SerialNumber).Int64() 656 s.Equal(serialNumber, sn) 657 } 658 659 func (s *localStoreRPCSuite) TestClientForceTLS() { 660 options, err := s.frontendConfigRootCAForceTLSFactory.RPCFactory.GetFrontendGRPCServerOptions() 661 s.NoError(err) 662 s.Nil(options) 663 } 664 665 func (s *localStoreRPCSuite) TestSystemWorkerOnlyConfig() { 666 localStoreSystemWorkerOnly := &config.Global{ 667 Membership: s.membershipConfig, 668 TLS: config.RootTLS{ 669 SystemWorker: s.systemWorkerOnly, 670 }, 671 } 672 provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreSystemWorkerOnly.TLS, metrics.NoopMetricsHandler, s.logger, nil) 673 s.NoError(err) 674 tlsConfig, err := provider.GetFrontendClientConfig() 675 s.NoError(err) 676 s.NotNil(tlsConfig) 677 s.NotNil(tlsConfig.GetClientCertificate) 678 cert, err := tlsConfig.GetClientCertificate(nil) 679 s.NoError(err) 680 s.NotNil(cert) 681 }