Skip to content

Commit ec26b66

Browse files
authored
security: only approve validated CSR (#5972)
Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
1 parent 5610b55 commit ec26b66

File tree

3 files changed

+50
-13
lines changed

3 files changed

+50
-13
lines changed

pkg/controller/pki.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import (
1515
)
1616

1717
func (c *Controller) InitDefaultOVNIPsecCA() error {
18-
_, err := c.config.KubeClient.CoreV1().Secrets("kube-system").Get(context.TODO(), util.DefaultOVNIPSecCA, metav1.GetOptions{})
18+
namespace := os.Getenv("POD_NAMESPACE")
19+
_, err := c.config.KubeClient.CoreV1().Secrets(namespace).Get(context.TODO(), util.DefaultOVNIPSecCA, metav1.GetOptions{})
1920
if err == nil {
2021
klog.Infof("ovn ipsec CA secret already exists, skip")
2122
return nil
@@ -56,15 +57,15 @@ func (c *Controller) InitDefaultOVNIPsecCA() error {
5657
secret := &v1.Secret{
5758
ObjectMeta: metav1.ObjectMeta{
5859
Name: util.DefaultOVNIPSecCA,
59-
Namespace: "kube-system",
60+
Namespace: namespace,
6061
},
6162
Data: map[string][]byte{
6263
"cacert": cacert,
6364
"cakey": cakey,
6465
},
6566
}
6667

67-
if _, err = c.config.KubeClient.CoreV1().Secrets("kube-system").Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil {
68+
if _, err = c.config.KubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil {
6869
return err
6970
}
7071

pkg/controller/signer.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import (
1111
"errors"
1212
"fmt"
1313
"math/big"
14+
"os"
15+
"slices"
16+
"strings"
1417
"time"
1518

1619
csrv1 "k8s.io/api/certificates/v1"
@@ -22,8 +25,46 @@ import (
2225
"github.com/kubeovn/kube-ovn/pkg/util"
2326
)
2427

28+
func (c *Controller) validateCsrName(name string) error {
29+
after, found := strings.CutPrefix(name, "ovn-ipsec-")
30+
if !found || len(after) == 0 {
31+
return fmt.Errorf("CSR name %s is invalid, must be in format ovn-ipsec-<node-name>", name)
32+
}
33+
34+
node, err := c.nodesLister.Get(after)
35+
if err != nil {
36+
if k8serrors.IsNotFound(err) {
37+
return fmt.Errorf("node %s not found for CSR %s", after, name)
38+
}
39+
return fmt.Errorf("failed to get node %s for CSR %s: %w", after, name, err)
40+
}
41+
if node.Status.NodeInfo.OperatingSystem != "linux" {
42+
return fmt.Errorf("node %s is not linux, CSR %s is invalid", after, name)
43+
}
44+
45+
return nil
46+
}
47+
48+
func (c *Controller) isOVNIPSecCSR(csr *csrv1.CertificateSigningRequest) bool {
49+
if csr.Spec.SignerName != util.SignerName ||
50+
!strings.HasPrefix(csr.Name, "ovn-ipsec-") ||
51+
!slices.Equal(csr.Spec.Usages, []csrv1.KeyUsage{csrv1.UsageIPsecTunnel}) {
52+
return false
53+
}
54+
if err := c.validateCsrName(csr.Name); err != nil {
55+
klog.Warningf("CSR %s validation failed: %v", csr.Name, err)
56+
return false
57+
}
58+
return true
59+
}
60+
2561
func (c *Controller) enqueueAddCsr(obj any) {
26-
key := cache.MetaObjectToName(obj.(*csrv1.CertificateSigningRequest)).String()
62+
req := obj.(*csrv1.CertificateSigningRequest)
63+
if !c.isOVNIPSecCSR(req) {
64+
return
65+
}
66+
67+
key := cache.MetaObjectToName(req).String()
2768
klog.V(3).Infof("enqueue add csr %s", key)
2869
c.addOrUpdateCsrQueue.Add(key)
2970
}
@@ -34,6 +75,9 @@ func (c *Controller) enqueueUpdateCsr(oldObj, newObj any) {
3475
if oldCsr.ResourceVersion == newCsr.ResourceVersion {
3576
return
3677
}
78+
if !c.isOVNIPSecCSR(newCsr) {
79+
return
80+
}
3781

3882
key := cache.MetaObjectToName(newCsr).String()
3983
klog.V(3).Infof("enqueue update csr %s", key)
@@ -50,10 +94,6 @@ func (c *Controller) handleAddOrUpdateCsr(key string) (err error) {
5094
return err
5195
}
5296

53-
if csr.Spec.SignerName != util.SignerName {
54-
return nil
55-
}
56-
5797
if len(csr.Status.Certificate) != 0 {
5898
// Request already has a certificate. There is nothing
5999
// to do as we will, currently, not re-certify or handle any updates to
@@ -83,7 +123,7 @@ func (c *Controller) handleAddOrUpdateCsr(key string) (err error) {
83123
}
84124
// From this, point we are dealing with an approved CSR
85125
// Get CA in from ovn-ipsec-ca
86-
caSecret, err := c.config.KubeClient.CoreV1().Secrets("kube-system").Get(context.TODO(), util.DefaultOVNIPSecCA, metav1.GetOptions{})
126+
caSecret, err := c.config.KubeClient.CoreV1().Secrets(os.Getenv("POD_NAMESPACE")).Get(context.TODO(), util.DefaultOVNIPSecCA, metav1.GetOptions{})
87127
if err != nil {
88128
c.signerFailure(csr, "CAFailure",
89129
fmt.Sprintf("Could not get CA certificate and key: %v", err))

pkg/daemon/ipsec.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,6 @@ func (c *Controller) getCertManagerSignedCert(ctx context.Context, csrBytes []by
297297

298298
func (c *Controller) getSignedCert(ctx context.Context, csrBytes []byte) ([]byte, error) {
299299
csr := &v1.CertificateSigningRequest{
300-
TypeMeta: metav1.TypeMeta{
301-
APIVersion: "certificates.k8s.io/v1",
302-
Kind: "CertificateSigningRequest",
303-
},
304300
ObjectMeta: metav1.ObjectMeta{
305301
Name: "ovn-ipsec-" + os.Getenv("HOSTNAME"),
306302
},

0 commit comments

Comments
 (0)