From 7db639ee914b28b1fcf8d1bd03032a3779b5d5b4 Mon Sep 17 00:00:00 2001 From: miampf Date: Thu, 3 Apr 2025 15:07:22 +0200 Subject: [PATCH] joinservice: prepared host key generation --- joinservice/internal/server/server.go | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/joinservice/internal/server/server.go b/joinservice/internal/server/server.go index e6fc82b95..e81d49bd5 100644 --- a/joinservice/internal/server/server.go +++ b/joinservice/internal/server/server.go @@ -10,6 +10,7 @@ package server import ( "context" "crypto/ed25519" + "crypto/rand" "fmt" "log/slog" "net" @@ -26,6 +27,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/peer" "google.golang.org/grpc/status" kubeadmv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" @@ -114,6 +116,41 @@ func (s *Server) IssueJoinTicket(ctx context.Context, req *joinproto.IssueJoinTi return nil, status.Errorf(codes.Internal, "generating ssh emergency CA key: %s", err) } + p, _ := peer.FromContext(ctx) + nodeIP := p.Addr.String() + hostKey, _, err := ed25519.GenerateKey(nil) + if err != nil { + log.With(slog.Any("error", err), slog.String("ip", nodeIP)).Error("Failed to generate host key for node") + return nil, status.Errorf(codes.Internal, "generating host key for node: %s", err) + } + hostKeyPub, err := ssh.NewPublicKey(hostKey) + if err != nil { + log.With(slog.Any("error", err), slog.String("ip", nodeIP)).Error("Failed to create public host key") + return nil, status.Errorf(codes.Internal, "generating public host key for node: %s", err) + } + + certificate := ssh.Certificate{ + CertType: ssh.HostCert, + Nonce: []byte{}, + ValidPrincipals: []string{p.Addr.String()}, + ValidAfter: uint64(time.Now().Unix()), + ValidBefore: ssh.CertTimeInfinity, + Reserved: []byte{}, + Key: hostKeyPub, + KeyId: "host_key", + SignatureKey: ca.PublicKey(), + Permissions: ssh.Permissions{ + CriticalOptions: map[string]string{}, + Extensions: map[string]string{}, + }, + } + if certificate.SignCert(rand.Reader, ca) != nil { + log.With(slog.Any("error", err), slog.String("ip", nodeIP)).Error("Failed to sign host key with ssh CA for node") + return nil, status.Errorf(codes.Internal, "signing host key for node with CA: %s", err) + } + log.Info("Generated host key and certificate for node", "ip", nodeIP) + // TODO: send cert and host key to node for installation + log.Info("Creating Kubernetes join token") kubeArgs, err := s.joinTokenGetter.GetJoinToken(constants.KubernetesJoinTokenTTL) if err != nil {