Skip to content

Commit

Permalink
add renewBefore to validate certs
Browse files Browse the repository at this point in the history
Signed-off-by: Kuromesi <blackfacepan@163.com>
  • Loading branch information
Kuromesi committed Jul 6, 2024
1 parent 7b8e0d7 commit 70ecb33
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
34 changes: 34 additions & 0 deletions pkg/webhook/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package util
import (
"os"
"strconv"
"time"

"k8s.io/klog/v2"

Expand Down Expand Up @@ -69,3 +70,36 @@ func GetCertDir() string {
func GetCertWriter() string {
return os.Getenv("WEBHOOK_CERT_WRITER")
}

var (
renewBefore time.Duration
)

func GetRenewBeforeTime() time.Duration {
if renewBefore != 0 {
return renewBefore
}
renewBefore = 6 * 30 * 24 * time.Hour
if s := os.Getenv("CERTS_RENEW_BEFORE"); len(s) > 0 {
t, err := strconv.Atoi(s[0 : len(s)-1])
if err != nil {
klog.Errorf("failed to parese time %s: %v", s[0:len(s)-1], err)
return renewBefore
}
suffix := s[len(s)-1]
if suffix == 'd' {
renewBefore = time.Duration(t) * 7 * time.Hour
} else if suffix == 'm' {
renewBefore = time.Duration(t) * 30 * time.Hour
} else if suffix == 'y' {
renewBefore = time.Duration(t) * 365 * time.Hour
} else {
klog.Errorf("unkonw date suffix %c", suffix)

Check warning on line 97 in pkg/webhook/util/util.go

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"unkonw" should be "unknown".
}
}
if renewBefore <= 0 {
klog.Error("renewBefore time can not be less or equal than 0")
renewBefore = 6 * 30 * 24 * time.Hour
}
return renewBefore
}
7 changes: 4 additions & 3 deletions pkg/webhook/util/writer/certwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"k8s.io/klog/v2"

"github.com/openkruise/kruise/pkg/webhook/util"
"github.com/openkruise/kruise/pkg/webhook/util/generator"
)

Expand Down Expand Up @@ -61,7 +62,8 @@ func handleCommon(dnsName string, ch certReadWriter) (*generator.Artifacts, bool
}

// Recreate the cert if it's invalid.
valid := validCert(certs, dnsName)
renewBefore := util.GetRenewBeforeTime()
valid := validCert(certs, dnsName, time.Now().Add(renewBefore))
if !valid {
klog.Info("cert is invalid or expired, regenerating a new one")
certs, err = ch.overwrite(certs.ResourceVersion)
Expand Down Expand Up @@ -98,10 +100,9 @@ type certReadWriter interface {
overwrite(resourceVersion string) (*generator.Artifacts, error)
}

func validCert(certs *generator.Artifacts, dnsName string) bool {
func validCert(certs *generator.Artifacts, dnsName string, expired time.Time) bool {
if certs == nil {
return false
}
expired := time.Now().AddDate(0, 6, 0)
return generator.ValidCACert(certs.Key, certs.Cert, certs.CACert, dnsName, expired)
}
26 changes: 24 additions & 2 deletions pkg/webhook/util/writer/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ limitations under the License.
package writer

import (
"bytes"
"context"
"errors"
"fmt"
"time"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"

"github.com/openkruise/kruise/pkg/webhook/util"
"github.com/openkruise/kruise/pkg/webhook/util/generator"
)

Expand All @@ -39,6 +43,8 @@ const (
ExternalServerKey = "tls.key"
)

var currentExternalCerts *generator.Artifacts

// externalCertWriter provisions the certificate by reading from the k8s secrets.
type externalCertWriter struct {
*ExternalCertWriterOptions
Expand Down Expand Up @@ -78,16 +84,25 @@ func NewExternalCertWriter(ops ExternalCertWriterOptions) (CertWriter, error) {

// EnsureCert read and validate certs from k8s secret.
func (s *externalCertWriter) EnsureCert(dnsName string) (*generator.Artifacts, bool, error) {
// Create or refresh the certs based on clientConfig
// Read certs from secrets generated by external
s.dnsName = dnsName
certs, err := s.read()
if err != nil {
return nil, false, err
}
valid := validCert(certs, dnsName)
// check if the certs are expired
renewBefore := util.GetRenewBeforeTime()
valid := validCert(certs, dnsName, time.Now().Add(renewBefore))
if !valid {
return nil, false, fmt.Errorf("cert is invalid or expired in secret %s/%s", s.Secret.Namespace, s.Secret.Name)
}
// check if the certs are updated since last read
if currentExternalCerts != nil && compareCerts(certs, currentExternalCerts) {
klog.Info("external certs are not updated")
return certs, false, nil
}

currentExternalCerts = certs
return certs, true, nil
}

Expand Down Expand Up @@ -125,3 +140,10 @@ func externalSecretToCerts(secret *corev1.Secret) *generator.Artifacts {
}
return ret
}

func compareCerts(certsA, certsB *generator.Artifacts) bool {
if !bytes.Equal(certsA.CACert, certsB.CACert) || !bytes.Equal(certsA.CAKey, certsB.CAKey) || !bytes.Equal(certsA.Cert, certsB.Cert) || !bytes.Equal(certsA.Key, certsB.Key) {
return false
}
return true
}

0 comments on commit 70ecb33

Please sign in to comment.