tailscale: Fix SSH auth banners never sent

This commit is contained in:
世界
2026-10-09 12:36:03 +08:00
parent 67fb235ee8
commit 80c1171410
+23 -20
View File
@@ -252,28 +252,25 @@ func (s *Server) Close() error {
}
func (s *Server) serverConfig(ctx gliderssh.Context) *gossh.ServerConfig {
var preAuthConn gossh.ServerPreAuthConn
config := &gossh.ServerConfig{
PreAuthConnCallback: func(conn gossh.ServerPreAuthConn) {
preAuthConn = conn
},
NoClientAuthCallback: func(conn gossh.ConnMetadata) (*gossh.Permissions, error) {
return s.authenticate(ctx, conn)
return s.authenticate(ctx, preAuthConn, conn)
},
PasswordCallback: func(conn gossh.ConnMetadata, password []byte) (*gossh.Permissions, error) {
return s.authenticate(ctx, conn)
return s.authenticate(ctx, preAuthConn, conn)
},
PublicKeyCallback: func(conn gossh.ConnMetadata, key gossh.PublicKey) (*gossh.Permissions, error) {
return s.authenticate(ctx, conn)
},
BannerCallback: func(conn gossh.ConnMetadata) string {
connInfo := s.connInfoFromContext(ctx)
if connInfo != nil && connInfo.action.Message != "" {
return connInfo.action.Message
}
return ""
return s.authenticate(ctx, preAuthConn, conn)
},
}
return config
}
func (s *Server) authenticate(ctx gliderssh.Context, conn gossh.ConnMetadata) (*gossh.Permissions, error) {
func (s *Server) authenticate(ctx gliderssh.Context, preAuthConn gossh.ServerPreAuthConn, conn gossh.ConnMetadata) (*gossh.Permissions, error) {
if s.connInfoFromContext(ctx) != nil {
return &gossh.Permissions{}, nil
}
@@ -298,12 +295,22 @@ func (s *Server) authenticate(ctx gliderssh.Context, conn gossh.ConnMetadata) (*
s.logger.Info("SSH auth rejected for ", userProfile.LoginName, " -> ", conn.User(), ": ", err)
return nil, &gossh.PartialSuccessError{}
}
if connInfo.action.Reject {
s.logger.Info("SSH auth rejected for ", userProfile.LoginName, " -> ", conn.User())
return nil, &gossh.PartialSuccessError{}
}
connInfo.action0 = connInfo.action
for hops := 0; connInfo.action.HoldAndDelegate != ""; hops++ {
for hops := 0; ; hops++ {
if connInfo.action.Message != "" {
err = preAuthConn.SendAuthBanner(connInfo.action.Message)
if err != nil {
s.logger.Info("SSH auth: send banner: ", err)
return nil, &gossh.PartialSuccessError{}
}
}
if connInfo.action.Reject {
s.logger.Info("SSH auth rejected for ", userProfile.LoginName, " -> ", conn.User())
return nil, &gossh.PartialSuccessError{}
}
if connInfo.action.HoldAndDelegate == "" {
break
}
if hops >= 10 {
s.logger.Info("SSH auth rejected: hold-and-delegate chain too long")
return nil, &gossh.PartialSuccessError{}
@@ -314,10 +321,6 @@ func (s *Server) authenticate(ctx gliderssh.Context, conn gossh.ConnMetadata) (*
return nil, &gossh.PartialSuccessError{}
}
connInfo.action = delegatedAction
if connInfo.action.Reject {
s.logger.Info("SSH auth rejected for ", userProfile.LoginName, " -> ", conn.User())
return nil, &gossh.PartialSuccessError{}
}
}
if !connInfo.action.Accept {
s.logger.Info("SSH auth rejected for ", userProfile.LoginName, " -> ", conn.User())