diff --git a/pkg/localkube/apiserver.go b/pkg/localkube/apiserver.go index b8b1f9fa81..a563d371bb 100644 --- a/pkg/localkube/apiserver.go +++ b/pkg/localkube/apiserver.go @@ -77,6 +77,19 @@ func StartAPIServer(lk LocalkubeServer) func() error { RuntimeConfig: lk.RuntimeConfig, } + config.ProxyClientCertFile = lk.GetProxyClientPublicKeyCertPath() + config.ProxyClientKeyFile = lk.GetProxyClientPrivateKeyCertPath() + config.Authentication.RequestHeader.AllowedNames = + []string{} + config.Authentication.RequestHeader.UsernameHeaders = + []string{"X-Remote-User"} + config.Authentication.RequestHeader.GroupHeaders = + []string{"X-Remote-Group"} + config.Authentication.RequestHeader.ExtraHeaderPrefixes = + []string{"X-Remote-Extra-"} + config.Authentication.RequestHeader.ClientCAFile = + lk.GetProxyClientCAPublicKeyCertPath() + lk.SetExtraConfigForComponent("apiserver", &config) return func() error { diff --git a/pkg/localkube/localkube.go b/pkg/localkube/localkube.go index 03d464f4d8..aa1da9154f 100644 --- a/pkg/localkube/localkube.go +++ b/pkg/localkube/localkube.go @@ -90,6 +90,19 @@ func (lk LocalkubeServer) GetCAPublicKeyCertPath() string { return path.Join(lk.GetCertificateDirectory(), "ca.crt") } +func (lk LocalkubeServer) GetProxyClientPrivateKeyCertPath() string { + return path.Join(lk.GetCertificateDirectory(), "proxy-client.key") +} +func (lk LocalkubeServer) GetProxyClientPublicKeyCertPath() string { + return path.Join(lk.GetCertificateDirectory(), "proxy-client.crt") +} +func (lk LocalkubeServer) GetProxyClientCAPublicKeyCertPath() string { + return path.Join(lk.GetCertificateDirectory(), "proxy-client-ca.crt") +} +func (lk LocalkubeServer) GetProxyClientCAPrivateKeyCertPath() string { + return path.Join(lk.GetCertificateDirectory(), "proxy-client-ca.key") +} + func (lk LocalkubeServer) GetAPIServerSecureURL() string { return fmt.Sprintf("https://%s:%d", lk.APIServerAddress.String(), lk.APIServerPort) } @@ -198,11 +211,26 @@ func (lk LocalkubeServer) getAllIPs() ([]net.IP, error) { func (lk LocalkubeServer) GenerateCerts() error { if !lk.shouldGenerateCACerts() { - fmt.Println("Using these existing CA certs: ", lk.GetCAPublicKeyCertPath(), lk.GetCAPrivateKeyCertPath()) + fmt.Println( + "Using these existing CA certs: ", lk.GetCAPublicKeyCertPath(), + lk.GetCAPrivateKeyCertPath(), lk.GetProxyClientCAPublicKeyCertPath(), + lk.GetProxyClientCAPrivateKeyCertPath(), + ) } else { fmt.Println("Creating CA cert") - if err := util.GenerateCACert(lk.GetCAPublicKeyCertPath(), lk.GetCAPrivateKeyCertPath(), lk.APIServerName); err != nil { - fmt.Println("Failed to create CA certs: ", err) + if err := util.GenerateCACert( + lk.GetCAPublicKeyCertPath(), lk.GetCAPrivateKeyCertPath(), + lk.APIServerName, + ); err != nil { + fmt.Println("Failed to create CA cert: ", err) + return err + } + fmt.Println("Creating proxy client CA cert") + if err := util.GenerateCACert( + lk.GetProxyClientCAPublicKeyCertPath(), + lk.GetProxyClientCAPrivateKeyCertPath(), "proxyClientCA", + ); err != nil { + fmt.Println("Failed to create proxy client CA cert: ", err) return err } } @@ -213,13 +241,31 @@ func (lk LocalkubeServer) GenerateCerts() error { } if !lk.shouldGenerateCerts(ips) { - fmt.Println("Using these existing certs: ", lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath()) + fmt.Println( + "Using these existing certs: ", lk.GetPublicKeyCertPath(), + lk.GetPrivateKeyCertPath(), lk.GetProxyClientPublicKeyCertPath(), + lk.GetProxyClientPrivateKeyCertPath(), + ) return nil } fmt.Println("Creating cert with IPs: ", ips) - if err := util.GenerateSignedCert(lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath(), ips, util.GetAlternateDNS(lk.DNSDomain), lk.GetCAPublicKeyCertPath(), lk.GetCAPrivateKeyCertPath()); err != nil { - fmt.Println("Failed to create certs: ", err) + if err := util.GenerateSignedCert( + lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath(), "minikube", ips, + util.GetAlternateDNS(lk.DNSDomain), lk.GetCAPublicKeyCertPath(), + lk.GetCAPrivateKeyCertPath(), + ); err != nil { + fmt.Println("Failed to create cert: ", err) + return err + } + + if err := util.GenerateSignedCert( + lk.GetProxyClientPublicKeyCertPath(), lk.GetProxyClientPrivateKeyCertPath(), + "aggregator", []net.IP{}, []string{}, + lk.GetProxyClientCAPublicKeyCertPath(), + lk.GetProxyClientCAPrivateKeyCertPath(), + ); err != nil { + fmt.Println("Failed to create proxy client cert: ", err) return err } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index ac09a75388..edd442227b 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -33,7 +33,10 @@ import ( ) var ( - certs = []string{"ca.crt", "ca.key", "apiserver.crt", "apiserver.key"} + certs = []string{ + "ca.crt", "ca.key", "apiserver.crt", "apiserver.key", "proxy-client-ca.crt", + "proxy-client-ca.key", "proxy-client.crt", "proxy-client.key", + } // This is the internalIP , the API server and other components communicate on. internalIP = net.ParseIP(util.DefaultServiceClusterIP) ) @@ -48,7 +51,17 @@ func SetupCerts(cmd CommandRunner, k8s KubernetesConfig) error { caKey := filepath.Join(localPath, "ca.key") publicPath := filepath.Join(localPath, "apiserver.crt") privatePath := filepath.Join(localPath, "apiserver.key") - if err := generateCerts(caCert, caKey, publicPath, privatePath, ip, k8s.APIServerName, k8s.DNSDomain); err != nil { + + proxyClientCACert := filepath.Join(localPath, "proxy-client-ca.crt") + proxyClientCAKey := filepath.Join(localPath, "proxy-client-ca.key") + proxyClientPublicPath := filepath.Join(localPath, "proxy-client.crt") + proxyClientPrivatePath := filepath.Join(localPath, "proxy-client.key") + + if err := generateCerts( + caCert, caKey, publicPath, privatePath, ip, k8s.APIServerName, + k8s.DNSDomain, proxyClientCACert, proxyClientCAKey, proxyClientPublicPath, + proxyClientPrivatePath, + ); err != nil { return errors.Wrap(err, "Error generating certs") } @@ -95,16 +108,38 @@ func SetupCerts(cmd CommandRunner, k8s KubernetesConfig) error { return nil } -func generateCerts(caCert, caKey, pub, priv string, ip net.IP, name string, dnsDomain string) error { +func generateCerts( + caCert, caKey, pub, priv string, ip net.IP, name, dnsDomain string, + proxyCACert, proxyCAKey, proxyPub, proxyPriv string, +) error { if !(util.CanReadFile(caCert) && util.CanReadFile(caKey)) { if err := util.GenerateCACert(caCert, caKey, name); err != nil { - return errors.Wrap(err, "Error generating certificate") + return errors.Wrap(err, "Error generating CA certificate") } } ips := []net.IP{ip, internalIP} - if err := util.GenerateSignedCert(pub, priv, ips, util.GetAlternateDNS(dnsDomain), caCert, caKey); err != nil { + if err := util.GenerateSignedCert( + pub, priv, "minikube", ips, util.GetAlternateDNS(dnsDomain), + caCert, caKey, + ); err != nil { return errors.Wrap(err, "Error generating signed cert") } + + if !(util.CanReadFile(proxyCACert) && util.CanReadFile(proxyCAKey)) { + if err := util.GenerateCACert( + proxyCACert, proxyCAKey, "proxyClientCA", + ); err != nil { + return errors.Wrap(err, "Error generating proxy client CA certificate") + } + } + + if err := util.GenerateSignedCert( + proxyPub, proxyPriv, "aggregator", []net.IP{}, []string{}, + proxyCACert, proxyCAKey, + ); err != nil { + return errors.Wrap(err, "Error generating signed proxy client cert") + } + return nil } diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 04d99293ad..4db85f7d9a 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -45,10 +45,6 @@ import ( "k8s.io/minikube/pkg/util" ) -var ( - certs = []string{"ca.crt", "ca.key", "apiserver.crt", "apiserver.key"} -) - const fileScheme = "file" //This init function is used to set the logtostderr variable to false so that INFO level log info does not clutter the CLI diff --git a/pkg/util/crypto.go b/pkg/util/crypto.go index 90b21f6779..d987f3fafa 100644 --- a/pkg/util/crypto.go +++ b/pkg/util/crypto.go @@ -60,7 +60,7 @@ func GenerateCACert(certPath, keyPath string, name string) error { // The certificate will be created with file mode 0644. The key will be created with file mode 0600. // If the certificate or key files already exist, they will be overwritten. // Any parent directories of the certPath or keyPath will be created as needed with file mode 0755. -func GenerateSignedCert(certPath, keyPath string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error { +func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error { signerCertBytes, err := ioutil.ReadFile(signerCertPath) if err != nil { return errors.Wrap(err, "Error reading file: signerCertPath") @@ -89,7 +89,7 @@ func GenerateSignedCert(certPath, keyPath string, ips []net.IP, alternateDNS []s template := x509.Certificate{ SerialNumber: big.NewInt(2), Subject: pkix.Name{ - CommonName: "minikube", + CommonName: cn, Organization: []string{"system:masters"}, }, NotBefore: time.Now(), diff --git a/pkg/util/crypto_test.go b/pkg/util/crypto_test.go index 7aec649212..bbce6bcb6f 100644 --- a/pkg/util/crypto_test.go +++ b/pkg/util/crypto_test.go @@ -123,7 +123,10 @@ func TestGenerateSignedCert(t *testing.T) { for _, test := range tests { test := test t.Run(test.description, func(t *testing.T) { - err := GenerateSignedCert(certPath, keyPath, ips, alternateDNS, test.signerCertPath, test.signerKeyPath) + err := GenerateSignedCert( + certPath, keyPath, "minikube", ips, alternateDNS, test.signerCertPath, + test.signerKeyPath, + ) if err != nil && !test.err { t.Errorf("GenerateSignedCert() error = %v", err) }