Deploy KMS server image in Constellation

Add image pull secret for ghcr.io
This commit is contained in:
Christoph Meyer 2022-04-12 14:07:17 +00:00 committed by cm
parent 4dcb3aa062
commit db5468a886
22 changed files with 384 additions and 33 deletions

29
Dockerfile.kms Normal file
View File

@ -0,0 +1,29 @@
FROM ubuntu@sha256:7cc0576c7c0ec2384de5cbf245f41567e922aab1b075f3e8ad565f508032df17 as build
ENV DEBIAN_FRONTEND="noninteractive"
RUN apt-get update && apt-get install wget git -y
# Install Go
ARG GO_VER=1.18
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz
RUN tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && rm go${GO_VER}.linux-amd64.tar.gz
ENV PATH ${PATH}:/usr/local/go/bin
# Download go dependencies
WORKDIR /constellation/
COPY go.mod ./
COPY go.sum ./
RUN go mod download all
# Copy Repo
COPY . /constellation
RUN rm -rf ./hack/ go.work.sum go.work
# Build
RUN mkdir -p /constellation/build
WORKDIR /constellation/kms/server/cmd
RUN CGO_ENABLED=0 go build -o /constellation/build/kmsserver
FROM scratch as release
COPY --from=build /constellation/build/kmsserver /kmsserver
ENTRYPOINT ["/kmsserver"]

View File

@ -1,17 +0,0 @@
package cmd
const (
// wireguardAdminMTU is the MTU designated for the admin's WireGuard interface.
//
// WireGuard doesn't support Path MTU Discovery. Thus, its default MTU can be too high on some networks.
wireguardAdminMTU = 1300
// masterSecretLengthDefault is the default length in bytes for CLI generated master secrets.
masterSecretLengthDefault = 32
// masterSecretLengthMin is the minimal length in bytes for user provided master secrets.
masterSecretLengthMin = 16
// constellationNameLength is the maximum length of a Constellation's name.
constellationNameLength = 37
)

View File

