mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #123054 from neolit123/1.30-v1beta4-encryption-enhance
kubeadm: enhance encryption algorithm support in v1beta4
This commit is contained in:
commit
2372837838
@ -94,7 +94,7 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
|
||||
obj.APIServer.ExtraEnvs = []kubeadm.EnvVar{}
|
||||
obj.Scheduler.ExtraEnvs = []kubeadm.EnvVar{}
|
||||
obj.Etcd.Local.ExtraEnvs = []kubeadm.EnvVar{}
|
||||
obj.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA
|
||||
obj.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA2048
|
||||
obj.Proxy.Disabled = false
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ type ClusterConfiguration struct {
|
||||
ClusterName string
|
||||
|
||||
// EncryptionAlgorithm holds the type of asymmetric encryption algorithm used for keys and certificates.
|
||||
// Can be "RSA" (default algorithm, key size is 2048) or "ECDSA" (uses the P-256 elliptic curve).
|
||||
// Can be one of "RSA-2048" (default), "RSA-3072", "RSA-4096" or "ECDSA-P256".
|
||||
EncryptionAlgorithm EncryptionAlgorithmType
|
||||
}
|
||||
|
||||
@ -433,9 +433,9 @@ func (cfg *ClusterConfiguration) EncryptionAlgorithmType() EncryptionAlgorithmTy
|
||||
// TODO: remove this function when the feature gate is removed.
|
||||
if enabled, ok := cfg.FeatureGates[features.PublicKeysECDSA]; ok {
|
||||
if enabled {
|
||||
return EncryptionAlgorithmECDSA
|
||||
return EncryptionAlgorithmECDSAP256
|
||||
}
|
||||
return EncryptionAlgorithmRSA
|
||||
return EncryptionAlgorithmRSA2048
|
||||
}
|
||||
return cfg.EncryptionAlgorithm
|
||||
}
|
||||
@ -570,10 +570,14 @@ type EnvVar struct {
|
||||
type EncryptionAlgorithmType string
|
||||
|
||||
const (
|
||||
// EncryptionAlgorithmECDSA defines the ECDSA encryption algorithm type.
|
||||
EncryptionAlgorithmECDSA EncryptionAlgorithmType = "ECDSA"
|
||||
// EncryptionAlgorithmRSA defines the RSA encryption algorithm type.
|
||||
EncryptionAlgorithmRSA EncryptionAlgorithmType = "RSA"
|
||||
// EncryptionAlgorithmECDSAP256 defines the ECDSA encryption algorithm type with curve P256.
|
||||
EncryptionAlgorithmECDSAP256 EncryptionAlgorithmType = "ECDSA-P256"
|
||||
// EncryptionAlgorithmRSA2048 defines the RSA encryption algorithm type with key size 2048 bits.
|
||||
EncryptionAlgorithmRSA2048 EncryptionAlgorithmType = "RSA-2048"
|
||||
// EncryptionAlgorithmRSA3072 defines the RSA encryption algorithm type with key size 3072 bits.
|
||||
EncryptionAlgorithmRSA3072 EncryptionAlgorithmType = "RSA-3072"
|
||||
// EncryptionAlgorithmRSA4096 defines the RSA encryption algorithm type with key size 4096 bits.
|
||||
EncryptionAlgorithmRSA4096 EncryptionAlgorithmType = "RSA-4096"
|
||||
)
|
||||
|
||||
// Timeouts holds various timeouts that apply to kubeadm commands.
|
||||
|
@ -66,7 +66,7 @@ func Convert_kubeadm_ClusterConfiguration_To_v1beta3_ClusterConfiguration(in *ku
|
||||
func Convert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error {
|
||||
// Required to pass validation and fuzzer tests. The field is missing in v1beta3, thus we have to
|
||||
// default it to a sane (default) value in the internal type.
|
||||
out.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA
|
||||
out.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA2048
|
||||
return autoConvert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ const (
|
||||
DefaultImagePullPolicy = corev1.PullIfNotPresent
|
||||
|
||||
// DefaultEncryptionAlgorithm is the default encryption algorithm.
|
||||
DefaultEncryptionAlgorithm = EncryptionAlgorithmRSA
|
||||
DefaultEncryptionAlgorithm = EncryptionAlgorithmRSA2048
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
|
@ -33,8 +33,7 @@ limitations under the License.
|
||||
// The change applies to `ClusterConfiguration` - `APIServer.ExtraArgs, `ControllerManager.ExtraArgs`,
|
||||
// `Scheduler.ExtraArgs`, `Etcd.Local.ExtraArgs`. Also to `NodeRegistrationOptions.KubeletExtraArgs`.
|
||||
// - Add `ClusterConfiguration.EncryptionAlgorithm` that can be used to set the asymmetric encryption algorithm
|
||||
// used for this cluster's keys and certificates. Can be "RSA" (default algorithm, key size is 2048) or
|
||||
// "ECDSA" (uses the P-256 elliptic curve).
|
||||
// used for this cluster's keys and certificates. Can be one of "RSA-2048" (default), "RSA-3072", "RSA-4096" or "ECDSA-P256".
|
||||
// - Add `ClusterConfiguration.DNS.Disabled` and `ClusterConfiguration.Proxy.Disabled` that can be used to disable
|
||||
// the CoreDNS and kube-proxy addons during cluster initialization. Skipping the related addons phases,
|
||||
// during cluster creation will set the same fields to `false`.
|
||||
|
@ -149,7 +149,7 @@ type ClusterConfiguration struct {
|
||||
ClusterName string `json:"clusterName,omitempty"`
|
||||
|
||||
// EncryptionAlgorithm holds the type of asymmetric encryption algorithm used for keys and certificates.
|
||||
// Can be "RSA" (default algorithm, key size is 2048) or "ECDSA" (uses the P-256 elliptic curve).
|
||||
// Can be one of "RSA-2048" (default), "RSA-3072", "RSA-4096" or "ECDSA-P256".
|
||||
// +optional
|
||||
EncryptionAlgorithm EncryptionAlgorithmType `json:"encryptionAlgorithm,omitempty"`
|
||||
}
|
||||
@ -549,10 +549,14 @@ type EnvVar struct {
|
||||
type EncryptionAlgorithmType string
|
||||
|
||||
const (
|
||||
// EncryptionAlgorithmECDSA defines the ECDSA encryption algorithm type.
|
||||
EncryptionAlgorithmECDSA EncryptionAlgorithmType = "ECDSA"
|
||||
// EncryptionAlgorithmRSA defines the RSA encryption algorithm type.
|
||||
EncryptionAlgorithmRSA EncryptionAlgorithmType = "RSA"
|
||||
// EncryptionAlgorithmECDSAP256 defines the ECDSA encryption algorithm type with curve P256.
|
||||
EncryptionAlgorithmECDSAP256 EncryptionAlgorithmType = "ECDSA-P256"
|
||||
// EncryptionAlgorithmRSA2048 defines the RSA encryption algorithm type with key size 2048 bits.
|
||||
EncryptionAlgorithmRSA2048 EncryptionAlgorithmType = "RSA-2048"
|
||||
// EncryptionAlgorithmRSA3072 defines the RSA encryption algorithm type with key size 3072 bits.
|
||||
EncryptionAlgorithmRSA3072 EncryptionAlgorithmType = "RSA-3072"
|
||||
// EncryptionAlgorithmRSA4096 defines the RSA encryption algorithm type with key size 4096 bits.
|
||||
EncryptionAlgorithmRSA4096 EncryptionAlgorithmType = "RSA-4096"
|
||||
)
|
||||
|
||||
// Timeouts holds various timeouts that apply to kubeadm commands.
|
||||
|
@ -73,7 +73,7 @@ func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorLi
|
||||
allErrs = append(allErrs, ValidateHostPort(c.ControlPlaneEndpoint, field.NewPath("controlPlaneEndpoint"))...)
|
||||
allErrs = append(allErrs, ValidateImageRepository(c.ImageRepository, field.NewPath("imageRepository"))...)
|
||||
allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...)
|
||||
allErrs = append(allErrs, ValidateEncryptionAlgorithm(string(c.EncryptionAlgorithm), field.NewPath("encryptionAlgorithm"))...)
|
||||
allErrs = append(allErrs, ValidateEncryptionAlgorithm(c.EncryptionAlgorithm, field.NewPath("encryptionAlgorithm"))...)
|
||||
allErrs = append(allErrs, componentconfigs.Validate(c)...)
|
||||
return allErrs
|
||||
}
|
||||
@ -341,11 +341,16 @@ func ValidateEtcd(e *kubeadm.Etcd, fldPath *field.Path) field.ErrorList {
|
||||
}
|
||||
|
||||
// ValidateEncryptionAlgorithm validates the public key algorithm
|
||||
func ValidateEncryptionAlgorithm(algo string, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateEncryptionAlgorithm(algo kubeadm.EncryptionAlgorithmType, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if algo != string(kubeadm.EncryptionAlgorithmRSA) && algo != string(kubeadm.EncryptionAlgorithmECDSA) {
|
||||
msg := fmt.Sprintf("Invalid encryption algorithm. Must be %q or %q",
|
||||
kubeadm.EncryptionAlgorithmRSA, kubeadm.EncryptionAlgorithmECDSA)
|
||||
knownAlgorithms := sets.New(
|
||||
kubeadm.EncryptionAlgorithmECDSAP256,
|
||||
kubeadm.EncryptionAlgorithmRSA2048,
|
||||
kubeadm.EncryptionAlgorithmRSA3072,
|
||||
kubeadm.EncryptionAlgorithmRSA4096,
|
||||
)
|
||||
if !knownAlgorithms.Has(algo) {
|
||||
msg := fmt.Sprintf("Invalid encryption algorithm %q. Must be one of %v", algo, sets.List(knownAlgorithms))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, algo, msg))
|
||||
}
|
||||
return allErrs
|
||||
|
@ -515,7 +515,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
},
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodename, CRISocket: criPath},
|
||||
}, false},
|
||||
@ -531,7 +531,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
},
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodename, CRISocket: criPath},
|
||||
}, false},
|
||||
@ -547,7 +547,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
},
|
||||
}, false},
|
||||
{"valid InitConfiguration with incorrect IPv4 pod subnet",
|
||||
@ -563,7 +563,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
PodSubnet: "10.0.1.15",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
},
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodename, CRISocket: criPath},
|
||||
}, false},
|
||||
@ -586,7 +586,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
PodSubnet: "10.0.1.15/16",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
},
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodename, CRISocket: criPath},
|
||||
}, true},
|
||||
@ -608,7 +608,7 @@ func TestValidateInitConfiguration(t *testing.T) {
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmECDSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmECDSAP256,
|
||||
},
|
||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodename, CRISocket: criPath},
|
||||
}, true},
|
||||
@ -1197,11 +1197,13 @@ func TestValidateEtcd(t *testing.T) {
|
||||
func TestValidateEncryptionAlgorithm(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
algo string
|
||||
algo kubeadmapi.EncryptionAlgorithmType
|
||||
expectedErrors bool
|
||||
}{
|
||||
{name: "valid RSA", algo: string(kubeadmapi.EncryptionAlgorithmRSA), expectedErrors: false},
|
||||
{name: "valid ECDSA", algo: string(kubeadmapi.EncryptionAlgorithmECDSA), expectedErrors: false},
|
||||
{name: "valid RSA-2048", algo: kubeadmapi.EncryptionAlgorithmRSA2048, expectedErrors: false},
|
||||
{name: "valid RSA-3072", algo: kubeadmapi.EncryptionAlgorithmRSA3072, expectedErrors: false},
|
||||
{name: "valid RSA-4096", algo: kubeadmapi.EncryptionAlgorithmRSA4096, expectedErrors: false},
|
||||
{name: "valid ECDSA-P256", algo: kubeadmapi.EncryptionAlgorithmECDSAP256, expectedErrors: false},
|
||||
{name: "invalid algorithm", algo: "foo", expectedErrors: true},
|
||||
{name: "empty algorithm returns an error", algo: "", expectedErrors: true},
|
||||
}
|
||||
|
@ -43,8 +43,9 @@ const (
|
||||
// InitFeatureGates are the default feature gates for the init command
|
||||
var InitFeatureGates = FeatureList{
|
||||
PublicKeysECDSA: {
|
||||
FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Deprecated},
|
||||
DeprecationMessage: "The PublicKeysECDSA feature gate is deprecated and will be removed after the feature 'ClusterConfiguration.EncryptionAlgorithm' is added.",
|
||||
FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Deprecated},
|
||||
DeprecationMessage: "The PublicKeysECDSA feature gate is deprecated and will be removed when v1beta3 is removed." +
|
||||
" v1beta4 supports a new option 'ClusterConfiguration.EncryptionAlgorithm'.",
|
||||
},
|
||||
RootlessControlPlane: {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Alpha}},
|
||||
EtcdLearnerMode: {FeatureSpec: featuregate.FeatureSpec{Default: true, PreRelease: featuregate.Beta}},
|
||||
|
@ -262,7 +262,7 @@ func TestCreateServiceAccountKeyAndPublicKeyFiles(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err := CreateServiceAccountKeyAndPublicKeyFiles(dir, kubeadmapi.EncryptionAlgorithmRSA)
|
||||
err := CreateServiceAccountKeyAndPublicKeyFiles(dir, kubeadmapi.EncryptionAlgorithmRSA2048)
|
||||
if (err != nil) != tt.expectedErr {
|
||||
t.Fatalf("expected error: %v, got: %v, error: %v", tt.expectedErr, err != nil, err)
|
||||
} else if tt.expectedErr {
|
||||
|
@ -57,7 +57,6 @@ const (
|
||||
CertificateBlockType = "CERTIFICATE"
|
||||
// RSAPrivateKeyBlockType is a possible value for pem.Block.Type.
|
||||
RSAPrivateKeyBlockType = "RSA PRIVATE KEY"
|
||||
rsaKeySize = 2048
|
||||
)
|
||||
|
||||
// CertConfig is a wrapper around certutil.Config extending it with EncryptionAlgorithm.
|
||||
@ -608,12 +607,32 @@ func EncodePublicKeyPEM(key crypto.PublicKey) ([]byte, error) {
|
||||
// NewPrivateKey returns a new private key.
|
||||
var NewPrivateKey = GeneratePrivateKey
|
||||
|
||||
// rsaKeySizeFromAlgorithmType takes a known RSA algorithm defined in the kubeadm API
|
||||
// an returns its key size. For unknown types it returns 0. For an empty type it returns
|
||||
// the default size of 2048.
|
||||
func rsaKeySizeFromAlgorithmType(keyType kubeadmapi.EncryptionAlgorithmType) int {
|
||||
switch keyType {
|
||||
case kubeadmapi.EncryptionAlgorithmRSA2048, "":
|
||||
return 2048
|
||||
case kubeadmapi.EncryptionAlgorithmRSA3072:
|
||||
return 3072
|
||||
case kubeadmapi.EncryptionAlgorithmRSA4096:
|
||||
return 4096
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// GeneratePrivateKey is the default function for generating private keys.
|
||||
func GeneratePrivateKey(keyType kubeadmapi.EncryptionAlgorithmType) (crypto.Signer, error) {
|
||||
if keyType == kubeadmapi.EncryptionAlgorithmECDSA {
|
||||
if keyType == kubeadmapi.EncryptionAlgorithmECDSAP256 {
|
||||
return ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader)
|
||||
}
|
||||
|
||||
rsaKeySize := rsaKeySizeFromAlgorithmType(keyType)
|
||||
if rsaKeySize == 0 {
|
||||
return nil, errors.Errorf("cannot obtain key size from unknown RSA algorithm: %q", keyType)
|
||||
}
|
||||
return rsa.GenerateKey(cryptorand.Reader, rsaKeySize)
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ func TestMain(m *testing.M) {
|
||||
Config: certutil.Config{
|
||||
CommonName: "Root CA 1",
|
||||
},
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmRSA2048,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed generating Root CA: %v", err))
|
||||
@ -141,7 +141,7 @@ func TestHasServerAuth(t *testing.T) {
|
||||
CommonName: "test",
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
},
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmECDSA,
|
||||
EncryptionAlgorithm: kubeadmapi.EncryptionAlgorithmECDSAP256,
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
@ -940,3 +940,24 @@ func TestVerifyCertChain(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSAKeySizeFromAlgorithmType(t *testing.T) {
|
||||
var tests = []struct {
|
||||
algorithm kubeadmapi.EncryptionAlgorithmType
|
||||
expectedSize int
|
||||
}{
|
||||
{algorithm: "unknown", expectedSize: 0},
|
||||
{algorithm: "", expectedSize: 2048},
|
||||
{algorithm: kubeadmapi.EncryptionAlgorithmRSA2048, expectedSize: 2048},
|
||||
{algorithm: kubeadmapi.EncryptionAlgorithmRSA3072, expectedSize: 3072},
|
||||
{algorithm: kubeadmapi.EncryptionAlgorithmRSA4096, expectedSize: 4096},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
t.Run(string(rt.algorithm), func(t *testing.T) {
|
||||
size := rsaKeySizeFromAlgorithmType(rt.algorithm)
|
||||
if size != rt.expectedSize {
|
||||
t.Errorf("expected size: %d, got: %d", rt.expectedSize, size)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ func newPrivateKey(keyType kubeadmapi.EncryptionAlgorithmType) (crypto.Signer, e
|
||||
|
||||
keyName := ""
|
||||
switch keyType {
|
||||
case kubeadmapi.EncryptionAlgorithmECDSA:
|
||||
case kubeadmapi.EncryptionAlgorithmECDSAP256:
|
||||
ecdsa++
|
||||
keyName = fmt.Sprintf("%d.ecdsa", ecdsa)
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user