Skip to content

feat: support multiple certificates in coder server and helm #4150

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

Merged
merged 4 commits into from
Oct 4, 2022

Conversation

deansheather
Copy link
Member

@deansheather deansheather commented Sep 22, 2022

Adds multiple certificate support to coder server and the Helm chart as it's likely admins will want to be able to use multiple certificates to support the new wildcard access feature.

  • Converts --tls-cert-file and --tls-key-file to be array flags instead of single string flags.
  • Changes the TLS certificate loading logic to support accepting two arrays.
  • Adds new Helm value coder.tls.secretNames for loading multiple certificates.
  • Moves the TLS certificate templating logic to _helpers.tpl.
  • Deprecate coder.tls.secretName in favor of coder.tls.secretNames.
  • Add NOTES.txt that informs users if they are using the deprecated value and says hi. :)

TODO:

  • Tests for the coder server multiple certificate loading functionality.
  • Tests of the Helm chart using helm template and helm install --dry-run to ensure template correctness.
  • Manual tests of the Helm chart in real clusters.

@deansheather deansheather marked this pull request as ready for review September 29, 2022 08:46
@deansheather deansheather requested review from coadler and kylecarbs and removed request for kylecarbs September 29, 2022 08:46
cli/server.go Outdated
Comment on lines 1078 to 1098
tlsConfig.GetCertificate = func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
// If there's only one certificate, return it.
if len(certs) == 1 {
return &certs[0], nil
}

// Expensively check which certificate matches the client hello.
for _, cert := range certs {
cert := cert
if err := hi.SupportsCertificate(&cert); err == nil {
return &cert, nil
}
}

// Return the first certificate if we have one, or return nil so the
// server doesn't fail.
if len(certs) > 0 {
return &certs[0], nil
}
return nil, nil //nolint:nilnil
}
Copy link
Member

Choose a reason for hiding this comment

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

👍 This allows us to hot reload certs later.

func configureTLS(listener net.Listener, tlsMinVersion, tlsClientAuth, tlsCertFile, tlsKeyFile, tlsClientCAFile string) (net.Listener, error) {
func loadCertificates(tlsCertFiles, tlsKeyFiles []string) ([]tls.Certificate, error) {
if len(tlsCertFiles) != len(tlsKeyFiles) {
return nil, xerrors.New("--tls-cert-file and --tls-key-file must be used the same amount of times")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, xerrors.New("--tls-cert-file and --tls-key-file must be used the same amount of times")
return nil, xerrors.New("the number of --tls-cert-file and --tls-key-file must be the same")

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 personally think the old message is better, what do you think @kylecarbs

dials int64
)
client := codersdk.New(accessURL)
client.HTTPClient = &http.Client{
Copy link
Member

Choose a reason for hiding this comment

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

Could add the certs to the client. But not a big deal as you verify hostname later 🤷

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 going to leave this as-is because we will get better test failure messages if the server somehow returns an unexpected certificate

Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

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

Did you manually test the Helm chart with multiple certificates? Just to confirm that it all works.

All the code looks good to me, and I'm impressed with how thorough the tests are 🥳

@deansheather
Copy link
Member Author

Tested with real helm deployment and found a few bugs in the Helm chart which are now fixed in the latest commit. The coder binary worked flawlessly though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants