Skip to content
This repository was archived by the owner on Aug 12, 2024. It is now read-only.

Commit e1d8b0e

Browse files
committed
Update certificate support
Remove `rootCAs` from the `NewDefaultUnpacker` API, the argument is no longer used for HTTP transport. Add `CertificateData` to the ImageSource struct. This is PEM-encoded data (straight from a Secret[tls.crt]) to be used to validate the certificate used to access an image regidstry (works along side the `InsecureSkipTLSVerify` option). Signed-off-by: Todd Short <[email protected]>
1 parent d2888ec commit e1d8b0e

File tree

9 files changed

+51
-20
lines changed

9 files changed

+51
-20
lines changed

api/v1alpha2/bundle_types.go

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ type ImageSource struct {
6767
// This should not be used in a production environment.
6868
// +optional
6969
InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"`
70+
// CertificateData contains the PEM data of the certificate that is to be used for the TLS connection
71+
CertificateData string `json:"certificateData,omitempty"`
7072
}
7173

7274
type GitSource struct {

cmd/core/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func main() {
199199
os.Exit(1)
200200
}
201201

202-
unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir, rootCAs)
202+
unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir)
203203
if err != nil {
204204
setupLog.Error(err, "unable to setup bundle unpacker")
205205
os.Exit(1)

cmd/helm/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func main() {
189189
os.Exit(1)
190190
}
191191

192-
unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir, rootCAs)
192+
unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir)
193193
if err != nil {
194194
setupLog.Error(err, "unable to setup bundle unpacker")
195195
os.Exit(1)

manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ spec:
223223
description: Image is the bundle image that backs the content
224224
of this bundle.
225225
properties:
226+
certificateData:
227+
description: CertificateData contains the PEM data of the
228+
certificate that is to be used for the TLS connection
229+
type: string
226230
insecureSkipTLSVerify:
227231
description: |-
228232
InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped.
@@ -468,6 +472,10 @@ spec:
468472
description: Image is the bundle image that backs the content
469473
of this bundle.
470474
properties:
475+
certificateData:
476+
description: CertificateData contains the PEM data of the
477+
certificate that is to be used for the TLS connection
478+
type: string
471479
insecureSkipTLSVerify:
472480
description: |-
473481
InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped.

pkg/source/image_registry.go

+18-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"archive/tar"
55
"context"
66
"crypto/tls"
7+
"crypto/x509"
78
"errors"
89
"fmt"
910
"io/fs"
@@ -64,14 +65,25 @@ func (i *ImageRegistry) Unpack(ctx context.Context, bundle *rukpakv1alpha2.Bundl
6465
remoteOpts = append(remoteOpts, remote.WithAuthFromKeychain(authChain))
6566
}
6667

68+
transport := remote.DefaultTransport.(*http.Transport).Clone()
69+
if transport.TLSClientConfig == nil {
70+
transport.TLSClientConfig = &tls.Config{
71+
InsecureSkipVerify: false,
72+
MinVersion: tls.VersionTLS12,
73+
} // nolint:gosec
74+
}
6775
if bundle.Spec.Source.Image.InsecureSkipTLSVerify {
68-
insecureTransport := remote.DefaultTransport.(*http.Transport).Clone()
69-
if insecureTransport.TLSClientConfig == nil {
70-
insecureTransport.TLSClientConfig = &tls.Config{} // nolint:gosec
76+
transport.TLSClientConfig.InsecureSkipVerify = true // nolint:gosec
77+
}
78+
if bundle.Spec.Source.Image.CertificateData != "" {
79+
pool, err := x509.SystemCertPool()
80+
if err != nil || pool == nil {
81+
pool = x509.NewCertPool()
7182
}
72-
insecureTransport.TLSClientConfig.InsecureSkipVerify = true // nolint:gosec
73-
remoteOpts = append(remoteOpts, remote.WithTransport(insecureTransport))
83+
transport.TLSClientConfig.RootCAs = pool
84+
transport.TLSClientConfig.RootCAs.AppendCertsFromPEM([]byte(bundle.Spec.Source.Image.CertificateData))
7485
}
86+
remoteOpts = append(remoteOpts, remote.WithTransport(transport))
7587

7688
digest, isDigest := imgRef.(name.Digest)
7789
if isDigest {
@@ -141,6 +153,7 @@ func unpackedResult(fsys fs.FS, bundle *rukpakv1alpha2.BundleDeployment, ref str
141153
Ref: ref,
142154
ImagePullSecretName: bundle.Spec.Source.Image.ImagePullSecretName,
143155
InsecureSkipTLSVerify: bundle.Spec.Source.Image.InsecureSkipTLSVerify,
156+
CertificateData: bundle.Spec.Source.Image.CertificateData,
144157
},
145158
},
146159
State: StateUnpacked,

pkg/source/unpacker.go

+1-11
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ package source
22

33
import (
44
"context"
5-
"crypto/tls"
6-
"crypto/x509"
75
"fmt"
86
"io/fs"
9-
"net/http"
107

118
"sigs.k8s.io/controller-runtime/pkg/manager"
129

@@ -103,14 +100,7 @@ func (s *unpacker) Cleanup(ctx context.Context, bundle *rukpakv1alpha2.BundleDep
103100
// source types.
104101
//
105102
// TODO: refactor NewDefaultUnpacker due to growing parameter list
106-
func NewDefaultUnpacker(mgr manager.Manager, namespace, cacheDir string, rootCAs *x509.CertPool) (Unpacker, error) {
107-
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
108-
if httpTransport.TLSClientConfig == nil {
109-
httpTransport.TLSClientConfig = &tls.Config{
110-
MinVersion: tls.VersionTLS12,
111-
}
112-
}
113-
httpTransport.TLSClientConfig.RootCAs = rootCAs
103+
func NewDefaultUnpacker(mgr manager.Manager, namespace, cacheDir string) (Unpacker, error) {
114104
return NewUnpacker(map[rukpakv1alpha2.SourceType]Unpacker{
115105
rukpakv1alpha2.SourceTypeImage: &ImageRegistry{
116106
BaseCachePath: cacheDir,

test/e2e/registry_provisioner_test.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
. "github.com/onsi/ginkgo/v2"
88
. "github.com/onsi/gomega"
99

10+
corev1 "k8s.io/api/core/v1"
1011
"k8s.io/apimachinery/pkg/api/meta"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/types"
1214
"sigs.k8s.io/controller-runtime/pkg/client"
1315

1416
rukpakv1alpha2 "github.com/operator-framework/rukpak/api/v1alpha2"
@@ -23,6 +25,19 @@ var _ = Describe("registry provisioner bundle", func() {
2325
)
2426
BeforeEach(func() {
2527
ctx = context.Background()
28+
var secret corev1.Secret
29+
30+
name := types.NamespacedName{
31+
Name: "rukpak-e2e-registry",
32+
Namespace: "rukpak-e2e",
33+
}
34+
err := c.Get(ctx, name, &secret)
35+
Expect(err).ToNot(HaveOccurred())
36+
Expect(secret.Type).To(Equal(corev1.SecretTypeTLS))
37+
data, ok := secret.Data["ca.crt"]
38+
Expect(ok).To(BeTrue())
39+
Expect(data).ToNot(BeNil())
40+
certData := string(data[:])
2641

2742
bd = &rukpakv1alpha2.BundleDeployment{
2843
ObjectMeta: metav1.ObjectMeta{
@@ -38,12 +53,13 @@ var _ = Describe("registry provisioner bundle", func() {
3853
Type: rukpakv1alpha2.SourceTypeImage,
3954
Image: &rukpakv1alpha2.ImageSource{
4055
Ref: fmt.Sprintf("%v/%v", ImageRepo, "registry:valid"),
41-
InsecureSkipTLSVerify: true,
56+
InsecureSkipTLSVerify: false,
57+
CertificateData: certData,
4258
},
4359
},
4460
},
4561
}
46-
err := c.Create(ctx, bd)
62+
err = c.Create(ctx, bd)
4763
Expect(err).ToNot(HaveOccurred())
4864
})
4965
AfterEach(func() {

test/tools/imageregistry/image-registry-secure.sh

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ spec:
4747
isCA: true
4848
dnsNames:
4949
- ${name}-secure.${namespace}.svc
50+
- ${name}-secure.${namespace}.svc.cluster.local
5051
privateKey:
5152
algorithm: ECDSA
5253
size: 256

test/tools/imageregistry/image-registry.sh

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ spec:
4747
isCA: true
4848
dnsNames:
4949
- ${name}.${namespace}.svc
50+
- ${name}.${namespace}.svc.cluster.local
5051
privateKey:
5152
algorithm: ECDSA
5253
size: 256

0 commit comments

Comments
 (0)