8000 fix: use names not IDs for agent SSH key seed · coder/coder@c97ff5c · GitHub
[go: up one dir, main page]

Skip to content

Commit c97ff5c

Browse files
committed
fix: use names not IDs for agent SSH key seed
1 parent 3a0e8dd commit c97ff5c

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

agent/agent.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,9 +1186,9 @@ func (a *agent) createOrUpdateNetwork(manifestOK, networkOK *checkpoint) func(co
11861186
network := a.network
11871187
a.closeMutex.Unlock()
11881188
if network == nil {
1189-
keySeed, err := WorkspaceKeySeed(manifest.WorkspaceID, manifest.AgentName)
1189+
keySeed, err := SSHKeySeed(manifest.OwnerName, manifest.WorkspaceName, manifest.AgentName)
11901190
if err != nil {
1191-
return xerrors.Errorf("generate seed from workspace id: %w", err)
1191+
return xerrors.Errorf("generate SSH key seed: %w", err)
11921192
}
11931193
// use the graceful context here, because creating the tailnet is not itself tied to the
11941194
// agent API.
@@ -2068,12 +2068,31 @@ func PrometheusMetricsHandler(prometheusRegistry *prometheus.Registry, logger sl
20682068
})
20692069
}
20702070

2071-
// WorkspaceKeySeed converts a WorkspaceID UUID and agent name to an int64 hash.
2071+
// SSHKeySeed converts an owner userName, workspaceName and agentName to an int64 hash.
20722072
// This uses the FNV-1a hash algorithm which provides decent distribution and collision
20732073
// resistance for string inputs.
2074-
func WorkspaceKeySeed(workspaceID uuid.UUID, agentName string) (int64, error) {
2074+
//
2075+
// Why owner username, workspace name, and agent name? These are the components that are used in hostnames for the
2076+
// workspace over SSH, and so we want the workspace to have a stable key with respect to these. We don't use the
2077+
// respective UUIDs. The workspace UUID would be different if you delete and recreate a workspace with the same name.
2078+
// The agent UUID is regenerated on each build. Since Coder's Tailnet networking is handling the authentication, we
2079+
// should not be showing users warnings about host SSH keys.
2080+
func SSHKeySeed(userName, workspaceName, agentName string) (int64, error) {
20752081
h := fnv.New64a()
2076-
_, err := h.Write(workspaceID[:])
2082+
_, err := h.Write([]byte(userName))
2083+
if err != nil {
2084+
return 42, err
2085+
}
2086+
// null separators between strings so that (dog, foodstuff) is distinct from (dogfood, stuff)
2087+
_, err = h.Write([]byte{0})
2088+
if err != nil {
2089+
return 42, err
2090+
}
2091+
_, err = h.Write([]byte(workspaceName))
2092+
if err != nil {
2093+
return 42, err
2094+
}
2095+
_, err = h.Write([]byte{0})
20772096
if err != nil {
20782097
return 42, err
20792098
}

cli/ssh_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ func TestSSH(t *testing.T) {
479479
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
480480
defer cancel()
481481

482+
user, err := client.User(ctx, codersdk.Me)
483+
require.NoError(t, err)
484+
482485
inv, root := clitest.New(t, "ssh", "--stdio", workspace.Name)
483486
clitest.SetupConfig(t, client, root)
484487
inv.Stdin = clientOutput
@@ -490,7 +493,7 @@ func TestSSH(t *testing.T) {
490493
assert.NoError(t, err)
491494
})
492495

493-
keySeed, err := agent.WorkspaceKeySeed(workspace.ID, "dev")
496+
keySeed, err := agent.SSHKeySeed(user.Username, workspace.Name, "dev")
494497
assert.NoError(t, err)
495498

496499
signer, err := agentssh.CoderSigner(keySeed)

0 commit comments

Comments
 (0)
0