From 28168a7701c897a5b6af13bc472d6f5902e0a96d Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 25 Mar 2026 07:19:26 +0000 Subject: chore: remove arbitrary default max connections limit When NGIT_MAX_CONNECTIONS is unset the relay imposes no connection cap, deferring to OS fd limits and infrastructure controls. The option remains available for operators who want an explicit ceiling. --- .env.example | 4 ++-- CHANGELOG.md | 4 ++++ docs/reference/configuration.md | 10 +++++----- nix/module.nix | 10 ++++++---- src/config.rs | 9 ++++----- src/nostr/builder.rs | 13 ++++++++----- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/.env.example b/.env.example index 43f8f6f..24090ef 100644 --- a/.env.example +++ b/.env.example @@ -298,7 +298,7 @@ # ============================================================================ # Maximum total connections to the relay -# Prevents connection exhaustion DoS attacks +# When unset (default), connections are unlimited (defers to OS fd limits and infrastructure controls) # CLI: --max-connections -# Default: 4096 +# Default: unlimited # NGIT_MAX_CONNECTIONS=4096 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a1c2f60..217781c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Remove arbitrary default max connections limit; when `NGIT_MAX_CONNECTIONS` is unset the relay imposes no connection cap, deferring to OS fd limits and infrastructure controls + ## [1.0.1] - 2026-02-27 ### Fixed diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index a05aeee..bce1200 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -997,15 +997,15 @@ Event blacklist does **not** affect NIP-11 metadata: #### `NGIT_MAX_CONNECTIONS` -**Description:** Maximum total connections to the relay. Prevents connection exhaustion DoS attacks. +**Description:** Maximum total connections to the relay. When unset, connections are unlimited, deferring to OS fd limits and infrastructure-level controls. **Type:** Integer -**Default:** `4096` +**Default:** unlimited **Required:** No **Examples:** ```bash -# Default: 4096 connections +# Cap connections for a resource-constrained deployment NGIT_MAX_CONNECTIONS=4096 # Higher limit for large public relay @@ -1017,8 +1017,8 @@ NGIT_MAX_CONNECTIONS=100 **Notes:** -- Limits total concurrent WebSocket connections to the relay -- Prevents connection exhaustion attacks +- When unset, the relay imposes no connection limit (`Semaphore::MAX_PERMITS`); OS fd limits and infrastructure controls apply +- Set this only if you need an explicit cap; otherwise leave unset - Works in conjunction with per-connection limits (500 subscriptions, 60 events/min) - When limit is reached, new connections are rejected - Existing connections continue to work normally diff --git a/nix/module.nix b/nix/module.nix index 7354ab6..9693358 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -268,9 +268,10 @@ let }; maxConnections = mkOption { - type = types.int; - default = 4096; - description = "Maximum total connections to the relay"; + type = types.nullOr types.int; + default = null; + description = + "Maximum total connections to the relay (default: unlimited, defers to OS/infrastructure limits)"; }; user = mkOption { @@ -337,8 +338,9 @@ let NGIT_REPOSITORY_WHITELIST = concatStringsSep "," cfg.repositoryWhitelist; NGIT_REPOSITORY_BLACKLIST = concatStringsSep "," cfg.repositoryBlacklist; NGIT_EVENT_BLACKLIST = concatStringsSep "," cfg.eventBlacklist; - NGIT_MAX_CONNECTIONS = toString cfg.maxConnections; NGIT_LOG_LEVEL = cfg.logLevel; + } // optionalAttrs (cfg.maxConnections != null) { + NGIT_MAX_CONNECTIONS = toString cfg.maxConnections; } // optionalAttrs (cfg.relayName != null) { NGIT_RELAY_NAME = cfg.relayName; } // optionalAttrs (cfg.archiveReadOnly != null) { diff --git a/src/config.rs b/src/config.rs index 5c9303c..30e77ab 100644 --- a/src/config.rs +++ b/src/config.rs @@ -466,10 +466,9 @@ pub struct Config { #[arg(long, env = "NGIT_EVENT_BLACKLIST", default_value = "")] pub event_blacklist: String, - /// Maximum total connections to the relay (default: 4096) - /// Prevents connection exhaustion DoS attacks - #[arg(long, env = "NGIT_MAX_CONNECTIONS", default_value_t = 4096)] - pub max_connections: usize, + /// Maximum total connections to the relay (default: unlimited, defers to OS/infrastructure limits) + #[arg(long, env = "NGIT_MAX_CONNECTIONS")] + pub max_connections: Option, /// Log level for application logging #[arg(long, env = "NGIT_LOG_LEVEL", default_value = "info")] @@ -755,7 +754,7 @@ impl Config { repository_whitelist: String::new(), repository_blacklist: String::new(), event_blacklist: String::new(), - max_connections: 500, + max_connections: None, log_level: "debug".to_string(), } } diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs index 03132bf..02ba84b 100644 --- a/src/nostr/builder.rs +++ b/src/nostr/builder.rs @@ -736,7 +736,7 @@ pub async fn create_relay( let write_policy = Nip34WritePolicy::new(database.clone(), &git_data_path, purgatory, config.clone()); - let relay = LocalRelayBuilder::default() + let mut builder = LocalRelayBuilder::default() .database(database.clone()) .write_policy(write_policy.clone()) // Explicitly set rate limits (make defaults visible in code) @@ -744,10 +744,13 @@ pub async fn create_relay( .rate_limit(RateLimit { max_reqs: 500, // Max concurrent subscriptions per connection notes_per_minute: 60, // Max events per minute per connection - }) - // Total connection limit to prevent DoS attacks - .max_connections(config.max_connections) - .build(); + }); + + if let Some(max) = config.max_connections { + builder = builder.max_connections(max); + } + + let relay = builder.build(); tracing::info!( "Relay configured with GRASP-01 validation for domain: {}", -- cgit v1.2.3