// MaybeGenerateServingCerts generates serving certificates if requested and needed. func (c *Config) MaybeGenerateServingCerts(alternateIPs ...net.IP) error { // It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless // alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME") if c.SecureServingInfo != nil && c.SecureServingInfo.ServerCert.Generate { canReadCertAndKey, err := certutil.CanReadCertAndKey(c.SecureServingInfo.ServerCert.CertFile, c.SecureServingInfo.ServerCert.KeyFile) if err != nil { return err } if canReadCertAndKey { return nil } // TODO (cjcullen): Is ClusterIP the right address to sign a cert with? alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"} if cert, key, err := certutil.GenerateSelfSignedCertKey(c.PublicAddress.String(), alternateIPs, alternateDNS); err != nil { return fmt.Errorf("unable to generate self signed cert: %v", err) } else { if err := certutil.WriteCert(c.SecureServingInfo.ServerCert.CertFile, cert); err != nil { return err } if err := certutil.WriteKey(c.SecureServingInfo.ServerCert.KeyFile, key); err != nil { return err } glog.Infof("Generated self-signed cert (%s, %s)", c.SecureServingInfo.ServerCert.CertFile, c.SecureServingInfo.ServerCert.KeyFile) } } return nil }
// InitializeTLS checks for a configured TLSCertFile and TLSPrivateKeyFile: if unspecified a new self-signed // certificate and key file are generated. Returns a configured server.TLSOptions object. func InitializeTLS(kc *componentconfig.KubeletConfiguration) (*server.TLSOptions, error) { if kc.TLSCertFile == "" && kc.TLSPrivateKeyFile == "" { kc.TLSCertFile = path.Join(kc.CertDirectory, "kubelet.crt") kc.TLSPrivateKeyFile = path.Join(kc.CertDirectory, "kubelet.key") canReadCertAndKey, err := certutil.CanReadCertAndKey(kc.TLSCertFile, kc.TLSPrivateKeyFile) if err != nil { return nil, err } if !canReadCertAndKey { cert, key, err := certutil.GenerateSelfSignedCertKey(nodeutil.GetHostname(kc.HostnameOverride), nil, nil) if err != nil { return nil, fmt.Errorf("unable to generate self signed cert: %v", err) } if err := certutil.WriteCert(kc.TLSCertFile, cert); err != nil { return nil, err } if err := certutil.WriteKey(kc.TLSPrivateKeyFile, key); err != nil { return nil, err } glog.V(4).Infof("Using self-signed cert (%s, %s)", kc.TLSCertFile, kc.TLSPrivateKeyFile) } } tlsOptions := &server.TLSOptions{ Config: &tls.Config{ // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, }, CertFile: kc.TLSCertFile, KeyFile: kc.TLSPrivateKeyFile, } if len(kc.Authentication.X509.ClientCAFile) > 0 { clientCAs, err := cert.NewPool(kc.Authentication.X509.ClientCAFile) if err != nil { return nil, fmt.Errorf("unable to load client CA file %s: %v", kc.Authentication.X509.ClientCAFile, err) } // Specify allowed CAs for client certificates tlsOptions.Config.ClientCAs = clientCAs // Populate PeerCertificates in requests, but don't reject connections without verified certificates tlsOptions.Config.ClientAuth = tls.RequestClientCert } return tlsOptions, nil }
func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress string, alternateIPs ...net.IP) error { if s == nil { return nil } keyCert := &s.ServerCert.CertKey if s.ServingOptions.BindPort == 0 || len(keyCert.CertFile) != 0 || len(keyCert.KeyFile) != 0 { return nil } keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt") keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key") canReadCertAndKey, err := certutil.CanReadCertAndKey(keyCert.CertFile, keyCert.KeyFile) if err != nil { return err } if !canReadCertAndKey { // TODO: It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless // alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME") // TODO (cjcullen): Is ClusterIP the right address to sign a cert with? alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes"} // add either the bind address or localhost to the valid alternates bindIP := s.ServingOptions.BindAddress.String() if bindIP == "0.0.0.0" { alternateDNS = append(alternateDNS, "localhost") } else { alternateIPs = append(alternateIPs, s.ServingOptions.BindAddress) } if cert, key, err := certutil.GenerateSelfSignedCertKey(publicAddress, alternateIPs, alternateDNS); err != nil { return fmt.Errorf("unable to generate self signed cert: %v", err) } else { if err := certutil.WriteCert(keyCert.CertFile, cert); err != nil { return err } if err := certutil.WriteKey(keyCert.KeyFile, key); err != nil { return err } glog.Infof("Generated self-signed cert (%s, %s)", keyCert.CertFile, keyCert.KeyFile) } } return nil }