upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-14 11:42:05 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-14 13:40:03 +0000
commit50000cd9d47681390c3c45feef98fe51c7b79a0f (patch)
tree53ede8cb63ac2c5fe2321a6ecd9c87956537bbc7 /docs
parente3792b9abefd43b4594af2640ad4665c006fa3b0 (diff)
Add explicit rate limits and total connection limit
- Make RateLimit explicit in relay builder (500 subs, 60 events/min) - Add NGIT_MAX_CONNECTIONS config option (default: 500) - Update all 4 config locations (src, nix, docs, .env.example) - Fix documentation error: filter limit 5000→500 - Document Phase 2 deferral decision (per-IP enforcement) Addresses primary DoS vector (connection exhaustion) with minimal code. Per-IP rate limiting deferred until abuse detected in production. Related: issue ff38 (git endpoint throttling - separate concern)
Diffstat (limited to 'docs')
-rw-r--r--docs/explanation/defensive-measures.md211
-rw-r--r--docs/reference/configuration.md40
2 files changed, 251 insertions, 0 deletions
diff --git a/docs/explanation/defensive-measures.md b/docs/explanation/defensive-measures.md
new file mode 100644
index 0000000..f7abc30
--- /dev/null
+++ b/docs/explanation/defensive-measures.md
@@ -0,0 +1,211 @@
1# Defensive Measures & Rate Limiting
2
3This document describes the defensive measures implemented in ngit-grasp to protect against abuse, spam, and denial-of-service attacks.
4
5## Overview
6
7ngit-grasp employs multiple layers of defense:
8
91. **Connection & Subscription Limits** - Per-connection limits on subscriptions and event publishing
102. **Content Filtering** - Blacklist/whitelist system for repositories and event authors
113. **Event Validation** - Strict GRASP-01 protocol validation
124. **Relay Health Management** - Intelligent handling of problematic remote relays
13
14## What's Implemented
15
16### Per-Connection Rate Limits
17
18**Source:** Built-in to rust-nostr relay-builder
19
20- **Subscription limit:** Max 500 concurrent subscriptions per connection
21- **Event publishing limit:** Max 60 events per minute per connection
22- **Subscription ID length:** Max 250 characters
23- **Filter limit:** Max 500 results per query (default)
24
25These limits prevent individual connections from overwhelming the relay.
26
27### Per-IP Connection Monitoring
28
29**Source:** Custom ngit-grasp implementation
30**Location:** `src/metrics/connection.rs`
31
32- **Status:** Monitoring only (does NOT enforce limits)
33- Tracks connections per IP address internally
34- Flags IPs exceeding threshold (default: 10 connections)
35- **Privacy:** IP addresses never exposed in Prometheus metrics, only aggregate counts
36- Logs warnings when threshold exceeded
37
38**Future:** Could be extended to enforce per-IP connection limits.
39
40### Content Filtering (Blacklists/Whitelists)
41
42**Source:** Custom ngit-grasp implementation
43**Location:** `src/config.rs`, `src/nostr/builder.rs`
44
45**Event Blacklist:**
46- Block ALL events from specific authors (npubs)
47- Takes precedence over all other validation
48- Events never reach storage or purgatory
49
50**Repository Blacklist:**
51- Block specific repositories, developers, or identifiers
52- Takes precedence over whitelists
53- Three formats: `npub`, `npub/identifier`, `identifier`
54
55**Repository Whitelist:**
56- Curate which repositories are accepted (GRASP-01 mode)
57- Only accept announcements that both list your service AND match whitelist
58- Same three formats as blacklist
59
60**Archive Whitelist (GRASP-05):**
61- Mirror specific repositories even if they don't list your service
62- Same three formats as blacklist
63- Default: read-only mode when enabled
64
65**Privacy:** Blacklists not advertised in NIP-11 metadata.
66
67### Event Validation Plugin System
68
69**Source:** Built-in to rust-nostr relay-builder
70**Implementation:** Custom GRASP-01 validation in `src/nostr/builder.rs`
71
72- **WritePolicy trait:** Controls which events are accepted
73- **QueryPolicy trait:** Controls which queries are allowed (not currently used)
74- Access to client IP address for future per-IP rate limiting
75- Modular sub-policies for different event types (announcements, state events, PRs)
76
77### Relay Health Management (GRASP-02 Sync)
78
79**Source:** Custom ngit-grasp implementation
80**Location:** `src/sync/health.rs`
81
82**Exponential Backoff:**
83- Failed connections trigger increasing delays: 5s → 10s → 20s → ... → 1 hour max
84- Prevents hammering dead or slow relays
85
86**Naughty List:**
87- Tracks relays with persistent infrastructure issues (DNS, TLS, protocol errors)
88- Separate from normal connection failures
89- 12-hour expiration (configurable)
90- Reduces retry frequency for broken relays
91
92**Rate Limit Detection:**
93- Detects when remote relay rate limits us
94- Automatic 65-second cooldown
95- Prevents hammering relays that tell us to slow down
96
97**Domain Throttling (Git Data Fetching):**
98- Max 5 concurrent requests per domain
99- Max 30 requests per minute per domain
100- Respectful rate limiting when fetching missing git data
101
102## What's NOT Implemented
103
104### Per-IP Rate Limiting
105
106- **Per-IP connection limits:** Not enforced (only monitored)
107- **Per-IP subscription limits:** Not supported
108- **Per-IP event publishing limits:** Not supported
109
110**Why:** rust-nostr relay-builder tracks limits per WebSocket connection, not per IP address.
111
112**To implement:** Would require custom middleware/WritePolicy to aggregate across connections from the same IP.
113
114### Total Connection Limit
115
116**Status:** Supported by relay-builder but not currently configured in ngit-grasp.
117
118**To implement:** Add `max_connections(n)` to relay builder configuration.
119
120### Query Filtering
121
122**Status:** QueryPolicy trait available but not currently used.
123
124**Potential uses:** Rate limit queries per IP, block expensive queries, restrict access to certain event kinds.
125
126## Future Enhancements: Per-IP Rate Limiting (Deferred)
127
128### Decision: Defer Until Abuse Detected
129
130After comprehensive review (2026-01-14), we decided to defer per-IP rate limiting (Phase 2 & 3) until abuse patterns are detected in production.
131
132**Current protection (Phase 1):**
133- Per-connection limits: 500 subscriptions, 60 events/min
134- Total connection limit: 500 (configurable via `NGIT_MAX_CONNECTIONS`)
135- Connection monitoring: Tracks IPs, flags abuse at 10 connections
136- Content filtering: Event blacklist, repository blacklist/whitelist
137
138**Deferred features (Phase 2 & 3):**
139- Per-IP connection enforcement (reject after 10 connections)
140- Per-IP event rate limiting (reject after 100 events/min)
141
142### Rationale for Deferral
143
1441. **Config-only approach sufficient** - Total connection limit addresses primary DoS vector
1452. **Git relay context** - Developer users less likely to abuse than general public
1463. **Existing protections strong** - Per-connection limits + content filtering already robust
1474. **Data-driven approach** - Monitor ConnectionTracker metrics, implement if needed
1485. **Minimal maintenance** - Avoid custom rate limiting code until proven necessary
149
150### Implementation Path if Needed
151
152**Preferred approach:** Contribute to rust-nostr/relay-builder as PR
153- Propose IP-based rate limiting as optional feature
154- Let upstream maintain the code
155- Benefits entire Nostr ecosystem
156
157**Fallback:** Implement in ngit-grasp
158- Per-IP connection enforcement via actix middleware
159- Per-IP event rate limiting via token bucket in WritePolicy
160- See issue d6ee for detailed implementation plan
161
162### Monitoring for Abuse
163
164Watch these metrics to determine if Phase 2 is needed:
165- `ngit_connections_per_ip` - IPs exceeding 10 connections
166- `ngit_flagged_abusers` - IPs flagged by ConnectionTracker
167- Event publishing patterns from single IPs
168
169**Trigger for Phase 2:** If abuse detected for 2-4 weeks after Phase 1 deployment
170
171### Related Work
172
173**Git endpoint throttling:** Separate concern, tracked in issue ff38
174- Git HTTP endpoints have different threat model (bandwidth/CPU intensive)
175- Requires separate IP-based throttling (5 concurrent, 30/min per IP)
176- No interaction with relay code
177
178## Summary Table
179
180| Feature | Status | Enforced? | Configurable? |
181|---------|--------|-----------|---------------|
182| **Per-Connection Limits** |
183| Max subscriptions (500) | ✅ Active | Yes | No (relay-builder default) |
184| Event rate limit (60/min) | ✅ Active | Yes | No (relay-builder default) |
185| **Total Connection Limit** |
186| Max connections (500) | ✅ Active | Yes | Yes (`NGIT_MAX_CONNECTIONS`) |
187| **Per-IP Monitoring** |
188| Connection tracking | ✅ Active | No (monitor only) | Threshold only |
189| **Content Filtering** |
190| Event blacklist | ✅ Active | Yes | Yes |
191| Repository blacklist | ✅ Active | Yes | Yes |
192| Repository whitelist | ✅ Active | Yes (if set) | Yes |
193| Archive whitelist | ✅ Active | Yes (if set) | Yes |
194| **Event Validation** |
195| GRASP-01 validation | ✅ Active | Yes | Via WritePolicy |
196| **Relay Sync Protection** |
197| Exponential backoff | ✅ Active | Yes | Yes |
198| Naughty list | ✅ Active | Yes | Yes (12h default) |
199| Rate limit detection | ✅ Active | Yes | Automatic |
200| Domain throttling | ✅ Active | Yes | Hardcoded (5/30) |
201| **Deferred (Phase 2)** |
202| Per-IP connection limit | ⚠️ Deferred | No | - |
203| Per-IP rate limiting | ⚠️ Deferred | No | - |
204| Query filtering | ⚠️ Available | No | Not implemented |
205
206## Related Documentation
207
208- [Configuration Reference](../reference/configuration.md) - All config options for defensive features
209- [Monitoring Overview](monitoring.md) - Prometheus metrics for tracking abuse
210- [GRASP-05 Archive](grasp-05-archive.md) - Archive whitelist details
211- [Architecture](architecture.md) - Overall system design
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index 8b49297..c3001d3 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -925,6 +925,46 @@ Event blacklist does **not** affect NIP-11 metadata:
925 925
926--- 926---
927 927
928### Rate Limiting & DoS Protection
929
930#### `NGIT_MAX_CONNECTIONS`
931
932**Description:** Maximum total connections to the relay. Prevents connection exhaustion DoS attacks.
933**Type:** Integer
934**Default:** `500`
935**Required:** No
936
937**Examples:**
938
939```bash
940# Default: 500 connections
941NGIT_MAX_CONNECTIONS=500
942
943# Higher limit for large public relay
944NGIT_MAX_CONNECTIONS=1000
945
946# Lower limit for private relay
947NGIT_MAX_CONNECTIONS=100
948```
949
950**Notes:**
951
952- Limits total concurrent WebSocket connections to the relay
953- Prevents connection exhaustion attacks
954- Works in conjunction with per-connection limits (500 subscriptions, 60 events/min)
955- When limit is reached, new connections are rejected
956- Existing connections continue to work normally
957
958**Related Limits:**
959
960Per-connection limits (built-in to relay-builder, not configurable):
961- Max subscriptions per connection: 500
962- Max events per minute per connection: 60
963- Max subscription ID length: 250 characters
964- Max results per filter: 500
965
966---
967
928### Logging Configuration 968### Logging Configuration
929 969
930#### `RUST_LOG` 970#### `RUST_LOG`