diff --git a/cmd/dkl-local-server/bootv2.go b/cmd/dkl-local-server/bootv2.go index aaa1e04..5b34ff7 100644 --- a/cmd/dkl-local-server/bootv2.go +++ b/cmd/dkl-local-server/bootv2.go @@ -108,7 +108,7 @@ func buildInitrd(out io.Writer, ctx *renderContext) (err error) { cat.AppendDir("/etc/ssh", 0o700) // XXX do we want bootstrap-stage keys instead of the real host key? - for _, format := range []string{"rsa", "ecdsa", "ed25519"} { + for _, format := range sshKeyTypes { keyPath := "/etc/ssh/ssh_host_" + format + "_key" cat.AppendBytes(cfg.FileContent(keyPath), keyPath, 0o600) } diff --git a/cmd/dkl-local-server/ws-host.go b/cmd/dkl-local-server/ws-host.go index 20fa6df..2cea621 100644 --- a/cmd/dkl-local-server/ws-host.go +++ b/cmd/dkl-local-server/ws-host.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "io" "log" "net/http" @@ -13,6 +14,8 @@ import ( "novit.tech/direktil/local-server/pkg/mime" ) +var sshKeyTypes = []string{"rsa", "ecdsa", "ed25519"} + type AssetVariant struct { name string url string @@ -132,6 +135,9 @@ func (ws wsHost) register(rws *restful.WebService, alterRB func(*restful.RouteBu b("bootstrap.tar"). Produces(mime.TAR). Doc("Get the " + ws.hostDoc + "'s bootstrap seed archive"), + + // ssh + b("ssh.pub").Produces("text/plain").Doc("Get the " + ws.hostDoc + "'s ssh public keys"), } { alterRB(rb) rws.Route(rb) @@ -253,6 +259,9 @@ func renderHost(w http.ResponseWriter, r *http.Request, what string, host *local case "ipxe": err = renderIPXE(w, ctx) + case "ssh.pub": + err = renderSshPub(w, ctx) + default: http.NotFound(w, r) } @@ -262,3 +271,18 @@ func renderHost(w http.ResponseWriter, r *http.Request, what string, host *local http.Error(w, "", http.StatusServiceUnavailable) } } + +func renderSshPub(w http.ResponseWriter, ctx *renderContext) (err error) { + buf := new(bytes.Buffer) + + for _, t := range sshKeyTypes { + k, err := ctx.sshHostKeyPair(t) + if err != nil { + return err + } + buf.WriteString(k.Public) + } + + _, err = w.Write(buf.Bytes()) + return +}