github.com/kubernetes-incubator/kube-aws@v0.16.4/credential/generator.go (about) 1 package credential 2 3 import ( 4 "crypto/rsa" 5 "crypto/x509" 6 "fmt" 7 "io/ioutil" 8 "net" 9 "time" 10 11 "github.com/kubernetes-incubator/kube-aws/logger" 12 "github.com/kubernetes-incubator/kube-aws/netutil" 13 "github.com/kubernetes-incubator/kube-aws/pki" 14 ) 15 16 type Generator struct { 17 TLSCADurationDays int 18 TLSCertDurationDays int 19 TLSBootstrapEnabled bool 20 ManageCertificates bool 21 Region string 22 APIServerExternalDNSNames []string 23 APIServerAdditionalDNSSans []string 24 APIServerAdditionalIPAddressSans []string 25 EtcdNodeDNSNames []string 26 ServiceCIDR string 27 } 28 29 type GeneratorOptions struct { 30 AwsDebug bool 31 GenerateCA bool 32 CaCertPath string 33 CommonName string 34 // Paths for private certificate keys. 35 AdminKeyPath string 36 ApiServerAggregatorKeyPath string 37 ApiServerKeyPath string 38 CaKeyPath string 39 EtcdClientKeyPath string 40 EtcdKeyPath string 41 KubeControllerManagerKeyPath string 42 KubeSchedulerKeyPath string 43 ServiceAccountKeyPath string 44 WorkerKeyPath string 45 } 46 47 func (c Generator) GenerateAssetsOnDisk(dir string, o GeneratorOptions) (*RawAssetsOnDisk, error) { 48 logger.Info("Generating credentials...") 49 var caKey *rsa.PrivateKey 50 var caCert *x509.Certificate 51 if o.GenerateCA { 52 var err error 53 caKey, caCert, err = pki.NewCA(c.TLSCADurationDays, o.CommonName) 54 if err != nil { 55 return nil, fmt.Errorf("failed generating cluster CA: %v", err) 56 } 57 logger.Info("-> Generating new TLS CA\n") 58 } else { 59 logger.Info("-> Parsing existing TLS CA\n") 60 if caKeyBytes, err := ioutil.ReadFile(o.CaKeyPath); err != nil { 61 return nil, fmt.Errorf("failed reading ca key file %s : %v", o.CaKeyPath, err) 62 } else { 63 if caKey, err = pki.DecodePrivateKeyPEM(caKeyBytes); err != nil { 64 return nil, fmt.Errorf("failed parsing ca key: %v", err) 65 } 66 } 67 if caCertBytes, err := ioutil.ReadFile(o.CaCertPath); err != nil { 68 return nil, fmt.Errorf("failed reading ca cert file %s : %v", o.CaCertPath, err) 69 } else { 70 if caCert, err = pki.DecodeCertificatePEM(caCertBytes); err != nil { 71 return nil, fmt.Errorf("failed parsing ca cert: %v", err) 72 } 73 } 74 } 75 76 logger.Info("-> Generating new assets") 77 assets, err := c.GenerateAssetsOnMemory(caKey, caCert, o) 78 if err != nil { 79 return nil, fmt.Errorf("Error generating default assets: %v", err) 80 } 81 82 logger.Infof("--> Summarizing the configuration\n TLS certificates managed by kube-aws=%v, CA key required on controller nodes=%v\n", c.ManageCertificates, true) 83 84 logger.Info("--> Writing to the storage") 85 alsoWriteCAKey := o.GenerateCA || c.ManageCertificates 86 if err := assets.WriteToDir(dir, alsoWriteCAKey); err != nil { 87 return nil, fmt.Errorf("Error creating assets: %v", err) 88 } 89 90 { 91 logger.Info("--> Verifying the result") 92 verified, err := ReadRawAssets(dir, c.ManageCertificates, c.ManageCertificates) 93 94 if err != nil { 95 return nil, fmt.Errorf("failed verifying the result: %v", err) 96 } 97 98 return verified, nil 99 } 100 } 101 102 func getOrCreatePrivateKey(keyPath string) (*rsa.PrivateKey, error) { 103 if keyPath != "" { 104 keyBytes, err := ioutil.ReadFile(keyPath) 105 if err != nil { 106 return nil, fmt.Errorf("failed reading key file %s : %v", keyPath, err) 107 } 108 109 key, err := pki.DecodePrivateKeyPEM(keyBytes) 110 if err != nil { 111 return nil, fmt.Errorf("failed parsing key: %v", err) 112 } 113 return key, nil 114 } 115 return pki.NewPrivateKey() 116 } 117 118 func (c Generator) GenerateAssetsOnMemory(caKey *rsa.PrivateKey, caCert *x509.Certificate, generatorOptions GeneratorOptions) (*RawAssetsOnMemory, error) { 119 // Convert from days to time.Duration 120 certDuration := time.Duration(c.TLSCertDurationDays) * 24 * time.Hour 121 122 // Generate keys for the various components. 123 privateKeys := map[string]*rsa.PrivateKey{ 124 generatorOptions.ApiServerKeyPath: nil, 125 generatorOptions.KubeControllerManagerKeyPath: nil, 126 generatorOptions.KubeSchedulerKeyPath: nil, 127 generatorOptions.WorkerKeyPath: nil, 128 generatorOptions.AdminKeyPath: nil, 129 generatorOptions.EtcdKeyPath: nil, 130 generatorOptions.EtcdClientKeyPath: nil, 131 generatorOptions.ServiceAccountKeyPath: nil, 132 generatorOptions.ApiServerAggregatorKeyPath: nil, 133 } 134 135 for key := range privateKeys { 136 var err error 137 if privateKeys[key], err = getOrCreatePrivateKey(key); err != nil { 138 return nil, err 139 } 140 } 141 142 // Compute kubernetesServiceIP from serviceCIDR 143 _, serviceNet, err := net.ParseCIDR(c.ServiceCIDR) 144 if err != nil { 145 return nil, fmt.Errorf("invalid serviceCIDR: %v", err) 146 } 147 kubernetesServiceIPAddr := netutil.IncrementIP(serviceNet.IP) 148 149 dnsNames := append( 150 []string{ 151 "kubernetes", 152 "kubernetes.default", 153 "kubernetes.default.svc", 154 "kubernetes.default.svc.cluster.local", 155 }, c.APIServerExternalDNSNames...) 156 157 // 127.0.0.1 also allows control plane components to reach the apiserver via HTTPS at localhost 158 ipAddresses := []string{kubernetesServiceIPAddr.String(), "127.0.0.1"} 159 160 apiServerConfig := pki.ServerCertConfig{ 161 CommonName: "kube-apiserver", 162 DNSNames: append(dnsNames, c.APIServerExternalDNSNames...), 163 IPAddresses: append(ipAddresses, c.APIServerAdditionalIPAddressSans...), 164 Duration: certDuration, 165 } 166 apiServerCert, err := pki.NewSignedServerCertificate(apiServerConfig, privateKeys[generatorOptions.ApiServerKeyPath], caCert, caKey) 167 if err != nil { 168 return nil, err 169 } 170 171 etcdConfig := pki.ServerCertConfig{ 172 CommonName: "kube-etcd", 173 DNSNames: c.EtcdNodeDNSNames, 174 // etcd https client/peer interfaces are not exposed externally 175 // but anyway we'll make it valid for the same duration as other certs just because it is easy to implement. 176 Duration: certDuration, 177 } 178 179 etcdCert, err := pki.NewSignedServerCertificate(etcdConfig, privateKeys[generatorOptions.EtcdKeyPath], caCert, caKey) 180 if err != nil { 181 return nil, err 182 } 183 184 workerConfig := pki.ClientCertConfig{ 185 CommonName: "kube-worker", 186 DNSNames: []string{ 187 fmt.Sprintf("*.%s.compute.internal", c.Region), 188 "*.ec2.internal", 189 }, 190 Duration: certDuration, 191 } 192 workerCert, err := pki.NewSignedClientCertificate(workerConfig, privateKeys[generatorOptions.WorkerKeyPath], caCert, caKey) 193 if err != nil { 194 return nil, err 195 } 196 197 etcdClientConfig := pki.ClientCertConfig{ 198 CommonName: "kube-etcd-client", 199 Duration: certDuration, 200 } 201 202 etcdClientCert, err := pki.NewSignedClientCertificate(etcdClientConfig, privateKeys[generatorOptions.EtcdClientKeyPath], caCert, caKey) 203 if err != nil { 204 return nil, err 205 } 206 207 adminConfig := pki.ClientCertConfig{ 208 CommonName: "kube-admin", 209 Organization: []string{"system:masters"}, 210 Duration: certDuration, 211 } 212 adminCert, err := pki.NewSignedClientCertificate(adminConfig, privateKeys[generatorOptions.AdminKeyPath], caCert, caKey) 213 if err != nil { 214 return nil, err 215 } 216 217 kubeControllerManagerConfig := pki.ClientCertConfig{ 218 CommonName: "system:kube-controller-manager", 219 Duration: certDuration, 220 } 221 kubeControllerManagerCert, err := pki.NewSignedClientCertificate(kubeControllerManagerConfig, privateKeys[generatorOptions.KubeControllerManagerKeyPath], caCert, caKey) 222 if err != nil { 223 return nil, err 224 } 225 226 kubeSchedulerConfig := pki.ClientCertConfig{ 227 CommonName: "system:kube-scheduler", 228 Duration: certDuration, 229 } 230 kubeSchedulerCert, err := pki.NewSignedClientCertificate(kubeSchedulerConfig, privateKeys[generatorOptions.KubeSchedulerKeyPath], caCert, caKey) 231 if err != nil { 232 return nil, err 233 } 234 235 apiServerAggregatorConfig := pki.ClientCertConfig{ 236 CommonName: "aggregator", 237 Duration: certDuration, 238 } 239 apiServerAggregatorCert, err := pki.NewSignedClientCertificate(apiServerAggregatorConfig, privateKeys[generatorOptions.ApiServerAggregatorKeyPath], caCert, caKey) 240 if err != nil { 241 return nil, err 242 } 243 244 authTokens := "" 245 tlsBootstrapToken, err := RandomTokenString() 246 if err != nil { 247 return nil, err 248 } 249 250 encryptionConfig, err := EncryptionConfig() 251 if err != nil { 252 return nil, err 253 } 254 255 r := &RawAssetsOnMemory{ 256 CACert: pki.EncodeCertificatePEM(caCert), 257 APIServerCert: pki.EncodeCertificatePEM(apiServerCert), 258 KubeControllerManagerCert: pki.EncodeCertificatePEM(kubeControllerManagerCert), 259 KubeSchedulerCert: pki.EncodeCertificatePEM(kubeSchedulerCert), 260 WorkerCert: pki.EncodeCertificatePEM(workerCert), 261 AdminCert: pki.EncodeCertificatePEM(adminCert), 262 EtcdCert: pki.EncodeCertificatePEM(etcdCert), 263 EtcdClientCert: pki.EncodeCertificatePEM(etcdClientCert), 264 APIServerAggregatorCert: pki.EncodeCertificatePEM(apiServerAggregatorCert), 265 CAKey: pki.EncodePrivateKeyPEM(caKey), 266 APIServerKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.ApiServerKeyPath]), 267 KubeControllerManagerKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.KubeControllerManagerKeyPath]), 268 KubeSchedulerKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.KubeSchedulerKeyPath]), 269 WorkerKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.WorkerKeyPath]), 270 AdminKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.AdminKeyPath]), 271 EtcdKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.EtcdKeyPath]), 272 EtcdClientKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.EtcdClientKeyPath]), 273 ServiceAccountKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.ServiceAccountKeyPath]), 274 APIServerAggregatorKey: pki.EncodePrivateKeyPEM(privateKeys[generatorOptions.ApiServerAggregatorKeyPath]), 275 276 AuthTokens: []byte(authTokens), 277 TLSBootstrapToken: []byte(tlsBootstrapToken), 278 EncryptionConfig: []byte(encryptionConfig), 279 } 280 281 return r, nil 282 }