mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add flag to disaable all rate limits (#5570)
This commit is contained in:
@ -82,24 +82,20 @@ type Options struct {
|
||||
Auditor audit.Auditor
|
||||
AgentConnectionUpdateFrequency time.Duration
|
||||
AgentInactiveDisconnectTimeout time.Duration
|
||||
// APIRateLimit is the minutely throughput rate limit per user or ip.
|
||||
// Setting a rate limit <0 will disable the rate limiter across the entire
|
||||
// app. Specific routes may have their own limiters.
|
||||
APIRateLimit int
|
||||
AWSCertificates awsidentity.Certificates
|
||||
Authorizer rbac.Authorizer
|
||||
AzureCertificates x509.VerifyOptions
|
||||
GoogleTokenValidator *idtoken.Validator
|
||||
GithubOAuth2Config *GithubOAuth2Config
|
||||
OIDCConfig *OIDCConfig
|
||||
PrometheusRegistry *prometheus.Registry
|
||||
SecureAuthCookie bool
|
||||
SSHKeygenAlgorithm gitsshkey.Algorithm
|
||||
Telemetry telemetry.Reporter
|
||||
TracerProvider trace.TracerProvider
|
||||
GitAuthConfigs []*gitauth.Config
|
||||
RealIPConfig *httpmw.RealIPConfig
|
||||
TrialGenerator func(ctx context.Context, email string) error
|
||||
AWSCertificates awsidentity.Certificates
|
||||
Authorizer rbac.Authorizer
|
||||
AzureCertificates x509.VerifyOptions
|
||||
GoogleTokenValidator *idtoken.Validator
|
||||
GithubOAuth2Config *GithubOAuth2Config
|
||||
OIDCConfig *OIDCConfig
|
||||
PrometheusRegistry *prometheus.Registry
|
||||
SecureAuthCookie bool
|
||||
SSHKeygenAlgorithm gitsshkey.Algorithm
|
||||
Telemetry telemetry.Reporter
|
||||
TracerProvider trace.TracerProvider
|
||||
GitAuthConfigs []*gitauth.Config
|
||||
RealIPConfig *httpmw.RealIPConfig
|
||||
TrialGenerator func(ctx context.Context, email string) error
|
||||
// TLSCertificates is used to mesh DERP servers securely.
|
||||
TLSCertificates []tls.Certificate
|
||||
TailnetCoordinator tailnet.Coordinator
|
||||
@ -107,6 +103,13 @@ type Options struct {
|
||||
DERPMap *tailcfg.DERPMap
|
||||
SwaggerEndpoint bool
|
||||
|
||||
// APIRateLimit is the minutely throughput rate limit per user or ip.
|
||||
// Setting a rate limit <0 will disable the rate limiter across the entire
|
||||
// app. Some specific routes have their own configurable rate limits.
|
||||
APIRateLimit int
|
||||
LoginRateLimit int
|
||||
FilesRateLimit int
|
||||
|
||||
MetricsCacheRefreshInterval time.Duration
|
||||
AgentStatsRefreshInterval time.Duration
|
||||
Experimental bool
|
||||
@ -157,6 +160,12 @@ func New(options *Options) *API {
|
||||
if options.APIRateLimit == 0 {
|
||||
options.APIRateLimit = 512
|
||||
}
|
||||
if options.LoginRateLimit == 0 {
|
||||
options.LoginRateLimit = 60
|
||||
}
|
||||
if options.FilesRateLimit == 0 {
|
||||
options.FilesRateLimit = 12
|
||||
}
|
||||
if options.Authorizer == nil {
|
||||
options.Authorizer = rbac.NewAuthorizer()
|
||||
}
|
||||
@ -230,6 +239,10 @@ func New(options *Options) *API {
|
||||
Optional: false,
|
||||
})
|
||||
|
||||
// API rate limit middleware. The counter is local and not shared between
|
||||
// replicas or instances of this middleware.
|
||||
apiRateLimiter := httpmw.RateLimit(options.APIRateLimit, time.Minute)
|
||||
|
||||
r.Use(
|
||||
httpmw.Recover(api.Logger),
|
||||
tracing.StatusWriterMiddleware,
|
||||
@ -241,8 +254,8 @@ func New(options *Options) *API {
|
||||
// handleSubdomainApplications checks if the first subdomain is a valid
|
||||
// app URL. If it is, it will serve that application.
|
||||
api.handleSubdomainApplications(
|
||||
apiRateLimiter,
|
||||
// Middleware to impose on the served application.
|
||||
httpmw.RateLimit(options.APIRateLimit, time.Minute),
|
||||
httpmw.ExtractAPIKey(httpmw.ExtractAPIKeyConfig{
|
||||
DB: options.Database,
|
||||
OAuth2Configs: oauthConfigs,
|
||||
@ -268,7 +281,7 @@ func New(options *Options) *API {
|
||||
|
||||
apps := func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.RateLimit(options.APIRateLimit, time.Minute),
|
||||
apiRateLimiter,
|
||||
httpmw.ExtractAPIKey(httpmw.ExtractAPIKeyConfig{
|
||||
DB: options.Database,
|
||||
OAuth2Configs: oauthConfigs,
|
||||
@ -315,8 +328,9 @@ func New(options *Options) *API {
|
||||
|
||||
r.NotFound(func(rw http.ResponseWriter, r *http.Request) { httpapi.RouteNotFound(rw) })
|
||||
r.Use(
|
||||
// Specific routes can specify smaller limits.
|
||||
httpmw.RateLimit(options.APIRateLimit, time.Minute),
|
||||
// Specific routes can specify different limits, but every rate
|
||||
// limit must be configurable by the admin.
|
||||
apiRateLimiter,
|
||||
)
|
||||
r.Get("/", apiRoot)
|
||||
// All CSP errors will be logged
|
||||
@ -339,9 +353,7 @@ func New(options *Options) *API {
|
||||
r.Route("/files", func(r chi.Router) {
|
||||
r.Use(
|
||||
apiKeyMiddleware,
|
||||
// This number is arbitrary, but reading/writing
|
||||
// file content is expensive so it should be small.
|
||||
httpmw.RateLimit(12, time.Minute),
|
||||
httpmw.RateLimit(options.FilesRateLimit, time.Minute),
|
||||
)
|
||||
r.Get("/{fileID}", api.fileByID)
|
||||
r.Post("/", api.postFile)
|
||||
@ -426,25 +438,25 @@ func New(options *Options) *API {
|
||||
r.Route("/users", func(r chi.Router) {
|
||||
r.Get("/first", api.firstUser)
|
||||
r.Post("/first", api.postFirstUser)
|
||||
r.Group(func(r chi.Router) {
|
||||
// We use a tight limit for password login to protect
|
||||
// against audit-log write DoS, pbkdf2 DoS, and simple
|
||||
// brute-force attacks.
|
||||
//
|
||||
// Making this too small can break tests.
|
||||
r.Use(httpmw.RateLimit(60, time.Minute))
|
||||
r.Post("/login", api.postLogin)
|
||||
})
|
||||
r.Get("/authmethods", api.userAuthMethods)
|
||||
r.Route("/oauth2", func(r chi.Router) {
|
||||
r.Route("/github", func(r chi.Router) {
|
||||
r.Use(httpmw.ExtractOAuth2(options.GithubOAuth2Config, options.HTTPClient))
|
||||
r.Get("/callback", api.userOAuth2Github)
|
||||
r.Group(func(r chi.Router) {
|
||||
// We use a tight limit for password login to protect against
|
||||
// audit-log write DoS, pbkdf2 DoS, and simple brute-force
|
||||
// attacks.
|
||||
//
|
||||
// This value is intentionally increased during tests.
|
||||
r.Use(httpmw.RateLimit(options.LoginRateLimit, time.Minute))
|
||||
r.Post("/login", api.postLogin)
|
||||
r.Route("/oauth2", func(r chi.Router) {
|
||||
r.Route("/github", func(r chi.Router) {
|
||||
r.Use(httpmw.ExtractOAuth2(options.GithubOAuth2Config, options.HTTPClient))
|
||||
r.Get("/callback", api.userOAuth2Github)
|
||||
})
|
||||
})
|
||||
r.Route("/oidc/callback", func(r chi.Router) {
|
||||
r.Use(httpmw.ExtractOAuth2(options.OIDCConfig, options.HTTPClient))
|
||||
r.Get("/", api.userOIDC)
|
||||
})
|
||||
})
|
||||
r.Route("/oidc/callback", func(r chi.Router) {
|
||||
r.Use(httpmw.ExtractOAuth2(options.OIDCConfig, options.HTTPClient))
|
||||
r.Get("/", api.userOIDC)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(
|
||||
|
Reference in New Issue
Block a user