Skip to content

Commit

Permalink
Add kbs-init scripts to KBS docker image
Browse files Browse the repository at this point in the history
Signed-off-by: Jiale Zhang <[email protected]>
  • Loading branch information
訫剑 authored and jialez0 committed Jan 20, 2025
1 parent 7b93009 commit e482cb0
Show file tree
Hide file tree
Showing 10 changed files with 760 additions and 2 deletions.
4 changes: 2 additions & 2 deletions kbs/docker/coco-as-grpc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ RUN cd kbs && make AS_FEATURE=coco-as-grpc HTTPS_CRYPTO=${HTTPS_CRYPTO} POLICY_E

FROM ubuntu:22.04

LABEL org.opencontainers.image.source="https://github.com/confidential-containers/trustee/kbs"

COPY --from=builder /usr/local/bin/kbs /usr/local/bin/kbs
COPY --from=builder /usr/src/kbs/kbs/kbs-init/kbs-init /usr/local/bin/coco-kbs-init
COPY --from=builder /usr/src/kbs/kbs/kbs-init/kbs-watcher /usr/local/bin/coco-kbs-secret-watcher
5 changes: 5 additions & 0 deletions kbs/kbs-init/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


build:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o kbs-init main.go
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o kbs-watcher watcher/main.go
68 changes: 68 additions & 0 deletions kbs/kbs-init/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module gitlab.alibaba-inc.com/cos/coco-charts/dockerfiles/kbs-init

go 1.17

require (
k8s.io/api v0.28.2
k8s.io/apimachinery v0.28.2
k8s.io/client-go v0.28.2
sigs.k8s.io/controller-runtime v0.16.2
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.25.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/net v0.13.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/time v0.3.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.28.0 // indirect
k8s.io/component-base v0.28.1 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
214 changes: 214 additions & 0 deletions kbs/kbs-init/go.sum

Large diffs are not rendered by default.

Binary file added kbs/kbs-init/kbs-init
Binary file not shown.
Binary file added kbs/kbs-init/kbs-watcher
Binary file not shown.
191 changes: 191 additions & 0 deletions kbs/kbs-init/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package main

import (
"context"
"crypto/ed25519"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"log"
"math/big"
"os"
"os/signal"
"syscall"
"time"

"k8s.io/apimachinery/pkg/api/errors"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
)

type DSAKeyFormat struct {
Version int
P, Q, G, Y, X *big.Int
}

var (
namespace = ""
secretNameKeys = ""
secretNameAuth = ""
mountPath = ""
mountTimeout = time.Minute * 5
)

func init() {
flag.StringVar(&namespace, "namespace", "", "")
flag.StringVar(&secretNameKeys, "secret-name-keys", "kbs-auth-publickey", "")
flag.StringVar(&secretNameAuth, "secret-name-auth", "kbs-auth-keypair", "")
flag.StringVar(&mountPath, "mount-path", "/opt/confidential-containers/kbs/user-keys/public.pub", "")
flag.DurationVar(&mountTimeout, "mount-wait", time.Minute*5, "")
}

func main() {
flag.Parse()

if namespace == "" || secretNameKeys == "" || secretNameAuth == "" {
log.Println("both --namespace, --secret-name-keys and --secret-name-auth are required")
os.Exit(1)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

log.Println("start to init client")
client, err := newK8sClient()
if err != nil {
log.Fatalf("init k8s client failed: %+v", err)
}

log.Println("start to generate ed25519 keys")
pub, priv, err := newEd25519()
if err != nil {
log.Fatalf("generate ed25519 keys failed: %+v", err)
}

log.Println("start to ensure secrets")
if err := ensureSecrets(ctx, client, pub, priv); err != nil {
log.Fatalf("ensure secretes failed: %+v", err)
}

log.Printf("start to check mounted file with timeout(%s): %s", mountTimeout, mountPath)

if err := waitFileMounted(ctx); err != nil {
log.Fatalf("check mounted file (%s) failed: %+v", mountPath, err)
}
}

func waitFileMounted(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, mountTimeout)
defer cancel()

ticket := time.NewTicker(time.Second)
defer ticket.Stop()

var err error
loop:
for {
select {
case <-ctx.Done():
log.Println("canceled")
return ctx.Err()
case <-ticket.C:
err = checkMountFile()
if err == nil {
log.Println("the file is mounted")
break loop
}
}
}

return err
}

func checkMountFile() error {
_, err := os.Stat(mountPath)
return err
}

func ensureSecrets(ctx context.Context, client kubernetes.Interface, pub, priv []byte) error {
s1 := newSecret(pub, nil, secretNameKeys)
err1 := ensureSecret(ctx, client, s1)
if err1 != nil {
return fmt.Errorf("ensure secret %s failed: %+v", s1.Name, err1)
}
log.Printf("ensured secret %s", s1.Name)

s2 := newSecret(pub, priv, secretNameAuth)
err2 := ensureSecret(ctx, client, s2)
if err2 != nil {
return fmt.Errorf("ensure secret %s failed: %+v", s2.Name, err2)
}
log.Printf("ensured secret %s", s2.Name)

return nil
}

func ensureSecret(ctx context.Context, client kubernetes.Interface, s *corev1.Secret) error {
_, err := client.CoreV1().Secrets(namespace).Create(ctx, s, metav1.CreateOptions{})
if err != nil {
if errors.IsAlreadyExists(err) {
return nil
}
}
return err
}

func newSecret(pub, priv []byte, name string) *corev1.Secret {
s := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: map[string][]byte{
"public.pub": pub,
},
}
if len(priv) > 0 {
s.Data["private.key"] = priv
}

return s
}

func newEd25519() ([]byte, []byte, error) {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, err
}

return encodePublicKey(pub), encodePrivateKey(priv), nil
}

func encodePublicKey(key ed25519.PublicKey) []byte {
k, err := x509.MarshalPKIXPublicKey(key)
if err != nil {
return nil
}
b := &pem.Block{Type: "PUBLIC KEY", Bytes: k}
return pem.EncodeToMemory(b)
}

func encodePrivateKey(key ed25519.PrivateKey) []byte {
k, err := x509.MarshalPKCS8PrivateKey(key)
if err != nil {
return nil
}
b := &pem.Block{Type: "PRIVATE KEY", Bytes: k}
return pem.EncodeToMemory(b)
}

func newK8sClient() (kubernetes.Interface, error) {
config, err := ctrl.GetConfig()
if err != nil {
return nil, err
}

return kubernetes.NewForConfig(config)
}
Loading

0 comments on commit e482cb0

Please sign in to comment.