@@ -3,11 +3,11 @@ package agentssh
33import (
44"bufio"
55"context"
6- "crypto/rand"
76"crypto/rsa"
87"errors"
98"fmt"
109"io"
10+ "math/rand"
1111"net"
1212"os"
1313"os/exec"
@@ -85,6 +85,10 @@ type Config struct {
8585X11DisplayOffset * int
8686// BlockFileTransfer restricts use of file transfer applications.
8787BlockFileTransfer bool
88+
89+ // RandomSeed is a random seed value exclusively used to generate a
90+ // deterministic SSH host key.
91+ RandomSeed int64
8892}
8993
9094type Server struct {
@@ -112,20 +116,25 @@ type Server struct {
112116}
113117
114118func NewServer (ctx context.Context ,logger slog.Logger ,prometheusRegistry * prometheus.Registry ,fs afero.Fs ,execer agentexec.Execer ,config * Config ) (* Server ,error ) {
119+ if config == nil {
120+ config = & Config {}
121+ }
122+
115123// Clients' should ignore the host key when connecting.
116124// The agent needs to authenticate with coderd to SSH,
117125// so SSH authentication doesn't improve security.
118- randomHostKey ,err := rsa .GenerateKey (rand .Reader ,2048 )
126+
127+ // Create a deterministic random source
128+ // nolint: gosec
129+ deterministicRand := rand .New (rand .NewSource (config .RandomSeed ))
130+ coderHostKey ,err := rsa .GenerateKey (deterministicRand ,2048 )
119131if err != nil {
120132return nil ,err
121133}
122- randomSigner ,err := gossh .NewSignerFromKey (randomHostKey )
134+ coderSigner ,err := gossh .NewSignerFromKey (coderHostKey )
123135if err != nil {
124136return nil ,err
125137}
126- if config == nil {
127- config = & Config {}
128- }
129138if config .X11DisplayOffset == nil {
130139offset := X11DefaultDisplayOffset
131140config .X11DisplayOffset = & offset
@@ -190,7 +199,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
190199slog .Error (err ))
191200},
192201Handler :s .sessionHandler ,
193- HostSigners : []ssh.Signer {randomSigner },
202+ HostSigners : []ssh.Signer {coderSigner },
194203LocalPortForwardingCallback :func (ctx ssh.Context ,destinationHost string ,destinationPort uint32 )bool {
195204// Allow local port forwarding all!
196205s .logger .Debug (ctx ,"local port forward" ,