@ -133,10 +133,10 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
if err != nil {
return createFlags{}, err
}
if len(name) > constellationNameLength {
if len(name) > constants.ConstellationNameLength {
return createFlags{}, fmt.Errorf(
"name for Constellation cluster too long, maximum length is %d, got %d: %s",
constellationNameLength, len(name), name,
constants.ConstellationNameLength, len(name), name,
)
}

View File

@ -103,7 +103,7 @@ func TestCreate(t *testing.T) {
provider: cloudprovider.GCP,
controllerCountFlag: intPtr(1),
workerCountFlag: intPtr(1),
nameFlag: strings.Repeat("a", constellationNameLength+1),
nameFlag: strings.Repeat("a", constants.ConstellationNameLength+1),
wantErr: true,
},
"flag control-plane-count invalid": {

View File

@ -153,7 +153,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
return err
}
vpnConfig, err := vpnHandler.Create(result.coordinatorPubKey, result.coordinatorPubIP, string(flags.userPrivKey), result.clientVpnIP, wireguardAdminMTU)
vpnConfig, err := vpnHandler.Create(result.coordinatorPubKey, result.coordinatorPubIP, string(flags.userPrivKey), result.clientVpnIP, constants.WireguardAdminMTU)
if err != nil {
return err
}
@ -374,14 +374,14 @@ func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename
if err != nil {
return nil, err
}
if len(decoded) < masterSecretLengthMin {
if len(decoded) < constants.MasterSecretLengthMin {
return nil, errors.New("provided master secret is smaller than the required minimum of 16 Bytes")
}
return decoded, nil
}
// No file given, generate a new secret, and save it to disk
masterSecret, err := util.GenerateRandomBytes(masterSecretLengthDefault)
masterSecret, err := util.GenerateRandomBytes(constants.MasterSecretLengthDefault)
if err != nil {
return nil, err
}

View File

@ -24,7 +24,7 @@ func (c *Core) GetK8SCertificateKey() (string, error) {
}
// InitCluster initializes the cluster, stores the join args, and returns the kubeconfig.
func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error) {
func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error) {
var nodeName string
var providerID string
var instance Instance
@ -99,6 +99,7 @@ func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountUR
CloudNodeManagerImage: c.cloudNodeManager.Image(),
CloudNodeManagerPath: c.cloudNodeManager.Path(),
CloudNodeManagerExtraArgs: c.cloudNodeManager.ExtraArgs(),
MasterSecret: masterSecret,
}); err != nil {
c.zaplogger.Error("Initializing cluster failed", zap.Error(err))
return nil, err

View File

@ -23,12 +23,15 @@ import (
func TestInitCluster(t *testing.T) {
someErr := errors.New("someErr")
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
testCases := map[string]struct {
cluster clusterStub
metadata stubMetadata
cloudControllerManager stubCloudControllerManager
cloudNodeManager stubCloudNodeManager
clusterAutoscaler stubClusterAutoscaler
masterSecret []byte
autoscalingNodeGroups []string
wantErr bool
wantInitClusterInput kubernetes.InitClusterInput
@ -38,6 +41,7 @@ func TestInitCluster(t *testing.T) {
kubeconfig: []byte("kubeconfig"),
},
autoscalingNodeGroups: []string{"someNodeGroup"},
masterSecret: testMS,
wantInitClusterInput: kubernetes.InitClusterInput{
APIServerAdvertiseIP: "10.118.0.1",
NodeIP: "10.118.0.1",
@ -45,6 +49,7 @@ func TestInitCluster(t *testing.T) {
SupportsCloudControllerManager: false,
SupportClusterAutoscaler: false,
AutoscalingNodeGroups: []string{"someNodeGroup"},
MasterSecret: testMS,
},
wantErr: false,
},
@ -52,6 +57,7 @@ func TestInitCluster(t *testing.T) {
cluster: clusterStub{
kubeconfig: []byte("kubeconfig"),
},
masterSecret: testMS,
metadata: stubMetadata{
selfRes: Instance{
Name: "some-name",
@ -66,6 +72,7 @@ func TestInitCluster(t *testing.T) {
ProviderID: "fake://providerid",
SupportsCloudControllerManager: false,
SupportClusterAutoscaler: false,
MasterSecret: testMS,
},
wantErr: false,
},
@ -87,6 +94,7 @@ func TestInitCluster(t *testing.T) {
nameRes: "some-name",
supportedRes: true,
},
masterSecret: testMS,
autoscalingNodeGroups: []string{"someNodeGroup"},
wantInitClusterInput: kubernetes.InitClusterInput{
APIServerAdvertiseIP: "10.118.0.1",
@ -96,6 +104,7 @@ func TestInitCluster(t *testing.T) {
SupportClusterAutoscaler: true,
AutoscalingCloudprovider: "some-name",
AutoscalingNodeGroups: []string{"someNodeGroup"},
MasterSecret: testMS,
},
wantErr: false,
},
@ -103,6 +112,7 @@ func TestInitCluster(t *testing.T) {
cluster: clusterStub{
kubeconfig: []byte("kubeconfig"),
},
masterSecret: testMS,
cloudControllerManager: stubCloudControllerManager{
supportedRes: true,
nameRes: "some-name",
@ -118,6 +128,7 @@ func TestInitCluster(t *testing.T) {
CloudControllerManagerName: "some-name",
CloudControllerManagerImage: "someImage",
CloudControllerManagerPath: "/some/path",
MasterSecret: testMS,
},
wantErr: false,
},
@ -141,6 +152,7 @@ func TestInitCluster(t *testing.T) {
cluster: clusterStub{
kubeconfig: []byte("kubeconfig"),
},
masterSecret: testMS,
metadata: stubMetadata{
signalRoleErr: errors.New("updating role fails"),
supportedRes: true,
@ -149,6 +161,7 @@ func TestInitCluster(t *testing.T) {
wantInitClusterInput: kubernetes.InitClusterInput{
APIServerAdvertiseIP: "10.118.0.1",
NodeIP: "10.118.0.1",
MasterSecret: testMS,
},
},
"getting kubeconfig fail detected": {
@ -176,7 +189,7 @@ func TestInitCluster(t *testing.T) {
core, err := NewCore(&stubVPN{}, &tc.cluster, &tc.metadata, &tc.cloudControllerManager, &tc.cloudNodeManager, &tc.clusterAutoscaler, nil, zapLogger, simulator.OpenSimulatedTPM, nil, file.NewHandler(fs), user.NewLinuxUserManagerFake(fs))
require.NoError(err)
kubeconfig, err := core.InitCluster(tc.autoscalingNodeGroups, "cloud-service-account-uri")
kubeconfig, err := core.InitCluster(tc.autoscalingNodeGroups, "cloud-service-account-uri", tc.masterSecret)
if tc.wantErr {
assert.Error(err)

View File

@ -32,4 +32,5 @@ type InitClusterInput struct {
CloudNodeManagerImage string
CloudNodeManagerPath string
CloudNodeManagerExtraArgs []string
MasterSecret []byte
}

View File

@ -0,0 +1,32 @@
package resources
import (
"encoding/base64"
"fmt"
"github.com/edgelesssys/constellation/internal/secrets"
k8s "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// NewImagePullSecret creates a new k8s.Secret from the config for authenticating when pulling images.
func NewImagePullSecret() k8s.Secret {
base64EncodedSecret := base64.StdEncoding.EncodeToString(
[]byte(fmt.Sprintf("%s:%s", secrets.PullSecretUser, secrets.PullSecretToken)),
)
pullSecretDockerCfgJson := fmt.Sprintf(`{"auths":{"ghcr.io":{"auth":"%s"}}}`, base64EncodedSecret)
return k8s.Secret{
TypeMeta: meta.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
},
ObjectMeta: meta.ObjectMeta{
Name: secrets.PullSecretName,
Namespace: "kube-system",
},
StringData: map[string]string{".dockerconfigjson": pullSecretDockerCfgJson},
Type: "kubernetes.io/dockerconfigjson",
}
}

View File

@ -0,0 +1,13 @@
package resources
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestImagePullSecret(t *testing.T) {
imgPullSec := NewImagePullSecret()
_, err := imgPullSec.Marshal()
assert.NoError(t, err)
}

View File

@ -0,0 +1,162 @@
package resources
import (
"github.com/edgelesssys/constellation/internal/constants"
"github.com/edgelesssys/constellation/internal/secrets"
apps "k8s.io/api/apps/v1"
k8s "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type kmsDeployment struct {
ServiceAccount k8s.ServiceAccount
ClusterRole rbac.ClusterRole
ClusterRoleBinding rbac.ClusterRoleBinding
Deployment apps.Deployment
MasterSecret k8s.Secret
ImagePullSecret k8s.Secret
}
const (
kmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:latest"
)
// NewKMSDeployment creates a new *kmsDeployment to use as the key management system inside Constellation.
func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
return &kmsDeployment{
ServiceAccount: k8s.ServiceAccount{
TypeMeta: meta.TypeMeta{
APIVersion: "v1",
Kind: "ServiceAccount",
},
ObjectMeta: meta.ObjectMeta{
Name: "kms",
Namespace: "kube-system",
},
},
ClusterRole: rbac.ClusterRole{
TypeMeta: meta.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRole",
},
ObjectMeta: meta.ObjectMeta{
Name: "kms",
Labels: map[string]string{
"k8s-app": "kms",
},
},
Rules: []rbac.PolicyRule{
{
APIGroups: []string{""},
Resources: []string{"secrets"},
Verbs: []string{"get"},
},
},
},
ClusterRoleBinding: rbac.ClusterRoleBinding{
TypeMeta: meta.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRoleBinding",
},
ObjectMeta: meta.ObjectMeta{
Name: "kms",
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "kms",
},
Subjects: []rbac.Subject{
{
Kind: "ServiceAccount",
Name: "kms",
Namespace: "kube-system",
},
},
},
Deployment: apps.Deployment{
TypeMeta: meta.TypeMeta{
APIVersion: "apps/v1",
Kind: "Deployment",
},
ObjectMeta: meta.ObjectMeta{
Labels: map[string]string{
"k8s-app": "kms",
},
Name: "kms",
Namespace: "kube-system",
},
Spec: apps.DeploymentSpec{
Selector: &meta.LabelSelector{
MatchLabels: map[string]string{
"k8s-app": "kms",
},
},
Template: k8s.PodTemplateSpec{
ObjectMeta: meta.ObjectMeta{
Labels: map[string]string{
"k8s-app": "kms",
},
},
Spec: k8s.PodSpec{
ImagePullSecrets: []k8s.LocalObjectReference{
{
Name: secrets.PullSecretName,
},
},
Volumes: []k8s.Volume{
{
Name: "mastersecret",
VolumeSource: k8s.VolumeSource{
Secret: &k8s.SecretVolumeSource{
SecretName: constants.ConstellationMasterSecretStoreName,
Items: []k8s.KeyToPath{
{
Key: constants.ConstellationMasterSecretKey,
Path: "constellation-mastersecret.base64",
},
},
},
},
},
},
ServiceAccountName: "kms",
Containers: []k8s.Container{
{
Name: "kms",
Image: kmsImage,
VolumeMounts: []k8s.VolumeMount{
{
Name: "mastersecret",
ReadOnly: true,
MountPath: "/constellation/",
},
},
},
},
},
},
},
},
MasterSecret: k8s.Secret{
TypeMeta: meta.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
},
ObjectMeta: meta.ObjectMeta{
Name: constants.ConstellationMasterSecretStoreName,
Namespace: "kube-system",
},
Data: map[string][]byte{
constants.ConstellationMasterSecretKey: masterSecret,
},
Type: "Opaque",
},
ImagePullSecret: NewImagePullSecret(),
}
}
func (c *kmsDeployment) Marshal() ([]byte, error) {
return MarshalK8SResources(c)
}

View File

@ -0,0 +1,22 @@
package resources
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestKMSMarshalUnmarshal(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
kmsDepl := NewKMSDeployment(testMS)
data, err := kmsDepl.Marshal()
require.NoError(err)
var recreated kmsDeployment
require.NoError(UnmarshalK8SResources(data, &recreated))
assert.Equal(kmsDepl, &recreated)
}

View File

@ -35,6 +35,7 @@ type ClusterUtil interface {
SetupAutoscaling(kubectl Client, clusterAutoscalerConfiguration resources.Marshaler, secrets resources.Marshaler) error
SetupCloudControllerManager(kubectl Client, cloudControllerManagerConfiguration resources.Marshaler, configMaps resources.Marshaler, secrets resources.Marshaler) error
SetupCloudNodeManager(kubectl Client, cloudNodeManagerConfiguration resources.Marshaler) error
SetupKMS(kubectl Client, kmsConfiguration resources.Marshaler) error
StartKubelet() error
RestartKubelet() error
GetControlPlaneJoinCertificateKey() (string, error)
@ -173,6 +174,14 @@ func (k *KubernetesUtil) JoinCluster(joinConfig []byte) error {
return nil
}
// SetupKMS deploys the KMS deployment.
func (k *KubernetesUtil) SetupKMS(kubectl Client, kmsConfiguration resources.Marshaler) error {
if err := kubectl.Apply(kmsConfiguration, true); err != nil {
return fmt.Errorf("applying KMS configuration failed: %w", err)
}
return nil
}
// StartKubelet enables and starts the kubelet systemd unit.
func (k *KubernetesUtil) StartKubelet() error {
ctx, cancel := context.WithTimeout(context.TODO(), kubeletStartTimeout)

View File

@ -79,6 +79,11 @@ func (k *KubeWrapper) InitCluster(in InitClusterInput) error {
return fmt.Errorf("setup of pod network failed: %w", err)
}
kms := resources.NewKMSDeployment(in.MasterSecret)
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
return fmt.Errorf("setup of kms failed: %w", err)
}
if in.SupportsCloudControllerManager {
cloudControllerManagerConfiguration := resources.NewDefaultCloudControllerManagerDeployment(
in.CloudControllerManagerName, in.CloudControllerManagerImage, in.CloudControllerManagerPath, in.CloudControllerManagerExtraArgs,

View File

@ -27,6 +27,7 @@ type stubClusterUtil struct {
setupAutoscalingError error
setupCloudControllerManagerError error
setupCloudNodeManagerError error
setupKMSError error
joinClusterErr error
startKubeletErr error
restartKubeletErr error
@ -58,6 +59,10 @@ func (s *stubClusterUtil) SetupCloudControllerManager(kubectl k8sapi.Client, clo
return s.setupCloudControllerManagerError
}
func (s *stubClusterUtil) SetupKMS(kubectl k8sapi.Client, kmsDeployment resources.Marshaler) error {
return s.setupKMSError
}
func (s *stubClusterUtil) SetupCloudNodeManager(kubectl k8sapi.Client, cloudNodeManagerConfiguration resources.Marshaler) error {
return s.setupCloudNodeManagerError
}

View File

@ -99,7 +99,7 @@ func (a *API) ActivateAsCoordinator(in *pubproto.ActivateAsCoordinatorRequest, s
}
logToCLI("Initializing Kubernetes ...")
kubeconfig, err := a.core.InitCluster(in.AutoscalingNodeGroups, in.CloudServiceAccountUri)
kubeconfig, err := a.core.InitCluster(in.AutoscalingNodeGroups, in.CloudServiceAccountUri, in.MasterSecret)
if err != nil {
return status.Errorf(codes.Internal, "initializing Kubernetes cluster failed: %v", err)
}

View File

@ -39,6 +39,6 @@ type Core interface {
CreateSSHUsers([]ssh.UserKey) error
InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error)
InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error)
JoinCluster(joinToken *kubeadm.BootstrapTokenDiscovery, certificateKey string, role role.Role) error
}

View File

@ -122,7 +122,7 @@ func (c *fakeCore) UpdatePeers(peers []peer.Peer) error {
return c.UpdatePeersErr
}
func (c *fakeCore) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error) {
func (c *fakeCore) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error) {
c.autoscalingNodeGroups = autoscalingNodeGroups
return c.kubeconfig, nil
}

View File

@ -1,5 +1,26 @@
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
github.com/google/cadvisor v0.43.0/go.mod h1:+RdMSbc3FVr5NYCD2dOEJy/LI0jYJ/0xJXkzWXEyiFQ=
github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
k8s.io/kubernetes v1.23.5/go.mod h1:avI3LUTUYZugxwh52KMVM7v9ZjB5gYJ6D3FIoZ1SHUo=
k8s.io/system-validators v1.6.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
k8s.io/utils v0.0.0-20220127004650-9b3446523e65/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=

View File

@ -7,6 +7,17 @@ package constants
import "time"
const (
//
// Constellation.
//
// ConstellationNameLength is the maximum length of a Constellation's name.
ConstellationNameLength = 37
// ConstellationMasterSecretStoreName is the name for the Constellation secrets in Kubernetes.
ConstellationMasterSecretStoreName = "constellation-mastersecret"
// ConstellationMasterSecretKey is the name of the key for master secret in the master secret store secret.
ConstellationMasterSecretKey = "mastersecret"
//
// Ports.
//
@ -35,8 +46,14 @@ const (
//
// Cryptographic constants.
//
StateDiskKeyLength = 32
StateDiskKeyLength = 32
// DerivedKeyLengthDefault is the default length in bytes for KMS derived keys.
DerivedKeyLengthDefault = 32
// MasterSecretLengthDefault is the default length in bytes for CLI generated master secrets.
MasterSecretLengthDefault = 32
// MasterSecretLengthMin is the minimal length in bytes for user provided master secrets.
MasterSecretLengthMin = 16
//
// CLI.
@ -52,6 +69,14 @@ const (
// KubernetesVersion installed by kubeadm.
KubernetesVersion = "stable-1.23"
KubernetesJoinTokenTTL = 15 * time.Minute
//
// VPN.
//
// WireguardAdminMTU is the MTU designated for the admin's WireGuard interface.
// WireGuard doesn't support Path MTU Discovery. Thus, its default MTU can be too high on some networks.
WireguardAdminMTU = 1300
)
// CliVersion is the version of the CLI. Left as a separate variable to allow override during build.

View File

@ -0,0 +1,7 @@
package secrets
const (
PullSecretName = "***REMOVED***"
PullSecretToken = "***REMOVED***"
PullSecretUser = "***REMOVED***"
)

View File

@ -2,14 +2,18 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"log"
"net"
"github.com/edgelesssys/constellation/coordinator/util"
"github.com/edgelesssys/constellation/internal/constants"
"github.com/edgelesssys/constellation/internal/file"
"github.com/edgelesssys/constellation/kms/server/kmsapi"
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
"github.com/edgelesssys/constellation/kms/server/setup"
"github.com/spf13/afero"
"go.uber.org/zap"
"google.golang.org/grpc"
@ -17,12 +21,12 @@ import (
func main() {
port := flag.String("p", "9000", "Port gRPC server listens on")
masterSecretPath := flag.String("master-secret", "/constellation/constellation-mastersecret.base64", "Path to the Constellation master secret")
flag.Parse()
// TODO: Get masterSecret from Constellation CLI / after activation from cluster.
masterKey, err := util.GenerateRandomBytes(32)
masterKey, err := readMainSecret(*masterSecretPath)
if err != nil {
log.Fatalf("Failed to generate key: %v", err)
log.Fatalf("Failed to read master secret: %v", err)
}
conKMS, err := setup.SetUpKMS(context.Background(), setup.NoStoreURI, setup.ClusterKMSURI)
@ -50,3 +54,22 @@ func main() {
log.Fatalf("Failed to serve: %s", err)
}
}
// readMainSecret reads the base64 encoded main secret file from specified path and returns the secret as bytes.
func readMainSecret(fileName string) ([]byte, error) {
if fileName == "" {
return nil, errors.New("no filename to master secret provided")
}
fileHandler := file.NewHandler(afero.NewOsFs())
secretBytes, err := fileHandler.Read(fileName)
if err != nil {
return nil, err
}
if len(secretBytes) < constants.MasterSecretLengthMin {
return nil, fmt.Errorf("provided master secret is smaller than the required minimum of %d bytes", constants.MasterSecretLengthMin)
}
return secretBytes, nil
}