Skip to content

Commit fbe9077

Browse files
committed
Add cli option for passing a second key
1 parent bb2f187 commit fbe9077

File tree

5 files changed

+56
-17
lines changed

5 files changed

+56
-17
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ make build-httpserver
2424
**Run pubkey server**
2525

2626
```bash
27-
go run ./cmd/httpserver/main.go [--listen-addr=127.0.0.1:8080] [--ssh-pubkey-file=/etc/ssh/ssh_host_ed25519_key.pub]
27+
go run ./cmd/httpserver/main.go [--listen-addr=127.0.0.1:8080] [--host-ssh-pubkey-file=/etc/ssh/ssh_host_ed25519_key.pub] [--container-ssh-pubkey-file=/path/to/container_key.pub]
2828
```
2929

30+
The server will serve both pubkeys (if provided) at the `/pubkey` endpoint, separated by a newline. The `--container-ssh-pubkey-file` flag is optional.
31+
3032
**Install dev dependencies**
3133

3234
```bash

cmd/httpserver/main.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ import (
1515

1616
var flags []cli.Flag = []cli.Flag{
1717
&cli.StringFlag{
18-
Name: "ssh-pubkey-file",
18+
Name: "host-ssh-pubkey-file",
1919
Value: "/etc/ssh/ssh_host_ed25519_key.pub",
20-
Usage: "path to file containing pubkey to serve",
20+
Usage: "path to file containing host pubkey to serve",
21+
},
22+
&cli.StringFlag{
23+
Name: "container-ssh-pubkey-file",
24+
Value: "",
25+
Usage: "path to file containing container pubkey to serve",
2126
},
2227
&cli.StringFlag{
2328
Name: "listen-addr",
@@ -99,7 +104,8 @@ func main() {
99104
ReadTimeout: 60 * time.Second,
100105
WriteTimeout: 30 * time.Second,
101106

102-
SSHPubkeyPath: cCtx.String("ssh-pubkey-file"),
107+
HostSSHPubkeyPath: cCtx.String("host-ssh-pubkey-file"),
108+
ContainerSSHPubkeyPath: cCtx.String("container-ssh-pubkey-file"),
103109
}
104110

105111
srv, err := httpserver.New(cfg)

httpserver/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (s *Server) handleGetPubkey(w http.ResponseWriter, r *http.Request) {
1818
m.Record(r.Context(), float64(time.Since(start).Microseconds()))
1919
}(time.Now())
2020

21-
_, err := w.Write(s.sshPubkey)
21+
_, err := w.Write(s.sshPubkeys)
2222
if err != nil {
2323
s.log.Error("could not serve pubkey", "err", err)
2424
}

httpserver/handler_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ func Test_Handlers_Healthcheck_Drain_Undrain(t *testing.T) {
2929

3030
//nolint: exhaustruct
3131
s, err := New(&HTTPServerConfig{
32-
DrainDuration: latency,
33-
ListenAddr: listenAddr,
34-
Log: getTestLogger(),
35-
SSHPubkeyPath: "./test_key.pub",
32+
DrainDuration: latency,
33+
ListenAddr: listenAddr,
34+
Log: getTestLogger(),
35+
HostSSHPubkeyPath: "./test_key.pub",
36+
ContainerSSHPubkeyPath: "./test_key.pub",
3637
})
3738
require.NoError(t, err)
3839

@@ -45,7 +46,10 @@ func Test_Handlers_Healthcheck_Drain_Undrain(t *testing.T) {
4546
data, err := io.ReadAll(resp.Body)
4647
require.NoError(t, err)
4748
require.Equal(t, http.StatusOK, resp.StatusCode)
48-
require.Equal(t, data, []byte("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFGGVd5nQewq0hETk2Tr/P7OZxTW/4aftdfh9/cAe7FC"))
49+
expectedKey := []byte("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFGGVd5nQewq0hETk2Tr/P7OZxTW/4aftdfh9/cAe7FC")
50+
expectedOutput := append(expectedKey, '\n')
51+
expectedOutput = append(expectedOutput, expectedKey...)
52+
require.Equal(t, data, expectedOutput)
4953
}
5054

5155
{ // Check health

httpserver/server.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,64 @@ type HTTPServerConfig struct {
2828
ReadTimeout time.Duration
2929
WriteTimeout time.Duration
3030

31-
SSHPubkeyPath string
31+
HostSSHPubkeyPath string
32+
ContainerSSHPubkeyPath string
3233
}
3334

3435
type Server struct {
3536
cfg *HTTPServerConfig
3637
isReady atomic.Bool
3738
log *slog.Logger
3839

39-
sshPubkey []byte
40+
sshPubkeys []byte
4041

4142
srv *http.Server
4243
metricsSrv *metrics.MetricsServer
4344
}
4445

46+
func readAndFormatPubkey(path string) ([]byte, error) {
47+
if path == "" {
48+
return nil, nil
49+
}
50+
51+
pubkey, err := os.ReadFile(path)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
// pubkey is in the form <type> <key> <host>. we want to drop the host
57+
return bytes.Join(bytes.Fields(pubkey)[0:2], []byte(" ")), nil
58+
}
59+
4560
func New(cfg *HTTPServerConfig) (srv *Server, err error) {
4661
metricsSrv, err := metrics.New(common.PackageName, cfg.MetricsAddr)
4762
if err != nil {
4863
return nil, err
4964
}
5065

51-
sshPubkey, err := os.ReadFile(cfg.SSHPubkeyPath)
52-
if err != nil {
66+
var pubkeys [][]byte
67+
68+
// Read host pubkey
69+
if hostPubkey, err := readAndFormatPubkey(cfg.HostSSHPubkeyPath); err != nil {
5370
return nil, err
71+
} else if hostPubkey != nil {
72+
pubkeys = append(pubkeys, hostPubkey)
5473
}
55-
// pubkey is in the form <type> <key> <host>. we want to drop the host
56-
sshPubkey = bytes.Join(bytes.Fields(sshPubkey)[0:2], []byte(" "))
74+
75+
// Read container pubkey
76+
if containerPubkey, err := readAndFormatPubkey(cfg.ContainerSSHPubkeyPath); err != nil {
77+
return nil, err
78+
} else if containerPubkey != nil {
79+
pubkeys = append(pubkeys, containerPubkey)
80+
}
81+
82+
// Combine pubkeys with newline
83+
combinedPubkeys := bytes.Join(pubkeys, []byte("\n"))
5784

5885
srv = &Server{
5986
cfg: cfg,
6087
log: cfg.Log,
61-
sshPubkey: sshPubkey,
88+
sshPubkeys: combinedPubkeys,
6289
srv: nil,
6390
metricsSrv: metricsSrv,
6491
}

0 commit comments

Comments
 (0)