Skip to content

Commit 05adc2d

Browse files
authored
Limit GRPC Active streams (#33936)
Originally there was a default limit of 100 max concurrent streams, however in 2017 the GRPC team removed this default: grpc/grpc-go#1624 With the recent HTTP/2 Rapid Reset DoS, it is now being encouraged to re-introduce a limit. The fix requires this value to be configured in fact: grpc/grpc-go#6703
1 parent 0afe605 commit 05adc2d

File tree

6 files changed

+16
-2
lines changed

6 files changed

+16
-2
lines changed

lib/auth/grpcserver.go

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import (
7070
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
7171
"github.com/gravitational/teleport/lib/authz"
7272
"github.com/gravitational/teleport/lib/backend"
73+
"github.com/gravitational/teleport/lib/defaults"
7374
"github.com/gravitational/teleport/lib/events"
7475
"github.com/gravitational/teleport/lib/httplib"
7576
"github.com/gravitational/teleport/lib/joinserver"
@@ -5584,6 +5585,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
55845585
PermitWithoutStream: true,
55855586
},
55865587
),
5588+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
55875589
)
55885590
if err != nil {
55895591
return nil, trace.Wrap(err)

lib/defaults/defaults.go

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ const (
100100
// By default all users use /bin/bash
101101
DefaultShell = "/bin/bash"
102102

103+
// GRPCMaxConcurrentStreams is the max GRPC streams that can be active at a time. Once the limit is reached new
104+
// RPC calls will queue until capacity is available.
105+
GRPCMaxConcurrentStreams = 1000
106+
103107
// HTTPMaxIdleConns is the max idle connections across all hosts.
104108
HTTPMaxIdleConns = 2000
105109

lib/observability/tracing/collector.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func NewCollector(cfg CollectorConfig) (*Collector, error) {
7878
c := &Collector{
7979
grpcLn: grpcLn,
8080
httpLn: httpLn,
81-
grpcServer: grpc.NewServer(grpc.Creds(creds)),
81+
grpcServer: grpc.NewServer(grpc.Creds(creds), grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams)),
8282
tlsConfing: tlsConfig,
8383
exportedC: make(chan struct{}, 1),
8484
}

lib/proxy/peer/server.go

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/gravitational/teleport/api/metadata"
3232
"github.com/gravitational/teleport/api/utils/grpc/interceptors"
3333
"github.com/gravitational/teleport/lib/auth"
34+
"github.com/gravitational/teleport/lib/defaults"
3435
"github.com/gravitational/teleport/lib/utils"
3536
)
3637

@@ -141,6 +142,7 @@ func NewServer(config ServerConfig) (*Server, error) {
141142
MinTime: peerKeepAlive,
142143
PermitWithoutStream: true,
143144
}),
145+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
144146
)
145147

146148
proto.RegisterProxyServiceServer(server, config.service)

lib/service/service.go

+3
Original file line numberDiff line numberDiff line change
@@ -4283,6 +4283,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
42834283
otelgrpc.StreamServerInterceptor(),
42844284
),
42854285
grpc.Creds(creds),
4286+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
42864287
)
42874288

42884289
connMonitor, err := srv.NewConnectionMonitor(srv.ConnectionMonitorConfig{
@@ -5945,6 +5946,7 @@ func (process *TeleportProcess) initPublicGRPCServer(
59455946
// available for some time.
59465947
MaxConnectionIdle: 10 * time.Second,
59475948
}),
5949+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
59485950
)
59495951
joinServiceServer := joinserver.NewJoinServiceGRPCServer(conn.Client)
59505952
proto.RegisterJoinServiceServer(server, joinServiceServer)
@@ -6004,6 +6006,7 @@ func (process *TeleportProcess) initSecureGRPCServer(cfg initSecureGRPCServerCfg
60046006
grpc.ChainUnaryInterceptor(authMiddleware.UnaryInterceptors()...),
60056007
grpc.ChainStreamInterceptor(authMiddleware.StreamInterceptors()...),
60066008
grpc.Creds(creds),
6009+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
60076010
)
60086011

60096012
kubeServer, err := kubegrpc.New(kubegrpc.Config{

lib/teleterm/apiserver/apiserver.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"google.golang.org/grpc"
2424

2525
api "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/v1"
26+
"github.com/gravitational/teleport/lib/defaults"
2627
"github.com/gravitational/teleport/lib/teleterm/apiserver/handler"
2728
"github.com/gravitational/teleport/lib/utils"
2829
)
@@ -41,7 +42,9 @@ func New(cfg Config) (*APIServer, error) {
4142
}
4243

4344
grpcServer := grpc.NewServer(cfg.TshdServerCreds,
44-
grpc.ChainUnaryInterceptor(withErrorHandling(cfg.Log)))
45+
grpc.ChainUnaryInterceptor(withErrorHandling(cfg.Log)),
46+
grpc.MaxConcurrentStreams(defaults.GRPCMaxConcurrentStreams),
47+
)
4548

4649
// Create Terminal service.
4750

0 commit comments

Comments
 (0)