2018-08-20 04:37:04 +00:00
package pki
import (
"context"
"crypto/rsa"
"fmt"
2018-11-03 01:45:23 +00:00
"reflect"
2019-05-23 17:57:35 +00:00
"sort"
2019-12-12 06:00:21 +00:00
"strings"
2018-08-20 04:37:04 +00:00
"github.com/rancher/rke/hosts"
"github.com/rancher/rke/log"
2019-08-19 17:53:15 +00:00
"github.com/rancher/rke/pki/cert"
2020-07-11 16:24:19 +00:00
v3 "github.com/rancher/rke/types"
2020-03-08 09:07:56 +00:00
"github.com/sirupsen/logrus"
2018-08-20 04:37:04 +00:00
)
2018-11-12 23:24:59 +00:00
func GenerateKubeAPICertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate API certificate and key
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2018-08-20 04:37:04 +00:00
kubernetesServiceIP , err := GetKubernetesServiceIP ( rkeConfig . Services . KubeAPI . ServiceClusterIPRange )
if err != nil {
return fmt . Errorf ( "Failed to get Kubernetes Service IP: %v" , err )
}
clusterDomain := rkeConfig . Services . Kubelet . ClusterDomain
cpHosts := hosts . NodesToHosts ( rkeConfig . Nodes , controlRole )
kubeAPIAltNames := GetAltNames ( cpHosts , clusterDomain , kubernetesServiceIP , rkeConfig . Authentication . SANs )
2018-11-03 01:45:23 +00:00
kubeAPICert := certs [ KubeAPICertName ] . Certificate
if kubeAPICert != nil &&
reflect . DeepEqual ( kubeAPIAltNames . DNSNames , kubeAPICert . DNSNames ) &&
2019-07-24 20:25:14 +00:00
DeepEqualIPsAltNames ( kubeAPIAltNames . IPs , kubeAPICert . IPAddresses ) && ! rotate {
2018-11-03 01:45:23 +00:00
return nil
2018-08-20 04:37:04 +00:00
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kubernetes API server certificates" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeAPICertName ] . Key
}
kubeAPICrt , kubeAPIKey , err := GenerateSignedCertAndKey ( caCrt , caKey , true , KubeAPICertName , kubeAPIAltNames , serviceKey , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ KubeAPICertName ] = ToCertObject ( KubeAPICertName , "" , "" , kubeAPICrt , kubeAPIKey , nil )
2018-11-03 01:45:23 +00:00
// handle service account tokens in old clusters
apiCert := certs [ KubeAPICertName ]
if certs [ ServiceAccountTokenKeyName ] . Key == nil {
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Service account token key" )
2019-01-02 23:02:34 +00:00
certs [ ServiceAccountTokenKeyName ] = ToCertObject ( ServiceAccountTokenKeyName , ServiceAccountTokenKeyName , "" , apiCert . Certificate , apiCert . Key , nil )
2018-11-03 01:45:23 +00:00
}
2018-08-20 04:37:04 +00:00
return nil
}
2019-01-02 23:02:34 +00:00
func GenerateKubeAPICSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate API csr and key
kubernetesServiceIP , err := GetKubernetesServiceIP ( rkeConfig . Services . KubeAPI . ServiceClusterIPRange )
if err != nil {
return fmt . Errorf ( "Failed to get Kubernetes Service IP: %v" , err )
}
clusterDomain := rkeConfig . Services . Kubelet . ClusterDomain
cpHosts := hosts . NodesToHosts ( rkeConfig . Nodes , controlRole )
kubeAPIAltNames := GetAltNames ( cpHosts , clusterDomain , kubernetesServiceIP , rkeConfig . Authentication . SANs )
kubeAPICert := certs [ KubeAPICertName ] . Certificate
oldKubeAPICSR := certs [ KubeAPICertName ] . CSR
if oldKubeAPICSR != nil &&
reflect . DeepEqual ( kubeAPIAltNames . DNSNames , oldKubeAPICSR . DNSNames ) &&
2019-07-24 20:25:14 +00:00
DeepEqualIPsAltNames ( kubeAPIAltNames . IPs , oldKubeAPICSR . IPAddresses ) {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kubernetes API server csr" )
2019-01-02 23:02:34 +00:00
kubeAPICSR , kubeAPIKey , err := GenerateCertSigningRequestAndKey ( true , KubeAPICertName , kubeAPIAltNames , certs [ KubeAPICertName ] . Key , nil )
if err != nil {
return err
}
certs [ KubeAPICertName ] = ToCertObject ( KubeAPICertName , "" , "" , kubeAPICert , kubeAPIKey , kubeAPICSR )
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateKubeControllerCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate Kube controller-manager certificate and key
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2019-01-15 21:15:20 +00:00
if certs [ KubeControllerCertName ] . Certificate != nil && ! rotate {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Controller certificates" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeControllerCertName ] . Key
}
kubeControllerCrt , kubeControllerKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , getDefaultCN ( KubeControllerCertName ) , nil , serviceKey , nil )
2019-01-02 23:02:34 +00:00
if err != nil {
return err
}
certs [ KubeControllerCertName ] = ToCertObject ( KubeControllerCertName , "" , "" , kubeControllerCrt , kubeControllerKey , nil )
return nil
}
func GenerateKubeControllerCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate Kube controller-manager csr and key
kubeControllerCrt := certs [ KubeControllerCertName ] . Certificate
kubeControllerCSRPEM := certs [ KubeControllerCertName ] . CSRPEM
if kubeControllerCSRPEM != "" {
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Controller csr" )
2019-01-02 23:02:34 +00:00
kubeControllerCSR , kubeControllerKey , err := GenerateCertSigningRequestAndKey ( false , getDefaultCN ( KubeControllerCertName ) , nil , certs [ KubeControllerCertName ] . Key , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ KubeControllerCertName ] = ToCertObject ( KubeControllerCertName , "" , "" , kubeControllerCrt , kubeControllerKey , kubeControllerCSR )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateKubeSchedulerCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate Kube scheduler certificate and key
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2019-01-15 21:15:20 +00:00
if certs [ KubeSchedulerCertName ] . Certificate != nil && ! rotate {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Scheduler certificates" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeSchedulerCertName ] . Key
}
kubeSchedulerCrt , kubeSchedulerKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , getDefaultCN ( KubeSchedulerCertName ) , nil , serviceKey , nil )
2019-01-02 23:02:34 +00:00
if err != nil {
return err
}
certs [ KubeSchedulerCertName ] = ToCertObject ( KubeSchedulerCertName , "" , "" , kubeSchedulerCrt , kubeSchedulerKey , nil )
return nil
}
func GenerateKubeSchedulerCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate Kube scheduler csr and key
kubeSchedulerCrt := certs [ KubeSchedulerCertName ] . Certificate
kubeSchedulerCSRPEM := certs [ KubeSchedulerCertName ] . CSRPEM
if kubeSchedulerCSRPEM != "" {
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Scheduler csr" )
2019-01-02 23:02:34 +00:00
kubeSchedulerCSR , kubeSchedulerKey , err := GenerateCertSigningRequestAndKey ( false , getDefaultCN ( KubeSchedulerCertName ) , nil , certs [ KubeSchedulerCertName ] . Key , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ KubeSchedulerCertName ] = ToCertObject ( KubeSchedulerCertName , "" , "" , kubeSchedulerCrt , kubeSchedulerKey , kubeSchedulerCSR )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateKubeProxyCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate Kube Proxy certificate and key
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2019-01-15 21:15:20 +00:00
if certs [ KubeProxyCertName ] . Certificate != nil && ! rotate {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Proxy certificates" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeProxyCertName ] . Key
}
kubeProxyCrt , kubeProxyKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , getDefaultCN ( KubeProxyCertName ) , nil , serviceKey , nil )
2019-01-02 23:02:34 +00:00
if err != nil {
return err
}
certs [ KubeProxyCertName ] = ToCertObject ( KubeProxyCertName , "" , "" , kubeProxyCrt , kubeProxyKey , nil )
return nil
}
func GenerateKubeProxyCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate Kube Proxy csr and key
kubeProxyCrt := certs [ KubeProxyCertName ] . Certificate
kubeProxyCSRPEM := certs [ KubeProxyCertName ] . CSRPEM
if kubeProxyCSRPEM != "" {
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kube Proxy csr" )
2019-01-02 23:02:34 +00:00
kubeProxyCSR , kubeProxyKey , err := GenerateCertSigningRequestAndKey ( false , getDefaultCN ( KubeProxyCertName ) , nil , certs [ KubeProxyCertName ] . Key , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ KubeProxyCertName ] = ToCertObject ( KubeProxyCertName , "" , "" , kubeProxyCrt , kubeProxyKey , kubeProxyCSR )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateKubeNodeCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate kubelet certificate
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2019-01-15 21:15:20 +00:00
if certs [ KubeNodeCertName ] . Certificate != nil && ! rotate {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Node certificate" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeProxyCertName ] . Key
}
nodeCrt , nodeKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , KubeNodeCommonName , nil , serviceKey , [ ] string { KubeNodeOrganizationName } )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ KubeNodeCertName ] = ToCertObject ( KubeNodeCertName , KubeNodeCommonName , KubeNodeOrganizationName , nodeCrt , nodeKey , nil )
return nil
}
func GenerateKubeNodeCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate kubelet csr and key
nodeCrt := certs [ KubeNodeCertName ] . Certificate
nodeCSRPEM := certs [ KubeNodeCertName ] . CSRPEM
if nodeCSRPEM != "" {
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Node csr and key" )
2019-01-02 23:02:34 +00:00
nodeCSR , nodeKey , err := GenerateCertSigningRequestAndKey ( false , KubeNodeCommonName , nil , certs [ KubeNodeCertName ] . Key , [ ] string { KubeNodeOrganizationName } )
if err != nil {
return err
}
certs [ KubeNodeCertName ] = ToCertObject ( KubeNodeCertName , KubeNodeCommonName , KubeNodeOrganizationName , nodeCrt , nodeKey , nodeCSR )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateKubeAdminCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate Admin certificate and key
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating admin certificates and kubeconfig" )
2018-08-20 04:37:04 +00:00
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2018-08-20 04:37:04 +00:00
cpHosts := hosts . NodesToHosts ( rkeConfig . Nodes , controlRole )
if len ( configPath ) == 0 {
configPath = ClusterConfig
}
localKubeConfigPath := GetLocalKubeConfig ( configPath , configDir )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ KubeAdminCertName ] . Key
}
kubeAdminCrt , kubeAdminKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , KubeAdminCertName , nil , serviceKey , [ ] string { KubeAdminOrganizationName } )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
kubeAdminCertObj := ToCertObject ( KubeAdminCertName , KubeAdminCertName , KubeAdminOrganizationName , kubeAdminCrt , kubeAdminKey , nil )
2018-08-20 04:37:04 +00:00
if len ( cpHosts ) > 0 {
kubeAdminConfig := GetKubeConfigX509WithData (
"https://" + cpHosts [ 0 ] . Address + ":6443" ,
rkeConfig . ClusterName ,
KubeAdminCertName ,
string ( cert . EncodeCertPEM ( caCrt ) ) ,
string ( cert . EncodeCertPEM ( kubeAdminCrt ) ) ,
string ( cert . EncodePrivateKeyPEM ( kubeAdminKey ) ) )
kubeAdminCertObj . Config = kubeAdminConfig
kubeAdminCertObj . ConfigPath = localKubeConfigPath
} else {
kubeAdminCertObj . Config = ""
}
certs [ KubeAdminCertName ] = kubeAdminCertObj
return nil
}
2019-01-02 23:02:34 +00:00
func GenerateKubeAdminCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
// generate Admin certificate and key
kubeAdminCrt := certs [ KubeAdminCertName ] . Certificate
kubeAdminCSRPEM := certs [ KubeAdminCertName ] . CSRPEM
if kubeAdminCSRPEM != "" {
return nil
}
kubeAdminCSR , kubeAdminKey , err := GenerateCertSigningRequestAndKey ( false , KubeAdminCertName , nil , certs [ KubeAdminCertName ] . Key , [ ] string { KubeAdminOrganizationName } )
if err != nil {
return err
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating admin csr and kubeconfig" )
2019-01-02 23:02:34 +00:00
kubeAdminCertObj := ToCertObject ( KubeAdminCertName , KubeAdminCertName , KubeAdminOrganizationName , kubeAdminCrt , kubeAdminKey , kubeAdminCSR )
certs [ KubeAdminCertName ] = kubeAdminCertObj
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateAPIProxyClientCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
//generate API server proxy client key and certs
caCrt := certs [ RequestHeaderCACertName ] . Certificate
caKey := certs [ RequestHeaderCACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "Request Header CA Certificate or Key is empty" )
}
2019-01-15 21:15:20 +00:00
if certs [ APIProxyClientCertName ] . Certificate != nil && ! rotate {
2019-01-02 23:02:34 +00:00
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kubernetes API server proxy client certificates" )
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ APIProxyClientCertName ] . Key
}
apiserverProxyClientCrt , apiserverProxyClientKey , err := GenerateSignedCertAndKey ( caCrt , caKey , true , APIProxyClientCertName , nil , serviceKey , nil )
2019-01-02 23:02:34 +00:00
if err != nil {
return err
}
certs [ APIProxyClientCertName ] = ToCertObject ( APIProxyClientCertName , "" , "" , apiserverProxyClientCrt , apiserverProxyClientKey , nil )
return nil
}
func GenerateAPIProxyClientCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
//generate API server proxy client key and certs
apiserverProxyClientCrt := certs [ APIProxyClientCertName ] . Certificate
apiserverProxyClientCSRPEM := certs [ APIProxyClientCertName ] . CSRPEM
if apiserverProxyClientCSRPEM != "" {
return nil
}
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kubernetes API server proxy client csr" )
2019-01-02 23:02:34 +00:00
apiserverProxyClientCSR , apiserverProxyClientKey , err := GenerateCertSigningRequestAndKey ( true , APIProxyClientCertName , nil , certs [ APIProxyClientCertName ] . Key , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ APIProxyClientCertName ] = ToCertObject ( APIProxyClientCertName , "" , "" , apiserverProxyClientCrt , apiserverProxyClientKey , apiserverProxyClientCSR )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateExternalEtcdCertificates ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
clientCert , err := cert . ParseCertsPEM ( [ ] byte ( rkeConfig . Services . Etcd . Cert ) )
if err != nil {
return err
}
clientKey , err := cert . ParsePrivateKeyPEM ( [ ] byte ( rkeConfig . Services . Etcd . Key ) )
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ EtcdClientCertName ] = ToCertObject ( EtcdClientCertName , "" , "" , clientCert [ 0 ] , clientKey . ( * rsa . PrivateKey ) , nil )
2018-08-20 04:37:04 +00:00
caCert , err := cert . ParseCertsPEM ( [ ] byte ( rkeConfig . Services . Etcd . CACert ) )
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ EtcdClientCACertName ] = ToCertObject ( EtcdClientCACertName , "" , "" , caCert [ 0 ] , nil , nil )
2018-08-20 04:37:04 +00:00
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateEtcdCertificates ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2018-08-20 04:37:04 +00:00
kubernetesServiceIP , err := GetKubernetesServiceIP ( rkeConfig . Services . KubeAPI . ServiceClusterIPRange )
if err != nil {
return fmt . Errorf ( "Failed to get Kubernetes Service IP: %v" , err )
}
clusterDomain := rkeConfig . Services . Kubelet . ClusterDomain
etcdHosts := hosts . NodesToHosts ( rkeConfig . Nodes , etcdRole )
etcdAltNames := GetAltNames ( etcdHosts , clusterDomain , kubernetesServiceIP , [ ] string { } )
2019-05-23 17:57:35 +00:00
var (
dnsNames = make ( [ ] string , len ( etcdAltNames . DNSNames ) )
2019-05-29 21:55:48 +00:00
ips = [ ] string { }
2019-05-23 17:57:35 +00:00
)
copy ( dnsNames , etcdAltNames . DNSNames )
sort . Strings ( dnsNames )
for _ , ip := range etcdAltNames . IPs {
ips = append ( ips , ip . String ( ) )
}
sort . Strings ( ips )
2018-08-20 04:37:04 +00:00
for _ , host := range etcdHosts {
2019-07-24 20:25:14 +00:00
etcdName := GetCrtNameForHost ( host , EtcdCertName )
2019-03-20 03:34:24 +00:00
if _ , ok := certs [ etcdName ] ; ok && certs [ etcdName ] . CertificatePEM != "" && ! rotate {
2019-05-23 17:57:35 +00:00
cert := certs [ etcdName ] . Certificate
if cert != nil && len ( dnsNames ) == len ( cert . DNSNames ) && len ( ips ) == len ( cert . IPAddresses ) {
var (
certDNSNames = make ( [ ] string , len ( cert . DNSNames ) )
2019-05-29 21:55:48 +00:00
certIPs = [ ] string { }
2019-05-23 17:57:35 +00:00
)
copy ( certDNSNames , cert . DNSNames )
sort . Strings ( certDNSNames )
for _ , ip := range cert . IPAddresses {
certIPs = append ( certIPs , ip . String ( ) )
}
sort . Strings ( certIPs )
if reflect . DeepEqual ( dnsNames , certDNSNames ) && reflect . DeepEqual ( ips , certIPs ) {
continue
}
}
2018-11-03 01:45:23 +00:00
}
2019-01-15 21:15:20 +00:00
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ etcdName ] . Key
}
2020-03-08 09:07:56 +00:00
logrus . Infof ( "[certificates] Generating %s certificate and key" , etcdName )
2019-01-15 21:15:20 +00:00
etcdCrt , etcdKey , err := GenerateSignedCertAndKey ( caCrt , caKey , true , EtcdCertName , etcdAltNames , serviceKey , nil )
2019-01-02 23:02:34 +00:00
if err != nil {
return err
}
certs [ etcdName ] = ToCertObject ( etcdName , "" , "" , etcdCrt , etcdKey , nil )
}
2019-12-12 06:00:21 +00:00
deleteUnusedCerts ( ctx , certs , EtcdCertName , etcdHosts )
2019-01-02 23:02:34 +00:00
return nil
}
func GenerateEtcdCSRs ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
kubernetesServiceIP , err := GetKubernetesServiceIP ( rkeConfig . Services . KubeAPI . ServiceClusterIPRange )
if err != nil {
return fmt . Errorf ( "Failed to get Kubernetes Service IP: %v" , err )
}
clusterDomain := rkeConfig . Services . Kubelet . ClusterDomain
etcdHosts := hosts . NodesToHosts ( rkeConfig . Nodes , etcdRole )
etcdAltNames := GetAltNames ( etcdHosts , clusterDomain , kubernetesServiceIP , [ ] string { } )
for _ , host := range etcdHosts {
2019-07-24 20:25:14 +00:00
etcdName := GetCrtNameForHost ( host , EtcdCertName )
2019-01-02 23:02:34 +00:00
etcdCrt := certs [ etcdName ] . Certificate
2021-06-10 19:58:04 +00:00
etcdCsr := certs [ etcdName ] . CSR
if etcdCsr != nil {
if reflect . DeepEqual ( etcdAltNames . DNSNames , etcdCsr . DNSNames ) &&
DeepEqualIPsAltNames ( etcdAltNames . IPs , etcdCsr . IPAddresses ) {
continue
}
2019-01-02 23:02:34 +00:00
}
2020-03-08 09:07:56 +00:00
logrus . Infof ( "[certificates] Generating etcd-%s csr and key" , host . InternalAddress )
2019-01-02 23:02:34 +00:00
etcdCSR , etcdKey , err := GenerateCertSigningRequestAndKey ( true , EtcdCertName , etcdAltNames , certs [ etcdName ] . Key , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ etcdName ] = ToCertObject ( etcdName , "" , "" , etcdCrt , etcdKey , etcdCSR )
2018-08-20 04:37:04 +00:00
}
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateServiceTokenKey ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
// generate service account token key
2019-01-02 23:02:34 +00:00
privateAPIKey := certs [ ServiceAccountTokenKeyName ] . Key
2018-08-20 04:37:04 +00:00
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
2019-03-18 21:05:13 +00:00
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2019-01-02 23:02:34 +00:00
if certs [ ServiceAccountTokenKeyName ] . Certificate != nil {
return nil
}
2018-08-20 04:37:04 +00:00
// handle rotation on old clusters
if certs [ ServiceAccountTokenKeyName ] . Key == nil {
privateAPIKey = certs [ KubeAPICertName ] . Key
}
tokenCrt , tokenKey , err := GenerateSignedCertAndKey ( caCrt , caKey , false , ServiceAccountTokenKeyName , nil , privateAPIKey , nil )
if err != nil {
return fmt . Errorf ( "Failed to generate private key for service account token: %v" , err )
}
2019-01-02 23:02:34 +00:00
certs [ ServiceAccountTokenKeyName ] = ToCertObject ( ServiceAccountTokenKeyName , ServiceAccountTokenKeyName , "" , tokenCrt , tokenKey , nil )
2018-08-20 04:37:04 +00:00
return nil
}
func GenerateRKECACerts ( ctx context . Context , certs map [ string ] CertificatePKI , configPath , configDir string ) error {
2019-03-06 01:02:46 +00:00
if err := GenerateRKEMasterCACert ( ctx , certs , configPath , configDir ) ; err != nil {
return err
}
return GenerateRKERequestHeaderCACert ( ctx , certs , configPath , configDir )
}
func GenerateRKEMasterCACert ( ctx context . Context , certs map [ string ] CertificatePKI , configPath , configDir string ) error {
2018-08-20 04:37:04 +00:00
// generate kubernetes CA certificate and key
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating CA kubernetes certificates" )
2019-01-15 21:15:20 +00:00
caCrt , caKey , err := GenerateCACertAndKey ( CACertName , nil )
2018-08-20 04:37:04 +00:00
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ CACertName ] = ToCertObject ( CACertName , "" , "" , caCrt , caKey , nil )
2019-03-06 01:02:46 +00:00
return nil
}
2018-08-20 04:37:04 +00:00
2019-03-06 01:02:46 +00:00
func GenerateRKERequestHeaderCACert ( ctx context . Context , certs map [ string ] CertificatePKI , configPath , configDir string ) error {
2018-08-20 04:37:04 +00:00
// generate request header client CA certificate and key
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] Generating Kubernetes API server aggregation layer requestheader client CA certificates" )
2018-08-20 04:37:04 +00:00
requestHeaderCACrt , requestHeaderCAKey , err := GenerateCACertAndKey ( RequestHeaderCACertName , nil )
if err != nil {
return err
}
2019-01-02 23:02:34 +00:00
certs [ RequestHeaderCACertName ] = ToCertObject ( RequestHeaderCACertName , "" , "" , requestHeaderCACrt , requestHeaderCAKey , nil )
2018-08-20 04:37:04 +00:00
return nil
}
2019-07-24 20:25:14 +00:00
func GenerateKubeletCertificate ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
// generate kubelet certificate and key
caCrt := certs [ CACertName ] . Certificate
caKey := certs [ CACertName ] . Key
if caCrt == nil || caKey == nil {
return fmt . Errorf ( "CA Certificate or Key is empty" )
}
2020-01-16 00:29:25 +00:00
log . Debugf ( ctx , "[certificates] Generating Kubernetes Kubelet certificates" )
2019-07-24 20:25:14 +00:00
allHosts := hosts . NodesToHosts ( rkeConfig . Nodes , "" )
for _ , host := range allHosts {
kubeletName := GetCrtNameForHost ( host , KubeletCertName )
kubeletCert := certs [ kubeletName ] . Certificate
if kubeletCert != nil && ! rotate {
continue
}
kubeletAltNames := GetIPHostAltnamesForHost ( host )
if kubeletCert != nil &&
reflect . DeepEqual ( kubeletAltNames . DNSNames , kubeletCert . DNSNames ) &&
DeepEqualIPsAltNames ( kubeletAltNames . IPs , kubeletCert . IPAddresses ) && ! rotate {
continue
}
var serviceKey * rsa . PrivateKey
if ! rotate {
serviceKey = certs [ kubeletName ] . Key
}
2020-01-16 00:29:25 +00:00
log . Debugf ( ctx , "[certificates] Generating %s certificate and key" , kubeletName )
2019-07-24 20:25:14 +00:00
kubeletCrt , kubeletKey , err := GenerateSignedCertAndKey ( caCrt , caKey , true , kubeletName , kubeletAltNames , serviceKey , nil )
if err != nil {
return err
}
certs [ kubeletName ] = ToCertObject ( kubeletName , "" , "" , kubeletCrt , kubeletKey , nil )
}
2019-12-12 06:00:21 +00:00
deleteUnusedCerts ( ctx , certs , KubeletCertName , allHosts )
2019-07-24 20:25:14 +00:00
return nil
}
func GenerateKubeletCSR ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
allHosts := hosts . NodesToHosts ( rkeConfig . Nodes , "" )
for _ , host := range allHosts {
kubeletName := GetCrtNameForHost ( host , KubeletCertName )
kubeletCert := certs [ kubeletName ] . Certificate
oldKubeletCSR := certs [ kubeletName ] . CSR
kubeletAltNames := GetIPHostAltnamesForHost ( host )
if oldKubeletCSR != nil &&
reflect . DeepEqual ( kubeletAltNames . DNSNames , oldKubeletCSR . DNSNames ) &&
DeepEqualIPsAltNames ( kubeletAltNames . IPs , oldKubeletCSR . IPAddresses ) {
2021-06-10 19:58:04 +00:00
continue
2019-07-24 20:25:14 +00:00
}
2020-03-08 09:07:56 +00:00
logrus . Infof ( "[certificates] Generating %s Kubernetes Kubelet csr" , kubeletName )
2019-07-24 20:25:14 +00:00
kubeletCSR , kubeletKey , err := GenerateCertSigningRequestAndKey ( true , kubeletName , kubeletAltNames , certs [ kubeletName ] . Key , nil )
if err != nil {
return err
}
certs [ kubeletName ] = ToCertObject ( kubeletName , "" , "" , kubeletCert , kubeletKey , kubeletCSR )
}
return nil
}
2018-11-12 23:24:59 +00:00
func GenerateRKEServicesCerts ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig , configPath , configDir string , rotate bool ) error {
2018-08-20 04:37:04 +00:00
RKECerts := [ ] GenFunc {
GenerateKubeAPICertificate ,
GenerateServiceTokenKey ,
GenerateKubeControllerCertificate ,
GenerateKubeSchedulerCertificate ,
GenerateKubeProxyCertificate ,
GenerateKubeNodeCertificate ,
GenerateKubeAdminCertificate ,
GenerateAPIProxyClientCertificate ,
GenerateEtcdCertificates ,
}
2019-07-24 20:25:14 +00:00
if IsKubeletGenerateServingCertificateEnabledinConfig ( & rkeConfig ) {
RKECerts = append ( RKECerts , GenerateKubeletCertificate )
2019-12-12 06:00:21 +00:00
} else {
//Clean up kubelet certs when GenerateServingCertificate is disabled
2020-03-08 09:07:56 +00:00
logrus . Info ( "[certificates] GenerateServingCertificate is disabled, checking if there are unused kubelet certificates" )
2019-12-12 06:00:21 +00:00
for k := range certs {
if strings . HasPrefix ( k , KubeletCertName ) {
2020-03-08 09:07:56 +00:00
logrus . Infof ( "[certificates] Deleting unused kubelet certificate: %s" , k )
2019-12-12 06:00:21 +00:00
delete ( certs , k )
}
}
2019-07-24 20:25:14 +00:00
}
2018-08-20 04:37:04 +00:00
for _ , gen := range RKECerts {
2018-11-12 23:24:59 +00:00
if err := gen ( ctx , certs , rkeConfig , configPath , configDir , rotate ) ; err != nil {
2018-08-20 04:37:04 +00:00
return err
}
}
if len ( rkeConfig . Services . Etcd . ExternalURLs ) > 0 {
2018-11-12 23:24:59 +00:00
return GenerateExternalEtcdCertificates ( ctx , certs , rkeConfig , configPath , configDir , false )
2018-08-20 04:37:04 +00:00
}
return nil
}
2019-01-02 23:02:34 +00:00
func GenerateRKEServicesCSRs ( ctx context . Context , certs map [ string ] CertificatePKI , rkeConfig v3 . RancherKubernetesEngineConfig ) error {
RKECerts := [ ] CSRFunc {
GenerateKubeAPICSR ,
GenerateKubeControllerCSR ,
GenerateKubeSchedulerCSR ,
GenerateKubeProxyCSR ,
GenerateKubeNodeCSR ,
GenerateKubeAdminCSR ,
GenerateAPIProxyClientCSR ,
GenerateEtcdCSRs ,
}
2019-07-24 20:25:14 +00:00
if IsKubeletGenerateServingCertificateEnabledinConfig ( & rkeConfig ) {
RKECerts = append ( RKECerts , GenerateKubeletCSR )
}
2019-01-02 23:02:34 +00:00
for _ , csr := range RKECerts {
if err := csr ( ctx , certs , rkeConfig ) ; err != nil {
return err
}
}
return nil
}
2019-12-12 06:00:21 +00:00
2020-03-08 09:07:56 +00:00
func deleteUnusedCerts ( ctx context . Context , certs map [ string ] CertificatePKI , certName string , hostList [ ] * hosts . Host ) {
hostAddresses := hosts . GetInternalAddressForHosts ( hostList )
logrus . Tracef ( "Checking and deleting unused certificates with prefix [%s] for the following [%d] node(s): %s" , certName , len ( hostAddresses ) , strings . Join ( hostAddresses , "," ) )
2019-12-12 06:00:21 +00:00
unusedCerts := make ( map [ string ] bool )
for k := range certs {
if strings . HasPrefix ( k , certName ) {
unusedCerts [ k ] = true
}
}
2020-03-08 09:07:56 +00:00
for _ , host := range hostList {
2019-12-12 06:00:21 +00:00
Name := GetCrtNameForHost ( host , certName )
delete ( unusedCerts , Name )
}
for k := range unusedCerts {
2020-03-08 09:07:56 +00:00
logrus . Infof ( "[certificates] Deleting unused certificate: %s" , k )
2019-12-12 06:00:21 +00:00
delete ( certs , k )
}
}