Skip to content

Commit

Permalink
feat: use RSA key for kube-apiserver service account key
Browse files Browse the repository at this point in the history
Fixes #8111

Starting with 1.7, use RSA instead of ECDSA.

RSA is way slower, but it has better support with other providers.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
  • Loading branch information
smira committed Jan 31, 2024
1 parent a5e13c6 commit 7af48bd
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
6 changes: 6 additions & 0 deletions hack/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ machine:
features:
localDNS: false
```
"""

[notes.rsa-service-account]
title = "Kubernetes API Server Service Account Key"
description = """\
Talos Linux starting from this release uses RSA key for Kubernetes API Server Service Account instead of ECDSA key to provide better compatibility with external OpenID Connect implementations.
"""

[make_deps]
Expand Down
6 changes: 6 additions & 0 deletions pkg/machinery/config/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type VersionContract struct {
// Well-known Talos version contracts.
var (
TalosVersionCurrent = (*VersionContract)(nil)
TalosVersion1_7 = &VersionContract{1, 7}
TalosVersion1_6 = &VersionContract{1, 6}
TalosVersion1_5 = &VersionContract{1, 5}
TalosVersion1_4 = &VersionContract{1, 4}
Expand Down Expand Up @@ -184,3 +185,8 @@ func (contract *VersionContract) KubePrismEnabled() bool {
func (contract *VersionContract) LocalDNSEnabled() bool {
return contract.Greater(TalosVersion1_6)
}

// UseRSAServiceAccountKey returns true if version of Talos should use RSA Service Account key for the kube-apiserver.
func (contract *VersionContract) UseRSAServiceAccountKey() bool {
return contract.Greater(TalosVersion1_6)
}
57 changes: 57 additions & 0 deletions pkg/machinery/config/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,35 @@ func TestContractCurrent(t *testing.T) {
assert.True(t, contract.SecretboxEncryptionSupported())
assert.True(t, contract.DiskQuotaSupportEnabled())
assert.True(t, contract.KubePrismEnabled())
assert.True(t, contract.LocalDNSEnabled())
assert.True(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_7(t *testing.T) {
contract := config.TalosVersion1_7

assert.True(t, contract.SupportsAggregatorCA())
assert.True(t, contract.SupportsECDSAKeys())
assert.True(t, contract.SupportsServiceAccount())
assert.True(t, contract.SupportsRBACFeature())
assert.True(t, contract.SupportsDynamicCertSANs())
assert.True(t, contract.SupportsECDSASHA256())
assert.True(t, contract.ClusterDiscoveryEnabled())
assert.False(t, contract.PodSecurityPolicyEnabled())
assert.True(t, contract.PodSecurityAdmissionEnabled())
assert.True(t, contract.StableHostnameEnabled())
assert.True(t, contract.KubeletDefaultRuntimeSeccompProfileEnabled())
assert.False(t, contract.KubernetesAlternateImageRegistries())
assert.True(t, contract.KubernetesAllowSchedulingOnControlPlanes())
assert.True(t, contract.KubernetesDiscoveryBackendDisabled())
assert.True(t, contract.ApidExtKeyUsageCheckEnabled())
assert.True(t, contract.APIServerAuditPolicySupported())
assert.True(t, contract.KubeletManifestsDirectoryDisabled())
assert.True(t, contract.SecretboxEncryptionSupported())
assert.True(t, contract.DiskQuotaSupportEnabled())
assert.True(t, contract.KubePrismEnabled())
assert.True(t, contract.LocalDNSEnabled())
assert.True(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_6(t *testing.T) {
Expand All @@ -92,6 +121,8 @@ func TestContract1_6(t *testing.T) {
assert.True(t, contract.SecretboxEncryptionSupported())
assert.True(t, contract.DiskQuotaSupportEnabled())
assert.True(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_5(t *testing.T) {
Expand All @@ -117,6 +148,8 @@ func TestContract1_5(t *testing.T) {
assert.True(t, contract.SecretboxEncryptionSupported())
assert.True(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_4(t *testing.T) {
Expand All @@ -142,6 +175,8 @@ func TestContract1_4(t *testing.T) {
assert.True(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_3(t *testing.T) {
Expand All @@ -167,6 +202,8 @@ func TestContract1_3(t *testing.T) {
assert.True(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_2(t *testing.T) {
Expand All @@ -192,6 +229,8 @@ func TestContract1_2(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_1(t *testing.T) {
Expand All @@ -217,6 +256,8 @@ func TestContract1_1(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract1_0(t *testing.T) {
Expand All @@ -242,6 +283,8 @@ func TestContract1_0(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_14(t *testing.T) {
Expand All @@ -267,6 +310,8 @@ func TestContract0_14(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_13(t *testing.T) {
Expand All @@ -292,6 +337,8 @@ func TestContract0_13(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_12(t *testing.T) {
Expand All @@ -317,6 +364,8 @@ func TestContract0_12(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_11(t *testing.T) {
Expand All @@ -342,6 +391,8 @@ func TestContract0_11(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_10(t *testing.T) {
Expand All @@ -367,6 +418,8 @@ func TestContract0_10(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_9(t *testing.T) {
Expand All @@ -392,6 +445,8 @@ func TestContract0_9(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}

func TestContract0_8(t *testing.T) {
Expand All @@ -417,4 +472,6 @@ func TestContract0_8(t *testing.T) {
assert.False(t, contract.SecretboxEncryptionSupported())
assert.False(t, contract.DiskQuotaSupportEnabled())
assert.False(t, contract.KubePrismEnabled())
assert.False(t, contract.LocalDNSEnabled())
assert.False(t, contract.UseRSAServiceAccountKey())
}
23 changes: 17 additions & 6 deletions pkg/machinery/config/generate/secrets/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,24 @@ func (bundle *Bundle) populate(versionContract *config.VersionContract) error {
}

if versionContract.SupportsServiceAccount() && bundle.Certs.K8sServiceAccount == nil {
serviceAccount, err := x509.NewECDSAKey()
if err != nil {
return err
}
if versionContract.UseRSAServiceAccountKey() {
serviceAccount, err := x509.NewRSAKey()
if err != nil {
return err
}

bundle.Certs.K8sServiceAccount = &x509.PEMEncodedKey{
Key: serviceAccount.KeyPEM,
bundle.Certs.K8sServiceAccount = &x509.PEMEncodedKey{
Key: serviceAccount.KeyPEM,
}
} else {
serviceAccount, err := x509.NewECDSAKey()
if err != nil {
return err
}

bundle.Certs.K8sServiceAccount = &x509.PEMEncodedKey{
Key: serviceAccount.KeyPEM,
}
}
}

Expand Down

0 comments on commit 7af48bd

Please sign in to comment.