-
Notifications
You must be signed in to change notification settings - Fork 45
allow filestore to automatically update certificates #6598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ | |
| #include <cloud/filestore/libs/service_local/config.h> | ||
| #include <cloud/filestore/libs/service_local/service.h> | ||
| #include <cloud/filestore/libs/service_null/service.h> | ||
| #include <cloud/filestore/libs/storage/api/components.h> | ||
| #include <cloud/filestore/libs/storage/core/probes.h> | ||
| #include <cloud/filestore/libs/storage/fastshard/bootstrap/core.h> | ||
| #include <cloud/filestore/libs/storage/fastshard/client/async_client.h> | ||
|
|
@@ -85,8 +86,51 @@ const TString ServerMetricsComponent = "server"; | |
|
|
||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| struct TClientCertificateProviderFactory | ||
| { | ||
| ILoggingServicePtr Logging; | ||
| TString LogComponent; | ||
| ISchedulerPtr Scheduler; | ||
| ITaskQueuePtr LongRunningTaskExecutor; | ||
| NMonitoring::TDynamicCountersPtr ServerGroup; | ||
| TDuration RefreshInterval; | ||
|
|
||
| TClientCertificateProviderFactory( | ||
| ILoggingServicePtr logging, | ||
| TString logComponent, | ||
| ISchedulerPtr scheduler, | ||
| ITaskQueuePtr longRunningTaskExecutor, | ||
| NMonitoring::TDynamicCountersPtr serverGroup, | ||
| TDuration refreshInterval) | ||
| : Logging(std::move(logging)) | ||
| , LogComponent(std::move(logComponent)) | ||
| , Scheduler(std::move(scheduler)) | ||
| , LongRunningTaskExecutor(std::move(longRunningTaskExecutor)) | ||
| , ServerGroup(std::move(serverGroup)) | ||
| , RefreshInterval(refreshInterval) | ||
| {} | ||
|
|
||
| ICertificateProviderPtr Build( | ||
| TString rootCertPath, | ||
| TVector<TCertificateFiles> certificates) const | ||
| { | ||
| return CreateCertificateProvider( | ||
| Logging, | ||
| LogComponent, | ||
| Scheduler, | ||
| LongRunningTaskExecutor, | ||
| ServerGroup, | ||
| std::move(rootCertPath), | ||
| std::move(certificates), | ||
| RefreshInterval); | ||
| } | ||
| }; | ||
|
|
||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| ICertificateProviderPtr CreateClientCertificateProvider( | ||
| const NClient::TClientConfigPtr& config) | ||
| const NClient::TClientConfigPtr& config, | ||
| const TClientCertificateProviderFactory& factory) | ||
| { | ||
| TVector<NCloud::TCertificateFiles> certPathList { | ||
| { | ||
|
|
@@ -95,7 +139,12 @@ ICertificateProviderPtr CreateClientCertificateProvider( | |
| } | ||
| }; | ||
|
|
||
| return CreateStaticCertificateProvider( | ||
| if (config->GetSecurePort() && certPathList.empty()) { | ||
| ythrow yexception() | ||
| << "Secure client port is configured without certificates"; | ||
| } | ||
|
|
||
| return factory.Build( | ||
| config->GetRootCertsFile(), | ||
| std::move(certPathList)); | ||
| } | ||
|
|
@@ -107,24 +156,29 @@ class TFileStoreEndpoints final | |
| { | ||
| private: | ||
| using TEndpointsMap = TMap<TString, IFileStoreServicePtr>; | ||
| using TCertificateProvidersMap = TMap<TString, ICertificateProviderPtr>; | ||
|
|
||
| private: | ||
| TClientCertificateProviderFactory CertificateProviderFactory; | ||
| ITimerPtr Timer; | ||
| ISchedulerPtr Scheduler; | ||
| ILoggingServicePtr Logging; | ||
| IFileStoreServicePtr LocalService; | ||
| IActorSystemPtr ActorSystem; | ||
|
|
||
| TEndpointsMap Endpoints; | ||
| TCertificateProvidersMap CertificateProviders; | ||
|
|
||
| public: | ||
| TFileStoreEndpoints( | ||
| TClientCertificateProviderFactory certificateProviderFactory, | ||
| ITimerPtr timer, | ||
| ISchedulerPtr scheduler, | ||
| ILoggingServicePtr logging, | ||
| IFileStoreServicePtr localService, | ||
| IActorSystemPtr actorSystem) | ||
| : Timer(std::move(timer)) | ||
| : CertificateProviderFactory(std::move(certificateProviderFactory)) | ||
| , Timer(std::move(timer)) | ||
| , Scheduler(std::move(scheduler)) | ||
| , Logging(std::move(logging)) | ||
| , LocalService(std::move(localService)) | ||
|
|
@@ -133,6 +187,11 @@ class TFileStoreEndpoints final | |
|
|
||
| void Start() override | ||
| { | ||
| for (const auto& [name, certificateProvider]: CertificateProviders) { | ||
| Y_UNUSED(name); | ||
| certificateProvider->Start(); | ||
| } | ||
|
|
||
| for (const auto& [name, endpoint]: Endpoints) { | ||
| endpoint->Start(); | ||
| } | ||
|
|
@@ -143,6 +202,11 @@ class TFileStoreEndpoints final | |
| for (const auto& [name, endpoint]: Endpoints) { | ||
| endpoint->Stop(); | ||
| } | ||
|
|
||
| for (const auto& [name, certificateProvider]: CertificateProviders) { | ||
| Y_UNUSED(name); | ||
| certificateProvider->Stop(); | ||
| } | ||
| } | ||
|
|
||
| IFileStoreServicePtr GetEndpoint(const TString& name) override | ||
|
|
@@ -159,6 +223,7 @@ class TFileStoreEndpoints final | |
| ui32 permanentActorCount) | ||
| { | ||
| auto clientConfig = std::make_shared<NClient::TClientConfig>(config); | ||
| ICertificateProviderPtr certificateProvider; | ||
| IFileStoreServicePtr fileStore; | ||
| switch (kind) { | ||
| case NDaemon::EServiceKind::Null: { | ||
|
|
@@ -178,19 +243,28 @@ class TFileStoreEndpoints final | |
| if (LocalService) { | ||
| fileStore = LocalService; | ||
| } else { | ||
| certificateProvider = CreateClientCertificateProvider( | ||
| clientConfig, | ||
| CertificateProviderFactory); | ||
| fileStore = NClient::CreateFileStoreClient( | ||
| clientConfig, | ||
| Logging, | ||
| CreateClientCertificateProvider(clientConfig)); | ||
| certificateProvider); | ||
| } | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return AddEndpoint( | ||
| const bool inserted = AddEndpoint( | ||
| name, | ||
| std::move(clientConfig), | ||
| std::move(fileStore)); | ||
|
|
||
| if (inserted && certificateProvider) { | ||
| CertificateProviders.emplace(name, std::move(certificateProvider)); | ||
| } | ||
|
|
||
| return inserted; | ||
| } | ||
|
|
||
| bool Empty() const | ||
|
|
@@ -367,6 +441,10 @@ void TBootstrapVhost::InitComponents() | |
| Configs->VhostServiceConfig->GetEndpointStorageType()); | ||
| } | ||
|
|
||
| if (Configs->ServerConfig->GetRefreshCertsPeriod()) { | ||
| LongRunningTaskExecutor = CreateLongRunningTaskExecutor("CertRefresh"); | ||
| } | ||
|
|
||
| switch (Configs->Options->Service) { | ||
| case NDaemon::EServiceKind::Local: | ||
| case NDaemon::EServiceKind::Kikimr: | ||
|
|
@@ -394,10 +472,24 @@ void TBootstrapVhost::InitComponents() | |
| }); | ||
| } | ||
|
|
||
| if (!certPathList.empty()) { | ||
| CertificateProvider = CreateStaticCertificateProvider( | ||
| if (certPathList.empty()) { | ||
| if (Configs->ServerConfig->GetSecurePort()) { | ||
| ythrow yexception() | ||
| << "Secure port is configured without certificates"; | ||
| } | ||
|
|
||
| CertificateProvider = CreateCertificateProviderStub(); | ||
| } else { | ||
| CertificateProvider = CreateCertificateProvider( | ||
| Logging, | ||
| GetComponentName( | ||
| NStorage::TFileStoreComponents::TLS_CERTIFICATE_PROVIDER), | ||
| Scheduler, | ||
| LongRunningTaskExecutor, | ||
| serverCounters, | ||
| Configs->ServerConfig->GetRootCertsFile(), | ||
| std::move(certPathList)); | ||
| std::move(certPathList), | ||
| Configs->ServerConfig->GetRefreshCertsPeriod()); | ||
| } | ||
|
|
||
| Server = CreateServer( | ||
|
|
@@ -459,7 +551,17 @@ void TBootstrapVhost::InitEndpoints() | |
| localServiceConfig->Utf8DebugString().Quote().c_str()); | ||
| } | ||
|
|
||
| TClientCertificateProviderFactory certFactory( | ||
| Logging, | ||
| GetComponentName( | ||
| NStorage::TFileStoreComponents::TLS_CERTIFICATE_PROVIDER), | ||
| Scheduler, | ||
| LongRunningTaskExecutor, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For vhost remote endpoints with Useful? React with 👍 / 👎. |
||
| FilestoreCounters->GetSubgroup("component", VhostMetricsComponent), | ||
| Configs->ServerConfig->GetRefreshCertsPeriod()); | ||
|
|
||
| auto endpoints = std::make_shared<TFileStoreEndpoints>( | ||
| std::move(certFactory), | ||
| Timer, | ||
| Scheduler, | ||
| Logging, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When vhost is configured with
RefreshCertsPeriodand a remote service endpoint usesSecurePort, this helper now returns a periodic certificate provider owned only by the filestore client.TFileStoreEndpoints::Start()only starts the durable endpoint, and the client start path never callsCertificateProvider->Start()(unlike the top-level daemonCertificateProviderstarted byTBootstrapCommon), so the provider never publishes its initial materials or schedules reloads; TLS clients created from it can miss certificates and automatic refresh does not work. Store/start/stop these client providers with the endpoint lifecycle before using them for secure channels.Useful? React with 👍 / 👎.