diff --git a/.spelling b/.spelling index d84d1aa2f885..677a9a15fd8b 100644 --- a/.spelling +++ b/.spelling @@ -64,6 +64,7 @@ InsideBoard Invocators IAM-based Istio +IPs Jemison JetBrains KNative @@ -235,4 +236,4 @@ CronWorkflow CronWorkflows maxFailures maxSuccess -gitops \ No newline at end of file +gitops diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 30365feb53fd..7e17a0bf2443 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -122,6 +122,7 @@ data: | `DISABLE_VALUE_LIST_RETRIEVAL_KEY_PATTERN` | `string` | `""` | Disable the retrieval of the list of label values for keys based on this regular expression. | | `FIRST_TIME_USER_MODAL` | `bool` | `true` | Show this modal. | | `FEEDBACK_MODAL` | `bool` | `true` | Show this modal. | +| `IP_KEY_FUNC_HEADERS` | `string` | `""` | List of comma separated request headers containing IPs to use for rate limiting. For example, "X-Forwarded-For,X-Real-IP". By default, uses the request's remote IP address. | | `NEW_VERSION_MODAL` | `bool` | `true` | Show this modal. | | `POD_NAMES` | `string` | `v2` | Whether to have pod names contain the template name (v2) or be the node id (v1) - should be set the same for Controller | | `GRPC_MESSAGE_SIZE` | `string` | `104857600` | Use different GRPC Max message size for Server (supporting huge workflows). | diff --git a/server/apiserver/argoserver.go b/server/apiserver/argoserver.go index 03507e05f078..9370bffed562 100644 --- a/server/apiserver/argoserver.go +++ b/server/apiserver/argoserver.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "os" + "strings" "time" "github.com/gorilla/handlers" @@ -325,8 +326,13 @@ func (as *argoServer) newGRPCServer(instanceIDService instanceid.Service, offloa // using grpc-gateway as a proxy to the gRPC server. func (as *argoServer) newHTTPServer(ctx context.Context, port int, artifactServer *artifacts.ArtifactServer) *http.Server { endpoint := fmt.Sprintf("localhost:%d", port) + ipKeyFunc := httplimit.IPKeyFunc() + if ipKeyFuncHeadersStr := env.GetString("IP_KEY_FUNC_HEADERS", ""); ipKeyFuncHeadersStr != "" { + ipKeyFuncHeaders := strings.Split(ipKeyFuncHeadersStr, ",") + ipKeyFunc = httplimit.IPKeyFunc(ipKeyFuncHeaders...) + } - ratelimit_middleware, err := httplimit.NewMiddleware(as.apiRateLimiter, httplimit.IPKeyFunc()) + rateLimitMiddleware, err := httplimit.NewMiddleware(as.apiRateLimiter, ipKeyFunc) if err != nil { log.Fatal(err) } @@ -334,7 +340,7 @@ func (as *argoServer) newHTTPServer(ctx context.Context, port int, artifactServe mux := http.NewServeMux() httpServer := http.Server{ Addr: endpoint, - Handler: ratelimit_middleware.Handle(accesslog.Interceptor(mux)), + Handler: rateLimitMiddleware.Handle(accesslog.Interceptor(mux)), TLSConfig: as.tlsConfig, } dialOpts := []grpc.DialOption{