Skip to content

Conversation

@gwossum
Copy link
Member

@gwossum gwossum commented Nov 24, 2025

Add TLS certificate reloading on SIGHUP. For httpd service certificates, the configuration is reloaded and certificate and key file locations are updated accordingly. For opentsdb service certificates, certificates and keys at the existing locations are reloaded. If reloading a certificate fails, the currently loaded certificate continues to be used.

Also adds file permission checking for TLS certificates and private keys.

Add TLS certificate reloading on SIGHUP. For httpd service certificates,
the configuration is reloaded and certificate and key file locations are
updated accordingly. For opentsdb service certificates, certificates and
keys at the existing locations are reloaded. If reloading a certificate
fails, the currently loaded certificate continues to be used.

Also adds file permission checking for TLS certificates and private
keys.
Rewrite some tests so that tricks are not used to get a hold of the TLS
certificate in-use. Instead, an HTTP client is used to get the
certificate presented by the http service.
Comment on lines +334 to +337
// VerifyLoad verifies that the certificate at certPath and keyPath will load without error.
// If the certificate can be loaded, a function that will apply the certificate reload is
// returned. Otherwise, an error is returned.
func (cl *TLSCertLoader) VerifyLoad(certPath, keyPath string) (func() error, error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced VerifyLoad is the best name for this method. The name does make sense, because it is used on config reload to verify that that the new configuration and/or certificate will load properly before it is applied. The name is seems off, though, when you consider that it also returns a closure that will apply the change. Maybe something like PrepareReload would be a better name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MakeReloadFunc ??

if out == nil {
out = new(tls.Config)
}
out = new(tls.Config)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caught by a linter. Of course out is nil, this it the top of the method and out is a return variable.

// VerifyReloadTLSCertificate verifies that the configured TLS certificate can be reloaded.
// If so, then a function that will apply the reloaded certificate is returned. If no reload
// action is necessary, then nil is returned for the reload function.
func (s *Service) VerifyReloadTLSCertificate() (func() error, error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing as CertLoader.VerifyReload. Is this the best name for the method?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MakeTlsCertLoaderFunc??? Just a suggestion.

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few suggestions, questions, comments...

config, err := cmd.ParseConfig(options.GetConfigPath())
if err != nil {
return fmt.Errorf("parse config: %s", err)
return fail(fmt.Errorf("error parsing config file: %s", err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the config file path here so we can figure out bad environment variables, etc.


cmd.Logger.Info("Signal received, initializing clean shutdown...")
if sig == syscall.SIGTERM && cmd.Server.LogQueriesOnTermination() {
if logQueries && cmd.Server.LogQueriesOnTermination() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the logQueries variable? Is there a case where we get here with a signal on shutdownCh that is not a SIGTERM?


// VerifyFilePermissivenessF checks if permissions on f are as restrictive
// or more restrictive than maxPerms. if not, then an error is returned.
// For security reasons, there is no VerifyFilePermissiveness functino
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"functino"


f, err := os.Open(tmpFile)
require.NoError(t, err)
defer f.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap in a require.NoError?


f, err := os.Open(tmpFile)
require.NoError(t, err)
defer f.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require.NoError?

HTTPSEnabled: false,
}
applyFunc, err := s.VerifyReloadedConfig(newConfig)
require.Error(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This differs from usage elsewhere in this PR. Does require.ErrorContains imply require.Error? Or do you need to add require.Error to the other places?

HTTPSPrivateKey: ss.KeyPath,
}
applyFunc, err := s.VerifyReloadedConfig(newConfig)
require.Error(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above


// Open service to initialize certLoader
require.NoError(t, s.Open())
defer s.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any possible error?


// Open service to initialize certLoader
require.NoError(t, s.Open())
defer s.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any possible error?

// VerifyReloadTLSCertificate verifies that the configured TLS certificate can be reloaded.
// If so, then a function that will apply the reloaded certificate is returned. If no reload
// action is necessary, then nil is returned for the reload function.
func (s *Service) VerifyReloadTLSCertificate() (func() error, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MakeTlsCertLoaderFunc??? Just a suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants