Skip to content

feat: add configurable cipher suites for tls listening #10505

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 13 commits into from
Nov 7, 2023
Prev Previous commit
Next Next commit
add unit tests
  • Loading branch information
Emyrk committed Nov 2, 2023
commit a8c9b769e0866d2edb59a99180e3feea7624abe6
7 changes: 5 additions & 2 deletions cli/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
r.Verbosef(inv, "Shutting down provisioner daemon %d...", id)
err := shutdownWithTimeout(provisionerDaemon.Shutdown, 5*time.Second)
if err != nil {
cliui.Errorf(inv.Stderr, "Failed to shutdown provisioner daemon %d: %s\n", id, err)
cliui.Errorf(inv.Stderr, "Failed to shut down provisioner daemon %d: %s\n", id, err)
return
}
err = provisionerDaemon.Close()
Expand Down Expand Up @@ -1500,6 +1500,9 @@ func configureServerTLS(ctx context.Context, logger slog.Logger, tlsMinVersion,
}

func configureCipherSuites(ctx context.Context, logger slog.Logger, ciphers []string, allowInsecureCiphers bool, minTLS, maxTLS uint16) ([]uint16, error) {
if minTLS > maxTLS {
return nil, xerrors.Errorf("minimum tls version cannot be greater than maximum tls version")
}
if minTLS >= tls.VersionTLS13 {
// The cipher suites config option is ignored for tls 1.3 and higher.
// So this user flag is a no-op if the min version is 1.3.
Expand Down Expand Up @@ -1536,7 +1539,7 @@ func configureCipherSuites(ctx context.Context, logger slog.Logger, ciphers []st
for _, sv := range cipher.SupportedVersions {
versions = append(versions, tls.VersionName(sv))
}
logger.Warn(ctx, "cipher not supported for tls versions allowed, cipher will not be used",
logger.Warn(ctx, "cipher not supported for tls versions enabled, cipher will not be used",
slog.F("cipher", cipher.Name),
slog.F("cipher_supported_versions", strings.Join(versions, ",")),
slog.F("server_min_version", tls.VersionName(minTLS)),
Expand Down
70 changes: 70 additions & 0 deletions cli/server_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ func Test_configureCipherSuites(t *testing.T) {
return ids
}

cipherByName := func(cipher string) *tls.CipherSuite {
for _, c := range append(tls.CipherSuites(), tls.InsecureCipherSuites()...) {
if cipher == c.Name {
c := c
return c
}
}
return nil
}

tests := []struct {
name string
wantErr string
Expand All @@ -43,6 +53,14 @@ func Test_configureCipherSuites(t *testing.T) {
allowInsecure bool
expectCiphers []uint16
}{
{
name: "AllSecure",
minTLS: tls.VersionTLS10,
maxTLS: tls.VersionTLS13,
inputCiphers: cipherNames(tls.CipherSuites()),
wantWarnings: []string{},
expectCiphers: cipherIDs(tls.CipherSuites()),
},
{
name: "AllowInsecure",
minTLS: tls.VersionTLS10,
Expand All @@ -54,7 +72,45 @@ func Test_configureCipherSuites(t *testing.T) {
},
expectCiphers: append(cipherIDs(tls.CipherSuites()), tls.InsecureCipherSuites()[0].ID),
},
{
name: "AllInsecure",
minTLS: tls.VersionTLS10,
maxTLS: tls.VersionTLS13,
inputCiphers: append(cipherNames(tls.CipherSuites()), cipherNames(tls.InsecureCipherSuites())...),
allowInsecure: true,
wantWarnings: []string{
"insecure tls cipher specified",
},
expectCiphers: append(cipherIDs(tls.CipherSuites()), cipherIDs(tls.InsecureCipherSuites())...),
},
{
// Providing ciphers that are not compatible with any tls version
// enabled should generate a warning.
name: "ExcessiveCiphers",
minTLS: tls.VersionTLS10,
maxTLS: tls.VersionTLS11,
inputCiphers: []string{
"TLS_RSA_WITH_AES_128_CBC_SHA",
// Only for TLS 1.3
"TLS_AES_128_GCM_SHA256",
},
allowInsecure: true,
wantWarnings: []string{
"cipher not supported for tls versions",
},
expectCiphers: cipherIDs([]*tls.CipherSuite{
cipherByName("TLS_RSA_WITH_AES_128_CBC_SHA"),
cipherByName("TLS_AES_128_GCM_SHA256"),
}),
},
// Errors
{
name: "NotRealCiphers",
minTLS: tls.VersionTLS10,
maxTLS: tls.VersionTLS13,
inputCiphers: []string{"RSA-Fake"},
wantErr: "unsupported tls ciphers",
},
{
name: "NoCiphers",
minTLS: tls.VersionTLS10,
Expand All @@ -75,6 +131,20 @@ func Test_configureCipherSuites(t *testing.T) {
inputCiphers: cipherNames(tls.CipherSuites()),
wantErr: "tls ciphers cannot be specified when using minimum tls version 1.3",
},
{
name: "TLSUnsupported",
minTLS: tls.VersionTLS10,
maxTLS: tls.VersionTLS13,
// TLS_RSA_WITH_AES_128_GCM_SHA256 only supports tls 1.2
inputCiphers: []string{"TLS_RSA_WITH_AES_128_GCM_SHA256"},
wantErr: "no tls ciphers supported for tls versions",
},
{
name: "Min>Max",
minTLS: tls.VersionTLS13,
maxTLS: tls.VersionTLS12,
wantErr: "minimum tls version cannot be greater than maximum tls version",
},
}
for _, tt := range tests {
tt := tt
Expand Down