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.
This commit is contained in:
DanConwayDev
2026-03-25 07:19:26 +00:00
parent 05b7edb5f5
commit 28168a7701
6 changed files with 29 additions and 21 deletions
+2 -2
View File
@@ -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 <count>
# Default: 4096
# Default: unlimited
# NGIT_MAX_CONNECTIONS=4096
+4
View File
@@ -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
+5 -5
View File
@@ -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
+6 -4
View File
@@ -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) {
+4 -5
View File
@@ -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<usize>,
/// 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(),
}
}
+8 -5
View File
@@ -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: {}",