提交 617e969a 编写于 作者: H hongming

fix: private key not match public key

Signed-off-by: Nhongming <talonwan@yunify.com>
上级 1cb1eb4f
...@@ -220,6 +220,7 @@ func (c *Controller) reconcile(key string) error { ...@@ -220,6 +220,7 @@ func (c *Controller) reconcile(key string) error {
if len(csr.Status.Certificate) > 0 { if len(csr.Status.Certificate) > 0 {
err = c.UpdateKubeconfig(csr) err = c.UpdateKubeconfig(csr)
if err != nil { if err != nil {
// kubeconfig not generated
klog.Error(err) klog.Error(err)
return err return err
} }
...@@ -258,7 +259,6 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest) ...@@ -258,7 +259,6 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest)
// approve csr // approve csr
csr, err := c.k8sclient.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(csr) csr, err := c.k8sclient.CertificatesV1beta1().CertificateSigningRequests().UpdateApproval(csr)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return err return err
...@@ -269,12 +269,9 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest) ...@@ -269,12 +269,9 @@ func (c *Controller) Approve(csr *certificatesv1beta1.CertificateSigningRequest)
func (c *Controller) UpdateKubeconfig(csr *certificatesv1beta1.CertificateSigningRequest) error { func (c *Controller) UpdateKubeconfig(csr *certificatesv1beta1.CertificateSigningRequest) error {
username := csr.Labels[constants.UsernameLabelKey] username := csr.Labels[constants.UsernameLabelKey]
err := c.kubeconfigOperator.UpdateKubeconfig(username, csr)
err := c.kubeconfigOperator.UpdateKubeconfig(username, csr.Status.Certificate)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
} }
return err return err
} }
...@@ -44,7 +44,7 @@ import ( ...@@ -44,7 +44,7 @@ import (
) )
const ( const (
inClusterCAFilePath = "/run/secrets/kubernetes.io/serviceaccount/ca.crt" inClusterCAFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
configMapPrefix = "kubeconfig-" configMapPrefix = "kubeconfig-"
kubeconfigNameFormat = configMapPrefix + "%s" kubeconfigNameFormat = configMapPrefix + "%s"
defaultClusterName = "local" defaultClusterName = "local"
...@@ -52,12 +52,13 @@ const ( ...@@ -52,12 +52,13 @@ const (
kubeconfigFileName = "config" kubeconfigFileName = "config"
configMapKind = "ConfigMap" configMapKind = "ConfigMap"
configMapAPIVersion = "v1" configMapAPIVersion = "v1"
privateKeyAnnotation = "kubesphere.io/private-key"
) )
type Interface interface { type Interface interface {
GetKubeConfig(username string) (string, error) GetKubeConfig(username string) (string, error)
CreateKubeConfig(user *iamv1alpha2.User) error CreateKubeConfig(user *iamv1alpha2.User) error
UpdateKubeconfig(username string, certificate []byte) error UpdateKubeconfig(username string, csr *certificatesv1beta1.CertificateSigningRequest) error
} }
type operator struct { type operator struct {
...@@ -76,11 +77,8 @@ func NewReadOnlyOperator(configMapInformer corev1informers.ConfigMapInformer, ma ...@@ -76,11 +77,8 @@ func NewReadOnlyOperator(configMapInformer corev1informers.ConfigMapInformer, ma
} }
func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error { func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
configName := fmt.Sprintf(kubeconfigNameFormat, user.Name) configName := fmt.Sprintf(kubeconfigNameFormat, user.Name)
_, err := o.configMapInformer.Lister().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName) _, err := o.configMapInformer.Lister().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName)
// already exist // already exist
if err == nil { if err == nil {
return nil return nil
...@@ -104,15 +102,12 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error { ...@@ -104,15 +102,12 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
} }
} }
clientKey, err := o.createCSR(user.Name) if err = o.createCSR(user.Name); err != nil {
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return err return err
} }
currentContext := fmt.Sprintf("%s@%s", user.Name, defaultClusterName) currentContext := fmt.Sprintf("%s@%s", user.Name, defaultClusterName)
config := clientcmdapi.Config{ config := clientcmdapi.Config{
Kind: configMapKind, Kind: configMapKind,
APIVersion: configMapAPIVersion, APIVersion: configMapAPIVersion,
...@@ -122,9 +117,6 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error { ...@@ -122,9 +117,6 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
InsecureSkipTLSVerify: false, InsecureSkipTLSVerify: false,
CertificateAuthorityData: ca, CertificateAuthorityData: ca,
}}, }},
AuthInfos: map[string]*clientcmdapi.AuthInfo{user.Name: {
ClientKeyData: clientKey,
}},
Contexts: map[string]*clientcmdapi.Context{currentContext: { Contexts: map[string]*clientcmdapi.Context{currentContext: {
Cluster: defaultClusterName, Cluster: defaultClusterName,
AuthInfo: user.Name, AuthInfo: user.Name,
...@@ -134,26 +126,29 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error { ...@@ -134,26 +126,29 @@ func (o *operator) CreateKubeConfig(user *iamv1alpha2.User) error {
} }
kubeconfig, err := clientcmd.Write(config) kubeconfig, err := clientcmd.Write(config)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return err return err
} }
cm := &corev1.ConfigMap{TypeMeta: metav1.TypeMeta{Kind: configMapKind, APIVersion: configMapAPIVersion}, cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: configName, Labels: map[string]string{constants.UsernameLabelKey: user.Name}}, TypeMeta: metav1.TypeMeta{
Data: map[string]string{kubeconfigFileName: string(kubeconfig)}} Kind: configMapKind,
APIVersion: configMapAPIVersion,
err = controllerutil.SetControllerReference(user, cm, scheme.Scheme) },
ObjectMeta: metav1.ObjectMeta{
Name: configName,
Labels: map[string]string{constants.UsernameLabelKey: user.Name},
},
Data: map[string]string{kubeconfigFileName: string(kubeconfig)},
}
if err != nil { if err = controllerutil.SetControllerReference(user, cm, scheme.Scheme); err != nil {
klog.Errorln(err) klog.Errorln(err)
return err return err
} }
_, err = o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(cm) if _, err = o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(cm); err != nil {
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return err return err
} }
...@@ -170,23 +165,19 @@ func (o *operator) GetKubeConfig(username string) (string, error) { ...@@ -170,23 +165,19 @@ func (o *operator) GetKubeConfig(username string) (string, error) {
} }
data := []byte(configMap.Data[kubeconfigFileName]) data := []byte(configMap.Data[kubeconfigFileName])
kubeconfig, err := clientcmd.Load(data) kubeconfig, err := clientcmd.Load(data)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return "", err return "", err
} }
masterURL := o.masterURL masterURL := o.masterURL
// server host override // server host override
if cluster := kubeconfig.Clusters[defaultClusterName]; cluster != nil && masterURL != "" { if cluster := kubeconfig.Clusters[defaultClusterName]; cluster != nil && masterURL != "" {
cluster.Server = masterURL cluster.Server = masterURL
} }
data, err = clientcmd.Write(*kubeconfig) data, err = clientcmd.Write(*kubeconfig)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return "", err return "", err
...@@ -195,55 +186,49 @@ func (o *operator) GetKubeConfig(username string) (string, error) { ...@@ -195,55 +186,49 @@ func (o *operator) GetKubeConfig(username string) (string, error) {
return string(data), nil return string(data), nil
} }
func (o *operator) createCSR(username string) ([]byte, error) { func (o *operator) createCSR(username string) error {
csrConfig := &certutil.Config{ csrConfig := &certutil.Config{
CommonName: username, CommonName: username,
Organization: nil, Organization: nil,
AltNames: certutil.AltNames{}, AltNames: certutil.AltNames{},
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
} }
x509csr, x509key, err := pkiutil.NewCSRAndKey(csrConfig) x509csr, x509key, err := pkiutil.NewCSRAndKey(csrConfig)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
return nil, err return err
} }
var csrBuffer, keyBuffer bytes.Buffer var csrBuffer, keyBuffer bytes.Buffer
if err = pem.Encode(&keyBuffer, &pem.Block{Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(x509key)}); err != nil {
err = pem.Encode(&keyBuffer, &pem.Block{Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(x509key)})
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return nil, err return err
} }
csrBytes, err := x509.CreateCertificateRequest(rand.Reader, x509csr, x509key) var csrBytes []byte
if csrBytes, err = x509.CreateCertificateRequest(rand.Reader, x509csr, x509key); err != nil {
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return nil, err return err
} }
err = pem.Encode(&csrBuffer, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}) if err = pem.Encode(&csrBuffer, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}); err != nil {
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return nil, err return err
} }
csr := csrBuffer.Bytes() csr := csrBuffer.Bytes()
key := keyBuffer.Bytes() key := keyBuffer.Bytes()
csrName := fmt.Sprintf("%s-csr-%d", username, time.Now().Unix()) csrName := fmt.Sprintf("%s-csr-%d", username, time.Now().Unix())
k8sCSR := &certificatesv1beta1.CertificateSigningRequest{ k8sCSR := &certificatesv1beta1.CertificateSigningRequest{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "CertificateSigningRequest", Kind: "CertificateSigningRequest",
APIVersion: "certificates.k8s.io/v1beta1", APIVersion: "certificates.k8s.io/v1beta1",
}, },
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: csrName, Name: csrName,
Labels: map[string]string{constants.UsernameLabelKey: username}, Labels: map[string]string{constants.UsernameLabelKey: username},
Annotations: map[string]string{privateKeyAnnotation: string(key)},
}, },
Spec: certificatesv1beta1.CertificateSigningRequestSpec{ Spec: certificatesv1beta1.CertificateSigningRequestSpec{
Request: csr, Request: csr,
...@@ -254,17 +239,16 @@ func (o *operator) createCSR(username string) ([]byte, error) { ...@@ -254,17 +239,16 @@ func (o *operator) createCSR(username string) ([]byte, error) {
} }
// create csr // create csr
k8sCSR, err = o.k8sClient.CertificatesV1beta1().CertificateSigningRequests().Create(k8sCSR) if _, err = o.k8sClient.CertificatesV1beta1().CertificateSigningRequests().Create(k8sCSR); err != nil {
if err != nil {
klog.Errorln(err) klog.Errorln(err)
return nil, err return err
} }
return key, nil return nil
} }
func (o *operator) UpdateKubeconfig(username string, certificate []byte) error { // Update client key and client certificate after CertificateSigningRequest has been approved
func (o *operator) UpdateKubeconfig(username string, csr *certificatesv1beta1.CertificateSigningRequest) error {
configName := fmt.Sprintf(kubeconfigNameFormat, username) configName := fmt.Sprintf(kubeconfigNameFormat, username)
configMap, err := o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metav1.GetOptions{}) configMap, err := o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metav1.GetOptions{})
if err != nil { if err != nil {
...@@ -272,7 +256,7 @@ func (o *operator) UpdateKubeconfig(username string, certificate []byte) error { ...@@ -272,7 +256,7 @@ func (o *operator) UpdateKubeconfig(username string, certificate []byte) error {
return err return err
} }
configMap = appendCert(configMap, certificate) configMap = applyCert(configMap, csr)
_, err = o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Update(configMap) _, err = o.k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Update(configMap)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
...@@ -281,33 +265,31 @@ func (o *operator) UpdateKubeconfig(username string, certificate []byte) error { ...@@ -281,33 +265,31 @@ func (o *operator) UpdateKubeconfig(username string, certificate []byte) error {
return nil return nil
} }
func appendCert(cm *corev1.ConfigMap, cert []byte) *corev1.ConfigMap { func applyCert(cm *corev1.ConfigMap, csr *certificatesv1beta1.CertificateSigningRequest) *corev1.ConfigMap {
data := []byte(cm.Data[kubeconfigFileName]) data := []byte(cm.Data[kubeconfigFileName])
kubeconfig, err := clientcmd.Load(data) kubeconfig, err := clientcmd.Load(data)
// ignore if invalid format
if err != nil { if err != nil {
klog.Warning(err) klog.Error(err)
return cm return cm
} }
username := getControlledUsername(cm) username := getControlledUsername(cm)
privateKey := csr.Annotations[privateKeyAnnotation]
if kubeconfig.AuthInfos[username] != nil { clientCert := csr.Status.Certificate
kubeconfig.AuthInfos[username].ClientCertificateData = cert kubeconfig.AuthInfos = map[string]*clientcmdapi.AuthInfo{
username: {
ClientKeyData: []byte(privateKey),
ClientCertificateData: clientCert,
},
} }
data, err = clientcmd.Write(*kubeconfig) data, err = clientcmd.Write(*kubeconfig)
// ignore if invalid format
if err != nil { if err != nil {
klog.Warning(err) klog.Error(err)
return cm return cm
} }
cm.Data[kubeconfigFileName] = string(data) cm.Data[kubeconfigFileName] = string(data)
return cm return cm
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册