[client] Validate and bound SSH session requests and channels (#8344)

This commit is contained in:
Viktor Liu
2026-10-26 11:35:02 +01:00
committed by GitHub
parent fdc51d6f95
commit 280aa188d8
7 changed files with 709 additions and 9 deletions
+18 -3
View File
@@ -58,6 +58,10 @@ const (
// the forwarded destination before rejecting the SSH channel.
const directTCPIPDialTimeout = 30 * time.Second
// defaultHandshakeTimeout bounds how long a connection may take to complete the SSH
// handshake and authentication before it is dropped.
const defaultHandshakeTimeout = 60 * time.Second
var (
ErrPrivilegedUserDisabled = errors.New(msgPrivilegedUserDisabled)
ErrUserNotFound = errors.New("user not found")
@@ -165,6 +169,7 @@ type Server struct {
allowRemotePortForwarding bool
allowRootLogin bool
allowSFTP bool
handshakeTimeout time.Duration
jwtEnabled bool
netstackNet *wgbackend.NetstackNet
@@ -227,6 +232,7 @@ func New(config *Config) *Server {
jwtEnabled: config.JWT != nil,
jwtConfig: config.JWT,
authorizer: sshauth.NewAuthorizer(),
handshakeTimeout: defaultHandshakeTimeout,
}
if config.Auth != nil {
@@ -884,15 +890,16 @@ func (s *Server) createSSHServer(addr net.Addr) (*ssh.Server, error) {
},
HostSigners: []ssh.Signer{},
ChannelHandlers: map[string]ssh.ChannelHandler{
"session": ssh.DefaultSessionHandler,
"session": s.sessionChannelHandler,
"direct-tcpip": s.directTCPIPHandler,
},
RequestHandlers: map[string]ssh.RequestHandler{
"tcpip-forward": s.tcpipForwardHandler,
"cancel-tcpip-forward": s.cancelTcpipForwardHandler,
},
ConnCallback: s.connectionValidator,
Version: serverVersion,
ConnCallback: s.connectionValidator,
HandshakeTimeout: s.handshakeTimeout,
Version: serverVersion,
}
if s.jwtEnabled {
@@ -934,6 +941,14 @@ func (s *Server) removeRemoteForwardListener(key forwardKey) bool {
func (s *Server) directTCPIPHandler(srv *ssh.Server, conn *cryptossh.ServerConn, newChan cryptossh.NewChannel, ctx ssh.Context) {
logger := s.getRequestLogger(ctx)
release, ok := acquireConnSlot(ctx, directTCPIPCountKey{}, maxDirectTCPIPPerConn)
if !ok {
logger.Warnf("local port forwarding denied: too many forwarded connections")
_ = newChan.Reject(cryptossh.ResourceShortage, "too many forwarded connections")
return
}
defer release()
var payload struct {
Host string
Port uint32