Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 45 additions & 30 deletions pkg/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ func initCerts(cfg *config.Config) (*certchains.CertificateChains, error) {
}

func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
// Anchor certificate expiration to the next day. This forces
// homogenous expiry dates for all certificates with the same validity.
startTime := time.Now()
nextMidnight := time.Date(
startTime.Year(),
startTime.Month(),
startTime.Day()+1,
0, 0, 0, 0,
startTime.Location(),
)
alignValidity := func(baseValidity time.Duration) time.Duration {
targetExpiration := nextMidnight.Add(baseValidity)
return time.Until(targetExpiration)
}

_, svcNet, err := net.ParseCIDR(cfg.Network.ServiceNetwork[0])
if err != nil {
return nil, err
Expand Down Expand Up @@ -97,33 +112,33 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kube-control-plane-signer",
cryptomaterial.KubeControlPlaneSignerCertDir(certsDir),
cryptomaterial.ShortLivedCertificateValidity,
alignValidity(cryptomaterial.ShortLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-controller-manager",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:kube-controller-manager"},
},
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-scheduler",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:kube-scheduler"},
},
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "cluster-policy-controller",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:kube-controller-manager"},
},
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "route-controller-manager",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: serviceaccount.UserInfo("openshift-route-controller-manager", "route-controller-manager-sa", ""),
}),
Expand All @@ -132,12 +147,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kube-apiserver-to-kubelet-signer",
cryptomaterial.KubeAPIServerToKubeletSignerCertDir(certsDir),
cryptomaterial.ShortLivedCertificateValidity,
alignValidity(cryptomaterial.ShortLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-apiserver-to-kubelet-client",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:kube-apiserver", Groups: []string{"kube-master"}},
}),
Expand All @@ -146,19 +161,19 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"admin-kubeconfig-signer",
cryptomaterial.AdminKubeconfigSignerDir(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "admin-kubeconfig-client",
Validity: cryptomaterial.LongLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.LongLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:admin", Groups: []string{"system:masters"}},
}).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "openshift-observability-client",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "openshift-observability-client", Groups: []string{""}},
},
Expand All @@ -168,17 +183,17 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kubelet-signer",
cryptomaterial.KubeletCSRSignerSignerCertDir(certsDir),
cryptomaterial.ShortLivedCertificateValidity,
alignValidity(cryptomaterial.ShortLivedCertificateValidity),
).WithSubCAs(
certchains.NewCertificateSigner(
"kube-csr-signer",
cryptomaterial.CSRSignerCertDir(certsDir),
cryptomaterial.ShortLivedCertificateValidity,
alignValidity(cryptomaterial.ShortLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kubelet-client",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
// userinfo per https://kubernetes.io/docs/reference/access-authn-authz/node/#overview
UserInfo: &user.DefaultInfo{Name: "system:node:" + cfg.CanonicalNodeName(), Groups: []string{"system:nodes"}},
Expand All @@ -187,7 +202,7 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kubelet-server",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: []string{cfg.Node.HostnameOverride, cfg.Node.NodeIP},
},
Expand All @@ -196,12 +211,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"aggregator-signer",
cryptomaterial.AggregatorSignerDir(certsDir),
cryptomaterial.ShortLivedCertificateValidity,
alignValidity(cryptomaterial.ShortLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "aggregator-client",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:openshift-aggregator"},
},
Expand All @@ -213,12 +228,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"service-ca",
cryptomaterial.ServiceCADir(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithServingCertificates(
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "route-controller-manager-serving",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: []string{
"route-controller-manager.openshift-route-controller-manager.svc",
Expand All @@ -230,12 +245,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"ingress-ca",
cryptomaterial.IngressCADir(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithServingCertificates(
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "router-default-serving",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: []string{
"*.apps." + cfg.DNS.BaseDomain, // wildcard for any additional auto-generated domains
Expand All @@ -248,12 +263,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kube-apiserver-external-signer",
cryptomaterial.KubeAPIServerExternalSigner(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithServingCertificates(
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-external-serving",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: externalCertNames,
},
Expand All @@ -262,12 +277,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kube-apiserver-localhost-signer",
cryptomaterial.KubeAPIServerLocalhostSigner(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithServingCertificates(
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-apiserver-localhost-serving",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: []string{
"localhost",
Expand All @@ -278,12 +293,12 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"kube-apiserver-service-network-signer",
cryptomaterial.KubeAPIServerServiceNetworkSigner(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithServingCertificates(
&certchains.ServingCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "kube-apiserver-service-network-serving",
Validity: cryptomaterial.ShortLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity),
},
Hostnames: []string{
"kubernetes",
Expand All @@ -308,28 +323,28 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) {
certchains.NewCertificateSigner(
"etcd-signer",
cryptomaterial.EtcdSignerDir(certsDir),
cryptomaterial.LongLivedCertificateValidity,
alignValidity(cryptomaterial.LongLivedCertificateValidity),
).WithClientCertificates(
&certchains.ClientCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "apiserver-etcd-client",
Validity: cryptomaterial.LongLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.LongLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "etcd", Groups: []string{"etcd"}},
},
).WithPeerCertificiates(
&certchains.PeerCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "etcd-peer",
Validity: cryptomaterial.LongLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.LongLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:etcd-peer:etcd-client", Groups: []string{"system:etcd-peers"}},
Hostnames: []string{"localhost", cfg.Node.HostnameOverride, cfg.Node.NodeIP},
},
&certchains.PeerCertificateSigningRequestInfo{
CSRMeta: certchains.CSRMeta{
Name: "etcd-serving",
Validity: cryptomaterial.LongLivedCertificateValidity,
Validity: alignValidity(cryptomaterial.LongLivedCertificateValidity),
},
UserInfo: &user.DefaultInfo{Name: "system:etcd-server:etcd-client", Groups: []string{"system:etcd-servers"}},
Hostnames: []string{"localhost", cfg.Node.HostnameOverride, cfg.Node.NodeIP},
Expand Down
13 changes: 9 additions & 4 deletions test/suites/standard2/validate-certificate-rotation.robot
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ ${FUTURE_DAYS} 150
*** Test Cases ***
Certificate Rotation
[Documentation] Performs Certificate Expiration Rotation test
# Certificates expire at midnight of (tomorrow + validity). For short-lived certs,
# validity is 365 days, so expiry = tomorrow + 365 days.
${first_cert_date}= Compute Date After Days 365 ${OSSL_DATE_FORMAT}
Certs Should Expire On ${KUBE_SCHEDULER_CLIENT_CERT} ${first_cert_date}
${cert_should_expire_in_days}= Evaluate 365+${FUTURE_DAYS}
# After moving the clock forward by FUTURE_DAYS, regenerated certs will expire at
# (new tomorrow + 365). Since "new tomorrow" is (original tomorrow + FUTURE_DAYS + 1),
# the expected expiry from the original date is: tomorrow + 366 + FUTURE_DAYS.
${cert_should_expire_in_days}= Evaluate 366+${FUTURE_DAYS}
${cert_expiry_date}= Compute Date After Days ${cert_should_expire_in_days} ${OSSL_DATE_FORMAT}
${future_date}= Compute Date After Days ${FUTURE_DAYS} ${TIMEDATECTL_DATE_FORMAT}
Change System Date To ${future_date}
Expand Down Expand Up @@ -67,10 +72,10 @@ Change System Date To
Wait For MicroShift

Compute Date After Days
[Documentation] return system date after number of days elapsed
[Documentation] return system date after number of days elapsed from midnight tomorrow
[Arguments] ${number_of_days} ${date_format}
# date command is used here because we need to consider the remote vm timezone .
${future_date}= Command Should Work TZ=UTC date "+${date_format}" -d "$(date) + ${number_of_days} day"
# Certificates are aligned to expire at midnight of the next day + validity
${future_date}= Command Should Work TZ=UTC date "+${date_format}" -d "tomorrow + ${number_of_days} day"
RETURN ${future_date}

Certs Should Expire On
Expand Down