Merge commit from fork

Add configurable resource limits to prevent potential DoS vectors
via connection/stream exhaustion on gRPC, HTTPS, and HTTPS/3 servers.

New configuration plugins:
- grpc_server: configure max_streams, max_connections
- https: configure max_connections
- https3: configure max_streams

Changes:
- Use netutil.LimitListener for connection limiting
- Use gRPC MaxConcurrentStreams and message size limits
- Add QUIC MaxIncomingStreams for HTTPS/3 stream limiting
- Set secure defaults: 256 max streams, 200 max connections
- Setting any limit to 0 means unbounded/fallback to previous impl

Defaults are applied automatically when plugins are omitted from
config.

Includes tests and integration tests.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
Ville Vesilehto
2025-12-18 05:08:59 +02:00
committed by GitHub
parent 0fb05f225c
commit 0d8cbb1a6b
24 changed files with 1689 additions and 24 deletions

View File

@@ -21,6 +21,11 @@ import (
"github.com/quic-go/quic-go/http3"
)
const (
// DefaultHTTPS3MaxStreams is the default maximum number of concurrent QUIC streams per connection.
DefaultHTTPS3MaxStreams = 256
)
// ServerHTTPS3 represents a DNS-over-HTTP/3 server.
type ServerHTTPS3 struct {
*Server
@@ -29,6 +34,7 @@ type ServerHTTPS3 struct {
tlsConfig *tls.Config
quicConfig *quic.Config
validRequest func(*http.Request) bool
maxStreams int
}
// NewServerHTTPS3 builds the HTTP/3 (DoH3) server.
@@ -63,11 +69,20 @@ func NewServerHTTPS3(addr string, group []*Config) (*ServerHTTPS3, error) {
validator = func(r *http.Request) bool { return r.URL.Path == doh.Path }
}
// QUIC transport config
maxStreams := DefaultHTTPS3MaxStreams
if len(group) > 0 && group[0] != nil && group[0].MaxHTTPS3Streams != nil {
maxStreams = *group[0].MaxHTTPS3Streams
}
// QUIC transport config with stream limits (0 means use QUIC default)
qconf := &quic.Config{
MaxIdleTimeout: s.IdleTimeout,
Allow0RTT: true,
}
if maxStreams > 0 {
qconf.MaxIncomingStreams = int64(maxStreams)
qconf.MaxIncomingUniStreams = int64(maxStreams)
}
h3srv := &http3.Server{
Handler: nil, // set after constructing ServerHTTPS3
@@ -83,6 +98,7 @@ func NewServerHTTPS3(addr string, group []*Config) (*ServerHTTPS3, error) {
httpsServer: h3srv,
quicConfig: qconf,
validRequest: validator,
maxStreams: maxStreams,
}
h3srv.Handler = sh