Skip to content

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

Merged
deansheather merged 4 commits into
mainfrom
dean/multi-tls
Oct 4, 2022
Merged

feat: support multiple certificates in coder server and helm#4150
deansheather merged 4 commits into
mainfrom
dean/multi-tls

Conversation

@deansheather
Copy link
Copy Markdown
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.

Comment thread helm/values.yaml Outdated
@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
Comment thread cli/server.go
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
Copy Markdown
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.

Comment thread cli/server.go
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
Copy Markdown
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
Copy Markdown
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

Comment thread cli/server_test.go
dials int64
)
client := codersdk.New(accessURL)
client.HTTPClient = &http.Client{
Copy link
Copy Markdown
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
Copy Markdown
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

Comment thread cli/server.go Outdated
Comment thread cli/server.go Outdated
Copy link
Copy Markdown
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
Copy Markdown
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