From d82f19be4e0c082c69fa860ec1dbe12dc0da7232 Mon Sep 17 00:00:00 2001 From: shuting Date: Wed, 20 Jan 2021 15:25:27 -0800 Subject: [PATCH] Feature/fix dev mode execution (#1477) * add serverIP to X.509 certificate SANs * disable webhook monitor in debug mode Signed-off-by: Shuting Zhao Signed-off-by: Jim Bugwadia Co-authored-by: Jim Bugwadia --- cmd/kyverno/main.go | 5 ++++- pkg/dclient/certificates.go | 9 ++++---- pkg/engine/validation.go | 8 ------- pkg/kyverno/main.go | 4 +--- pkg/tls/tls.go | 21 ++++++++++++++++--- pkg/webhooks/server.go | 8 ++++++- ...generate-self-signed-cert-and-k8secrets.sh | 4 ++++ 7 files changed, 39 insertions(+), 20 deletions(-) diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 62a4d41646..fcdc0241d0 100755 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -71,6 +71,7 @@ func main() { setupLog.Error(err, "failed to set log level") os.Exit(1) } + flag.Parse() version.PrintVersionInfo(log.Log) @@ -281,7 +282,7 @@ func main() { ) // Configure certificates - tlsPair, err := client.InitTLSPemPair(clientConfig) + tlsPair, err := client.InitTLSPemPair(clientConfig, serverIP) if err != nil { setupLog.Error(err, "Failed to initialize TLS key/certificate pair") os.Exit(1) @@ -310,6 +311,7 @@ func main() { // -- annotations on resources with update details on mutation JSON patches // -- generate policy violation resource // -- generate events on policy and resource + debug := serverIP != "" server, err := webhooks.NewWebhookServer( pclient, client, @@ -335,6 +337,7 @@ func main() { openAPIController, rCache, grc, + debug, ) if err != nil { diff --git a/pkg/dclient/certificates.go b/pkg/dclient/certificates.go index aa09de814f..784fa5c947 100644 --- a/pkg/dclient/certificates.go +++ b/pkg/dclient/certificates.go @@ -16,7 +16,7 @@ import ( // InitTLSPemPair 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 (c *Client) InitTLSPemPair(configuration *rest.Config) (*tls.PemPair, error) { +func (c *Client) InitTLSPemPair(configuration *rest.Config, serverIP string) (*tls.PemPair, error) { logger := c.log certProps, err := c.GetTLSCertProps(configuration) if err != nil { @@ -24,7 +24,7 @@ func (c *Client) InitTLSPemPair(configuration *rest.Config) (*tls.PemPair, error } logger.Info("Building key/certificate pair for TLS") - tlsPair, err := c.buildTLSPemPair(certProps) + tlsPair, err := c.buildTLSPemPair(certProps, serverIP) if err != nil { return nil, err } @@ -37,7 +37,7 @@ func (c *Client) InitTLSPemPair(configuration *rest.Config) (*tls.PemPair, error // buildTLSPemPair Issues TLS certificate for webhook server using self-signed CA cert // Returns signed and approved TLS certificate in PEM format -func (c *Client) buildTLSPemPair(props tls.CertificateProps) (*tls.PemPair, error) { +func (c *Client) buildTLSPemPair(props tls.CertificateProps, serverIP string) (*tls.PemPair, error) { caCert, caPEM, err := tls.GenerateCACert() if err != nil { return nil, err @@ -46,7 +46,8 @@ func (c *Client) buildTLSPemPair(props tls.CertificateProps) (*tls.PemPair, erro if err := c.WriteCACertToSecret(caPEM, props); err != nil { return nil, fmt.Errorf("failed to write CA cert to secret: %v", err) } - return tls.GenerateCertPem(caCert, props) + + return tls.GenerateCertPem(caCert, props, serverIP) } //ReadRootCASecret returns the RootCA from the pre-defined secret diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go index c457029f9d..5d608268a7 100644 --- a/pkg/engine/validation.go +++ b/pkg/engine/validation.go @@ -127,15 +127,7 @@ func validateResource(log logr.Logger, ctx *PolicyContext) *response.EngineRespo resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResponse) } } - } else if rule.Validation.Deny != nil { - - // validate new resource if available - otherwise old resource - resource := ctx.NewResource - if reflect.DeepEqual(resource, unstructured.Unstructured{}) { - resource = ctx.OldResource - } - denyConditionsCopy := copyConditions(rule.Validation.Deny.Conditions) deny := variables.EvaluateConditions(log, ctx.JSONContext, denyConditionsCopy) ruleResp := response.RuleResponse{ diff --git a/pkg/kyverno/main.go b/pkg/kyverno/main.go index 940a387869..73f9ed71f2 100644 --- a/pkg/kyverno/main.go +++ b/pkg/kyverno/main.go @@ -17,7 +17,7 @@ import ( func CLI() { cli := &cobra.Command{ Use: "kyverno", - Short: "kyverno manages native policies of Kubernetes", + Short: "Kubernetes Native Policy Management", } configurelog(cli) @@ -30,8 +30,6 @@ func CLI() { cli.AddCommand(commands...) - cli.SilenceUsage = true - if err := cli.Execute(); err != nil { os.Exit(1) } diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index feac464f3a..023db9e699 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -10,6 +10,7 @@ import ( "fmt" "math/big" "net" + "strings" "time" ) @@ -20,6 +21,7 @@ type CertificateProps struct { Service string Namespace string APIServerHost string + ServerIP string } // PemPair The pair of TLS certificate corresponding private key, both in PEM format @@ -65,6 +67,7 @@ func GenerateCACert() (*KeyPair, *PemPair, error) { now := time.Now() begin := now.Add(-1 * time.Hour) end := now.Add(certValidityDuration) + templ := &x509.Certificate{ SerialNumber: big.NewInt(0), Subject: pkix.Name{ @@ -76,10 +79,12 @@ func GenerateCACert() (*KeyPair, *PemPair, error) { BasicConstraintsValid: true, IsCA: true, } + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, fmt.Errorf("error generating key: %v", err) } + der, err := x509.CreateCertificate(rand.Reader, templ, templ, key.Public(), key) if err != nil { return nil, nil, fmt.Errorf("error creating certificate: %v", err) @@ -105,7 +110,7 @@ func GenerateCACert() (*KeyPair, *PemPair, error) { // GenerateCertPem takes the results of GenerateCACert and uses it to create the // PEM-encoded public certificate and private key, respectively -func GenerateCertPem(caCert *KeyPair, props CertificateProps) (*PemPair, error) { +func GenerateCertPem(caCert *KeyPair, props CertificateProps, serverIP string) (*PemPair, error) { now := time.Now() begin := now.Add(-1 * time.Hour) end := now.Add(certValidityDuration) @@ -127,13 +132,23 @@ func GenerateCertPem(caCert *KeyPair, props CertificateProps) (*PemPair, error) dnsNames = append(dnsNames, props.APIServerHost) } + if serverIP != "" { + if strings.Contains(serverIP, ":") { + host, _, _ := net.SplitHostPort(serverIP) + serverIP = host + } + + ip := net.ParseIP(serverIP) + ips = append(ips, ip) + } + templ := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: csCommonName, }, - DNSNames: dnsNames, - // IPAddresses: ips, + DNSNames: dnsNames, + IPAddresses: ips, NotBefore: begin, NotAfter: end, KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 9359b0333d..a1f3606a49 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -119,6 +119,8 @@ type WebhookServer struct { resCache resourcecache.ResourceCacheIface grController *generate.Controller + + debug bool } // NewWebhookServer creates new instance of WebhookServer accordingly to given configuration @@ -148,6 +150,7 @@ func NewWebhookServer( openAPIController *openapi.Controller, resCache resourcecache.ResourceCacheIface, grc *generate.Controller, + debug bool, ) (*WebhookServer, error) { if tlsPair == nil { @@ -192,6 +195,7 @@ func NewWebhookServer( openAPIController: openAPIController, supportMutateValidate: supportMutateValidate, resCache: resCache, + debug: debug, } mux := httprouter.New() @@ -490,7 +494,9 @@ func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) { logger.Info("starting service") - go ws.webhookMonitor.Run(ws.webhookRegister, ws.eventGen, ws.client, stopCh) + if !ws.debug { + go ws.webhookMonitor.Run(ws.webhookRegister, ws.eventGen, ws.client, stopCh) + } } // Stop TLS server and returns control after the server is shut down diff --git a/scripts/generate-self-signed-cert-and-k8secrets.sh b/scripts/generate-self-signed-cert-and-k8secrets.sh index 7dfa94d405..12adb0e156 100755 --- a/scripts/generate-self-signed-cert-and-k8secrets.sh +++ b/scripts/generate-self-signed-cert-and-k8secrets.sh @@ -26,6 +26,10 @@ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt 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=${service}.kyverno.svc/emailAddress=test@test.com" + +# generate SANs +echo "subjectAltName = DNS:kyverno-svc,DNS:kyverno-svc.kyverno,DNS:kyverno-svc.kyverno.svc" >> webhook.ext + # 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