diff --git a/example-config.toml b/example-config.toml index 2da968e..38beb76 100644 --- a/example-config.toml +++ b/example-config.toml @@ -7,6 +7,6 @@ http_port = 8080 grpc_port = 50051 log_level = "info" -rate_limit_per_second = 10 -rate_limit_burst = 100 +rate_limit_per_second = 100 +rate_limit_burst = 1000 acme_staging = false diff --git a/src/config.rs b/src/config.rs index 792df84..83b51cb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -29,11 +29,11 @@ fn default_adoption_timeout() -> u64 { } fn default_rate_limit_per_second() -> u64 { - 10 + 100 } fn default_rate_limit_burst() -> u32 { - 100 + 1000 } #[derive(Parser, Debug, Deserialize, Clone)] @@ -58,11 +58,15 @@ pub struct EnvConfig { #[serde(default = "default_log_level")] pub log_level: LevelFilter, - #[arg(long, env = "DEFGUARD_PROXY_RATELIMIT_PERSECOND", default_value_t = 10)] + #[arg( + long, + env = "DEFGUARD_PROXY_RATELIMIT_PERSECOND", + default_value_t = 100 + )] #[serde(default = "default_rate_limit_per_second")] pub rate_limit_per_second: u64, - #[arg(long, env = "DEFGUARD_PROXY_RATELIMIT_BURST", default_value_t = 100)] + #[arg(long, env = "DEFGUARD_PROXY_RATELIMIT_BURST", default_value_t = 1000)] #[serde(default = "default_rate_limit_burst")] pub rate_limit_burst: u32, diff --git a/src/http.rs b/src/http.rs index 624db3e..2319702 100644 --- a/src/http.rs +++ b/src/http.rs @@ -499,24 +499,30 @@ pub async fn run_server( None }; + // Collect all API routes into a separate router to scope the rate-limiter middleware + let mut api_router = Router::new().nest( + "/api/v1", + Router::new() + .nest("/enrollment", enrollment::router()) + .nest("/password-reset", password_reset::router()) + .nest("/client-mfa", desktop_client_mfa::router()) + .nest("/openid", openid_login::router()) + .route("/poll", post(polling::info)) + .route("/health", get(healthcheck)) + .route("/health-grpc", get(healthcheckgrpc)) + .route("/info", get(app_info)), + ); + if let Some(conf) = governor_conf { + api_router = api_router.layer(GovernorLayer::new(conf)); + } + // Build axum app let mut app = Router::new() .route("/", get(index)) .route("/{*path}", get(index)) .route("/fonts/{*path}", get(web_asset)) .route("/assets/{*path}", get(web_asset)) - .nest( - "/api/v1", - Router::new() - .nest("/enrollment", enrollment::router()) - .nest("/password-reset", password_reset::router()) - .nest("/client-mfa", desktop_client_mfa::router()) - .nest("/openid", openid_login::router()) - .route("/poll", post(polling::info)) - .route("/health", get(healthcheck)) - .route("/health-grpc", get(healthcheckgrpc)) - .route("/info", get(app_info)), - ) + .merge(api_router) .fallback_service(get(handle_404)) .layer(middleware::from_fn_with_state( shared_state.clone(), @@ -546,9 +552,7 @@ pub async fn run_server( }) .on_response(trace::DefaultOnResponse::new().level(Level::DEBUG)), ); - if let Some(conf) = governor_conf { - app = app.layer(GovernorLayer::new(conf)); - } + // Global request body size limit; all proxy endpoints have small payloads. app = app.layer(DefaultBodyLimit::max(REQUEST_BODY_LIMIT)); // Security headers and version are the outermost layers so that ALL short-circuit