diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-02 09:34:11 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-02 09:34:11 +0200 |
| commit | d8d7e7c229e44bbd3a9d0ac268829e40d0704957 (patch) | |
| tree | de12262c0b98f41fed2dbb0fb99a0c83828a1f66 | |
| parent | 56a0081c9f8c0d0454712bbed410e6e5e16dd253 (diff) | |
server: enforce SSH handshake deadline
Task: 536d2467-2b3d-4b4a-a843-99c96d535cbb
| -rw-r--r-- | internal/server/server.go | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/internal/server/server.go b/internal/server/server.go index b4c4406..53aeec6 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -7,6 +7,7 @@ import ( "io" "net" "strings" + "time" "github.com/mimecast/dtail/internal/config" "github.com/mimecast/dtail/internal/io/dlog" @@ -18,6 +19,8 @@ import ( gossh "golang.org/x/crypto/ssh" ) +const sshHandshakeTimeout = 10 * time.Second + // Server is the main server data structure. type Server struct { cfg config.RuntimeConfig @@ -118,12 +121,26 @@ func (s *Server) listenerLoop(ctx context.Context, listener net.Listener) { func (s *Server) handleConnection(ctx context.Context, conn net.Conn) { dlog.Server.Info("Handling connection") + // Prevent slow clients from holding connections open indefinitely before SSH handshake completes. + if err := conn.SetDeadline(time.Now().Add(sshHandshakeTimeout)); err != nil { + dlog.Server.Error("Failed to set SSH handshake deadline", err) + conn.Close() + return + } + sshConn, chans, reqs, err := gossh.NewServerConn(conn, s.sshServerConfig) if err != nil { dlog.Server.Error("Something just happened", err) return } + // Handshake succeeded; remove deadline so active sessions are not cut off by the handshake timeout. + if err := conn.SetDeadline(time.Time{}); err != nil { + dlog.Server.Error("Failed to clear SSH handshake deadline", err) + sshConn.Close() + return + } + s.stats.incrementConnections() go gossh.DiscardRequests(reqs) for newChannel := range chans { |
