From 7ec9315e57ae0fad4dc222f7d1059bee11edcf8b Mon Sep 17 00:00:00 2001 From: shivdudhani Date: Wed, 29 May 2019 12:36:03 -0700 Subject: [PATCH 1/4] use single secret for tlsPair, check for secret annotation for self-signed cert & change type of secret from generic to tls --- client/certificates.go | 144 ++++++++++++++-------------------- documentation/installation.md | 9 ++- init.go | 54 +------------ main.go | 10 +-- pkg/webhooks/registration.go | 4 +- 5 files changed, 68 insertions(+), 153 deletions(-) diff --git a/client/certificates.go b/client/certificates.go index e7099bc081..3243a0954d 100644 --- a/client/certificates.go +++ b/client/certificates.go @@ -3,13 +3,16 @@ package client import ( "errors" "fmt" + "net/url" "time" + "github.com/nirmata/kyverno/pkg/config" tls "github.com/nirmata/kyverno/pkg/tls" certificates "k8s.io/api/certificates/v1beta1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/rest" ) // Issues TLS certificate for webhook server using given PEM private key @@ -114,47 +117,14 @@ func (c *Client) fetchCertificateFromRequest(req *certificates.CertificateSignin return nil, errors.New(fmt.Sprintf("Cerificate fetch timeout is reached: %d seconds", maxWaitSeconds)) } -const ( - ns string = "kyverno" - tlskeypair string = "tls.kyverno" - tlskeypaircert string = "tls.crt" - tlskeypairkey string = "tls.key" - tlsca string = "tls-ca" - tlscarootca string = "rootCA.crt" -) - -// CheckPrePreqSelfSignedCert checks if the required secrets are defined -// if the user is providing self-signed certificates,key pair and CA -func (c *Client) CheckPrePreqSelfSignedCert() bool { - // Check if secrets are defined if user is specifiying self-signed certificates - tlspairfound := true - tlscafound := true - _, err := c.GetResource(Secrets, ns, tlskeypair) +func (c *Client) ReadRootCASecret() (result []byte) { + certProps, err := c.GetTLSCertProps(c.clientConfig) if err != nil { - tlspairfound = false + utilruntime.HandleError(err) + return result } - _, err = c.GetResource(Secrets, ns, tlsca) - if err != nil { - tlscafound = false - } - if tlspairfound == tlscafound { - return true - } - // Fail if only one of them is defined - c.logger.Printf("while using self-signed certificates specify both secrets %s/%s & %s/%s for (cert,key) pair & CA respectively", ns, tlskeypair, ns, tlsca) - - if !tlspairfound { - c.logger.Printf("secret %s/%s not defined for (cert,key) pair", ns, tlskeypair) - } - - if !tlscafound { - c.logger.Printf("secret %s/%s not defined for CA", ns, tlsca) - } - return false -} - -func (c *Client) TlsrootCAfromSecret() (result []byte) { - stlsca, err := c.GetResource(Secrets, ns, tlsca) + sname := generateRootCASecretName(certProps) + stlsca, err := c.GetResource(Secrets, certProps.Namespace, sname) if err != nil { return result } @@ -164,69 +134,52 @@ func (c *Client) TlsrootCAfromSecret() (result []byte) { return result } - result = tlsca.Data[tlscarootca] + result = tlsca.Data[rootCAKey] if len(result) == 0 { - c.logger.Printf("root CA certificate not found in secret %s/%s", ns, tlsca.Name) + c.logger.Printf("root CA certificate not found in secret %s/%s", certProps.Namespace, tlsca.Name) return result } - c.logger.Printf("using CA bundle defined in secret %s/%s to validate the webhook's server certificate", ns, tlsca.Name) + c.logger.Printf("using CA bundle defined in secret %s/%s to validate the webhook's server certificate", certProps.Namespace, tlsca.Name) return result } -func (c *Client) TlsPairFromSecrets() *tls.TlsPemPair { - // Check if secrets are defined - stlskeypair, err := c.GetResource(Secrets, ns, tlskeypair) - if err != nil { - return nil - } - tlskeypair, err := convertToSecret(stlskeypair) - if err != nil { - utilruntime.HandleError(err) - return nil - } - - pemPair := tls.TlsPemPair{ - Certificate: tlskeypair.Data[tlskeypaircert], - PrivateKey: tlskeypair.Data[tlskeypairkey], - } - - if len(pemPair.Certificate) == 0 { - c.logger.Printf("TLS Certificate not found in secret %s/%s", ns, tlskeypair.Name) - return nil - } - if len(pemPair.PrivateKey) == 0 { - c.logger.Printf("TLS PrivateKey not found in secret %s/%s", ns, tlskeypair.Name) - return nil - } - c.logger.Printf("using TLS pair defined in secret %s/%s for webhook's server tls configuration", ns, tlskeypair.Name) - return &pemPair -} - -const privateKeyField string = "privateKey" -const certificateField string = "certificate" +const selfSignedAnnotation string = "self-signed-cert" +const rootCAKey string = "rootCA.crt" // Reads the pair of TLS certificate and key from the specified secret. func (c *Client) ReadTlsPair(props tls.TlsCertificateProps) *tls.TlsPemPair { - name := generateSecretName(props) - unstrSecret, err := c.GetResource(Secrets, props.Namespace, name) + sname := generateTLSPairSecretName(props) + unstrSecret, err := c.GetResource(Secrets, props.Namespace, sname) if err != nil { - c.logger.Printf("Unable to get secret %s/%s: %s", props.Namespace, name, err) + c.logger.Printf("Unable to get secret %s/%s: %s", props.Namespace, sname, err) return nil } + + // If secret contains annotation 'self-signed-cert', then it's created using helper scripts to setup self-signed certificates. + // As the root CA used to sign the certificate is required for webhook cnofiguration, check if the corresponding secret is created + annotations := unstrSecret.GetAnnotations() + if _, ok := annotations[selfSignedAnnotation]; ok { + sname := generateRootCASecretName(props) + _, err := c.GetResource(Secrets, props.Namespace, sname) + if err != nil { + utilruntime.HandleError(fmt.Errorf("Root CA secret %s/%s is required while using self-signed certificates TLS pair, defaulting to generating new TLS pair", props.Namespace, sname)) + return nil + } + } secret, err := convertToSecret(unstrSecret) if err != nil { return nil } pemPair := tls.TlsPemPair{ - Certificate: secret.Data[certificateField], - PrivateKey: secret.Data[privateKeyField], + Certificate: secret.Data[v1.TLSCertKey], + PrivateKey: secret.Data[v1.TLSPrivateKeyKey], } if len(pemPair.Certificate) == 0 { - c.logger.Printf("TLS Certificate not found in secret %s/%s", props.Namespace, name) + c.logger.Printf("TLS Certificate not found in secret %s/%s", props.Namespace, sname) return nil } if len(pemPair.PrivateKey) == 0 { - c.logger.Printf("TLS PrivateKey not found in secret %s/%s", props.Namespace, name) + c.logger.Printf("TLS PrivateKey not found in secret %s/%s", props.Namespace, sname) return nil } return &pemPair @@ -235,7 +188,7 @@ func (c *Client) ReadTlsPair(props tls.TlsCertificateProps) *tls.TlsPemPair { // Writes the pair of TLS certificate and key to the specified secret. // Updates existing secret or creates new one. func (c *Client) WriteTlsPair(props tls.TlsCertificateProps, pemPair *tls.TlsPemPair) error { - name := generateSecretName(props) + name := generateTLSPairSecretName(props) _, err := c.GetResource(Secrets, props.Namespace, name) if err != nil { secret := &v1.Secret{ @@ -248,9 +201,10 @@ func (c *Client) WriteTlsPair(props tls.TlsCertificateProps, pemPair *tls.TlsPem Namespace: props.Namespace, }, Data: map[string][]byte{ - certificateField: pemPair.Certificate, - privateKeyField: pemPair.PrivateKey, + v1.TLSCertKey: pemPair.Certificate, + v1.TLSPrivateKeyKey: pemPair.PrivateKey, }, + Type: v1.SecretTypeTLS, } _, err := c.CreateResource(Secrets, props.Namespace, secret) @@ -264,8 +218,8 @@ func (c *Client) WriteTlsPair(props tls.TlsCertificateProps, pemPair *tls.TlsPem if secret.Data == nil { secret.Data = make(map[string][]byte) } - secret.Data[certificateField] = pemPair.Certificate - secret.Data[privateKeyField] = pemPair.PrivateKey + secret.Data[v1.TLSCertKey] = pemPair.Certificate + secret.Data[v1.TLSPrivateKeyKey] = pemPair.PrivateKey _, err = c.UpdateResource(Secrets, props.Namespace, secret) if err != nil { @@ -275,6 +229,24 @@ func (c *Client) WriteTlsPair(props tls.TlsCertificateProps, pemPair *tls.TlsPem return nil } -func generateSecretName(props tls.TlsCertificateProps) string { +func generateTLSPairSecretName(props tls.TlsCertificateProps) string { return tls.GenerateInClusterServiceName(props) + ".kyverno-tls-pair" } + +func generateRootCASecretName(props tls.TlsCertificateProps) string { + return tls.GenerateInClusterServiceName(props) + ".kyverno-tls-ca" +} + +//GetTLSCertProps provides the TLS Certificate Properties +func (c *Client) GetTLSCertProps(configuration *rest.Config) (certProps tls.TlsCertificateProps, err error) { + apiServerURL, err := url.Parse(configuration.Host) + if err != nil { + return certProps, err + } + certProps = tls.TlsCertificateProps{ + Service: config.WebhookServiceName, + Namespace: config.KubePolicyNamespace, + ApiServerHost: apiServerURL.Hostname(), + } + return certProps, nil +} diff --git a/documentation/installation.md b/documentation/installation.md index f2751c3066..6a2407c66c 100644 --- a/documentation/installation.md +++ b/documentation/installation.md @@ -56,13 +56,14 @@ the following files are generated and are used to create kubernetes secrets: To create the required secrets: 1. `kubectl create ns kyverno` -2. `kubectl -n kyverno create secret tls tls.kyverno --cert=webhook.crt --key=webhook.key ` -3. `kubectl -n kyverno create secret generic tls-ca --from-file=rootCA.crt` +2. `kubectl -n kyverno create secret tls kyverno-svc.kyverno.svc.kyverno-tls-pair --cert=webhook.crt --key=webhook.key ` +3. `kubectl annotate secret kyverno-svc.kyverno.svc.kyverno-tls-pair -n kyverno self-signed-cert=true` +4. `kubectl -n kyverno create secret generic kyverno-svc.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt` Secret | Data | Content ------------ | ------------- | ------------- -`tls.ca` | rootCA.crt | root CA used to sign the certificate -`tls.kyverno` | tls.key & tls.crt | key and signed certificate +`kyverno-svc.kyverno.svc.kyverno-tls-pair` | rootCA.crt | root CA used to sign the certificate +`kyverno-svc.kyverno.svc.kyverno-tls-ca` | tls.key & tls.crt | key and signed certificate Kyverno uses secrets created above to define the TLS configuration for the webserver hook and specify the CA bundle used to validate the webhook's server certificate in the admission webhook configurations. diff --git a/init.go b/init.go index 3d14ffdfd4..11dd35c42e 100644 --- a/init.go +++ b/init.go @@ -1,12 +1,9 @@ package main import ( - "io/ioutil" "log" - "net/url" client "github.com/nirmata/kyverno/client" - "github.com/nirmata/kyverno/pkg/config" tls "github.com/nirmata/kyverno/pkg/tls" rest "k8s.io/client-go/rest" @@ -22,60 +19,14 @@ func createClientConfig(kubeconfig string) (*rest.Config, error) { return clientcmd.BuildConfigFromFlags("", kubeconfig) } -func initTlsPemPair(certFile, keyFile string, clientConfig *rest.Config, client *client.Client) (*tls.TlsPemPair, error) { - var tlsPair *tls.TlsPemPair - if certFile != "" || keyFile != "" { - tlsPair = tlsPairFromFiles(certFile, keyFile) - } - // if cert & key defined in secret(tls.kyverno) use it, - // the CA used to sign the cert is expected in secret (tls-ca) - tlsPair = client.TlsPairFromSecrets() - - var err error - if tlsPair != nil { - return tlsPair, nil - } - tlsPair, err = tlsPairFromCluster(clientConfig, client) - return tlsPair, err -} - -// Loads PEM private key and TLS certificate from given files -func tlsPairFromFiles(certFile, keyFile string) *tls.TlsPemPair { - if certFile == "" || keyFile == "" { - return nil - } - - certContent, err := ioutil.ReadFile(certFile) - if err != nil { - log.Printf("Unable to read file with TLS certificate: path - %s, error - %v", certFile, err) - return nil - } - - keyContent, err := ioutil.ReadFile(keyFile) - if err != nil { - log.Printf("Unable to read file with TLS private key: path - %s, error - %v", keyFile, err) - return nil - } - - return &tls.TlsPemPair{ - Certificate: certContent, - PrivateKey: keyContent, - } -} - // Loads or creates PEM private key and TLS certificate for webhook server. // Created pair is stored in cluster's secret. // Returns struct with key/certificate pair. -func tlsPairFromCluster(configuration *rest.Config, client *client.Client) (*tls.TlsPemPair, error) { - apiServerURL, err := url.Parse(configuration.Host) +func initTlsPemPair(configuration *rest.Config, client *client.Client) (*tls.TlsPemPair, error) { + certProps, err := client.GetTLSCertProps(configuration) if err != nil { return nil, err } - certProps := tls.TlsCertificateProps{ - Service: config.WebhookServiceName, - Namespace: config.KubePolicyNamespace, - ApiServerHost: apiServerURL.Hostname(), - } tlsPair := client.ReadTlsPair(certProps) if tls.IsTlsPairShouldBeUpdated(tlsPair) { log.Printf("Generating new key/certificate pair for TLS") @@ -88,6 +39,5 @@ func tlsPairFromCluster(configuration *rest.Config, client *client.Client) (*tls log.Printf("Unable to save TLS pair to the cluster: %v", err) } } - return tlsPair, nil } diff --git a/main.go b/main.go index 1e15d009b5..2c6007f06c 100644 --- a/main.go +++ b/main.go @@ -15,8 +15,6 @@ import ( var ( kubeconfig string - cert string - key string ) func main() { @@ -30,10 +28,6 @@ func main() { log.Fatalf("Error creating client: %v\n", err) } - if !client.CheckPrePreqSelfSignedCert() { - log.Fatalf("Error loading the pre-requisites\n") - } - policyInformerFactory, err := sharedinformer.NewSharedInformerFactory(clientConfig) if err != nil { log.Fatalf("Error creating policy sharedinformer: %v\n", err) @@ -48,7 +42,7 @@ func main() { eventController, nil) - tlsPair, err := initTlsPemPair(cert, key, clientConfig, client) + tlsPair, err := initTlsPemPair(clientConfig, client) if err != nil { log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err) } @@ -84,7 +78,5 @@ func main() { func init() { flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") - flag.StringVar(&cert, "cert", "", "TLS certificate used in connection with cluster.") - flag.StringVar(&key, "key", "", "Key, used in TLS connection.") flag.Parse() } diff --git a/pkg/webhooks/registration.go b/pkg/webhooks/registration.go index a79a6b7815..88e654897b 100644 --- a/pkg/webhooks/registration.go +++ b/pkg/webhooks/registration.go @@ -74,7 +74,7 @@ func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(configurati var caData []byte // Check if ca is defined in the secret tls-ca // assume the key and signed cert have been defined in secret tls.kyverno - caData = wrc.client.TlsrootCAfromSecret() + caData = wrc.client.ReadRootCASecret() if len(caData) == 0 { // load the CA from kubeconfig caData = extractCA(configuration) @@ -103,7 +103,7 @@ func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(configurati func (wrc *WebhookRegistrationClient) constructValidatingWebhookConfig(configuration *rest.Config) (*admregapi.ValidatingWebhookConfiguration, error) { // Check if ca is defined in the secret tls-ca // assume the key and signed cert have been defined in secret tls.kyverno - caData := wrc.client.TlsrootCAfromSecret() + caData := wrc.client.ReadRootCASecret() if len(caData) == 0 { // load the CA from kubeconfig caData = extractCA(configuration) From 6cc4148facc63f8ae0c2e7ca9177172834e63f2e Mon Sep 17 00:00:00 2001 From: shivdudhani Date: Wed, 29 May 2019 14:12:09 -0700 Subject: [PATCH 2/4] move client to pkg, helper script for self-signed certs & update documentation --- documentation/installation.md | 4 ++++ init.go | 2 +- main.go | 2 +- pkg/controller/controller.go | 2 +- {client => pkg/dclient}/certificates.go | 0 {client => pkg/dclient}/client.go | 0 {client => pkg/dclient}/client_test.go | 0 {client => pkg/dclient}/utils.go | 0 pkg/engine/generation.go | 2 +- pkg/event/controller.go | 2 +- pkg/violation/builder.go | 2 +- pkg/webhooks/registration.go | 2 +- pkg/webhooks/server.go | 2 +- ...generate-self-signed-cert-and-k8secrets.sh | 23 +++++++++++++++++++ 14 files changed, 35 insertions(+), 8 deletions(-) rename {client => pkg/dclient}/certificates.go (100%) rename {client => pkg/dclient}/client.go (100%) rename {client => pkg/dclient}/client_test.go (100%) rename {client => pkg/dclient}/utils.go (100%) create mode 100755 scripts/generate-self-signed-cert-and-k8secrets.sh diff --git a/documentation/installation.md b/documentation/installation.md index 6a2407c66c..5d11150435 100644 --- a/documentation/installation.md +++ b/documentation/installation.md @@ -69,5 +69,9 @@ Kyverno uses secrets created above to define the TLS configuration for the webse To deploy the Kyverno project, run `kubectl create -f definitions/install.yaml`. You can ignore the error 'namespaces "kyverno" already exists', which occurs as we previously created the namespace while creating the secrets. +*If tls pair secret is created and secret for root CA is not defined, then Kyverno follows its default behaviour of generating new tls pair and generate certificate signing request for issuer to issue certificate.* + +Script to generate self-signed certificate and corresponding kubernetes secrets: [helper script](/scripts/generate-self-signed-cert-and-k8secrets.sh) + --- *Read Next >> [Writing Policies](/documentation/writing-policies.md)* diff --git a/init.go b/init.go index 11dd35c42e..a985d88a49 100644 --- a/init.go +++ b/init.go @@ -3,7 +3,7 @@ package main import ( "log" - client "github.com/nirmata/kyverno/client" + client "github.com/nirmata/kyverno/pkg/dclient" tls "github.com/nirmata/kyverno/pkg/tls" rest "k8s.io/client-go/rest" diff --git a/main.go b/main.go index 2c6007f06c..1d3497e674 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,8 @@ import ( "flag" "log" - client "github.com/nirmata/kyverno/client" controller "github.com/nirmata/kyverno/pkg/controller" + client "github.com/nirmata/kyverno/pkg/dclient" event "github.com/nirmata/kyverno/pkg/event" "github.com/nirmata/kyverno/pkg/sharedinformer" "github.com/nirmata/kyverno/pkg/violation" diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 132c652814..d750dea990 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -6,9 +6,9 @@ import ( "os" "time" - client "github.com/nirmata/kyverno/client" types "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1" lister "github.com/nirmata/kyverno/pkg/client/listers/policy/v1alpha1" + client "github.com/nirmata/kyverno/pkg/dclient" event "github.com/nirmata/kyverno/pkg/event" "github.com/nirmata/kyverno/pkg/sharedinformer" violation "github.com/nirmata/kyverno/pkg/violation" diff --git a/client/certificates.go b/pkg/dclient/certificates.go similarity index 100% rename from client/certificates.go rename to pkg/dclient/certificates.go diff --git a/client/client.go b/pkg/dclient/client.go similarity index 100% rename from client/client.go rename to pkg/dclient/client.go diff --git a/client/client_test.go b/pkg/dclient/client_test.go similarity index 100% rename from client/client_test.go rename to pkg/dclient/client_test.go diff --git a/client/utils.go b/pkg/dclient/utils.go similarity index 100% rename from client/utils.go rename to pkg/dclient/utils.go diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index 41084f3318..c4a3e2a1ab 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -4,8 +4,8 @@ import ( "fmt" "log" - client "github.com/nirmata/kyverno/client" kubepolicy "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1" + client "github.com/nirmata/kyverno/pkg/dclient" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/event/controller.go b/pkg/event/controller.go index 1ffd97c218..6425679e85 100644 --- a/pkg/event/controller.go +++ b/pkg/event/controller.go @@ -6,10 +6,10 @@ import ( "os" "time" - client "github.com/nirmata/kyverno/client" "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme" policyscheme "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme" v1alpha1 "github.com/nirmata/kyverno/pkg/client/listers/policy/v1alpha1" + client "github.com/nirmata/kyverno/pkg/dclient" "github.com/nirmata/kyverno/pkg/sharedinformer" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/violation/builder.go b/pkg/violation/builder.go index 8e76660be8..fe0d8e948c 100644 --- a/pkg/violation/builder.go +++ b/pkg/violation/builder.go @@ -5,9 +5,9 @@ import ( "log" "os" - client "github.com/nirmata/kyverno/client" types "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1" v1alpha1 "github.com/nirmata/kyverno/pkg/client/listers/policy/v1alpha1" + client "github.com/nirmata/kyverno/pkg/dclient" event "github.com/nirmata/kyverno/pkg/event" "github.com/nirmata/kyverno/pkg/sharedinformer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" diff --git a/pkg/webhooks/registration.go b/pkg/webhooks/registration.go index 88e654897b..0ec020c750 100644 --- a/pkg/webhooks/registration.go +++ b/pkg/webhooks/registration.go @@ -4,7 +4,7 @@ import ( "errors" "io/ioutil" - "github.com/nirmata/kyverno/client" + "github.com/nirmata/kyverno/pkg/dclient" "github.com/nirmata/kyverno/pkg/config" admregapi "k8s.io/api/admissionregistration/v1beta1" diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 116c0f7b98..457d0aec7d 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -12,9 +12,9 @@ import ( "os" "time" - "github.com/nirmata/kyverno/client" "github.com/nirmata/kyverno/pkg/client/listers/policy/v1alpha1" "github.com/nirmata/kyverno/pkg/config" + client "github.com/nirmata/kyverno/pkg/dclient" engine "github.com/nirmata/kyverno/pkg/engine" "github.com/nirmata/kyverno/pkg/sharedinformer" tlsutils "github.com/nirmata/kyverno/pkg/tls" diff --git a/scripts/generate-self-signed-cert-and-k8secrets.sh b/scripts/generate-self-signed-cert-and-k8secrets.sh new file mode 100755 index 0000000000..d168ec3f6a --- /dev/null +++ b/scripts/generate-self-signed-cert-and-k8secrets.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "Generating self-signed certificate" +# generate priv key for root CA +openssl genrsa -out rootCA.key 4096 +# generate root CA +openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt -subj "/C=US/ST=test/L=test /O=test /OU=PIB/CN=*.kyverno.svc/emailAddress=test@test.com" +# generate priv key +openssl genrsa -out webhook.key 4096 +# generate certificate +openssl req -new -key webhook.key -out webhook.csr -subj "/C=US/ST=test /L=test /O=test /OU=PIB/CN=kyverno-svc.kyverno.svc/emailAddress=test@test.com" +# sign the certificate using the root CA +openssl x509 -req -in webhook.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out webhook.crt -days 1024 -sha256 + +echo "Generating corresponding kubernetes secrets for TLS pair and root CA" +# create project namespace +kubectl create ns kyverno +# create tls pair secret +kubectl -n kyverno create secret tls kyverno-svc.kyverno.svc.kyverno-tls-pair --cert=webhook.crt --key=webhook.key +# annotate tls pair secret to specify use of self-signed certificates and check if root CA is created as secret +kubectl annotate secret kyverno-svc.kyverno.svc.kyverno-tls-pair -n kyverno self-signed-cert=true +# create root CA secret +kubectl -n kyverno create secret generic kyverno-svc.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt \ No newline at end of file From 9b0f8d48e06c7ea4964a437460ec1f66075619c4 Mon Sep 17 00:00:00 2001 From: shivdudhani Date: Wed, 29 May 2019 14:23:37 -0700 Subject: [PATCH 3/4] update doc --- documentation/installation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/installation.md b/documentation/installation.md index 5d11150435..61295f0bd0 100644 --- a/documentation/installation.md +++ b/documentation/installation.md @@ -59,6 +59,7 @@ To create the required secrets: 2. `kubectl -n kyverno create secret tls kyverno-svc.kyverno.svc.kyverno-tls-pair --cert=webhook.crt --key=webhook.key ` 3. `kubectl annotate secret kyverno-svc.kyverno.svc.kyverno-tls-pair -n kyverno self-signed-cert=true` 4. `kubectl -n kyverno create secret generic kyverno-svc.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt` +*The annotation on the TLS pair secret is used by Kyverno to identify the use of self-signed certificates and checks for the required root CA secret* Secret | Data | Content ------------ | ------------- | ------------- From 1c123a5513a45178e6a9f33f861d51b22a110891 Mon Sep 17 00:00:00 2001 From: shivdudhani Date: Wed, 29 May 2019 17:45:42 -0700 Subject: [PATCH 4/4] update doc --- documentation/installation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/installation.md b/documentation/installation.md index 61295f0bd0..6b3b3864e2 100644 --- a/documentation/installation.md +++ b/documentation/installation.md @@ -59,6 +59,7 @@ To create the required secrets: 2. `kubectl -n kyverno create secret tls kyverno-svc.kyverno.svc.kyverno-tls-pair --cert=webhook.crt --key=webhook.key ` 3. `kubectl annotate secret kyverno-svc.kyverno.svc.kyverno-tls-pair -n kyverno self-signed-cert=true` 4. `kubectl -n kyverno create secret generic kyverno-svc.kyverno.svc.kyverno-tls-ca --from-file=rootCA.crt` + *The annotation on the TLS pair secret is used by Kyverno to identify the use of self-signed certificates and checks for the required root CA secret* Secret | Data | Content