upleb.uk

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

summaryrefslogtreecommitdiff
path: root/docs/explanation/defensive-measures.md
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-14 13:40:33 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-14 13:43:40 +0000
commit5897e4bccd41f1a9ebb01a11280cea929c93d2c0 (patch)
treecbe4d2447312b7bc7653bef874b6fb23d60a0ede /docs/explanation/defensive-measures.md
parent4c8f1813fada9ce2bfd371095b0721bff68173e3 (diff)
parent2821578202d1313c23c30a5dbae39548822e3c55 (diff)
Add defensive relay features with rate limiting and connection limits
Implement defensive measures to protect against DoS attacks: - Add explicit rate limits (500 subscriptions, 60 events/min per connection) - Add total connection limit (default: 500, configurable via NGIT_MAX_CONNECTIONS) - Update configuration across all 4 locations (src, nix, docs, .env.example) Per-IP rate limiting deferred until abuse is detected in production or implemented in rust-nostr relay-builder to benefit the entire Nostr ecosystem. Documentation added explaining the defensive features and rationale. Detailed analysis of other relay implementations preserved in commit history.
Diffstat (limited to 'docs/explanation/defensive-measures.md')
-rw-r--r--docs/explanation/defensive-measures.md165
1 files changed, 165 insertions, 0 deletions
diff --git a/docs/explanation/defensive-measures.md b/docs/explanation/defensive-measures.md
new file mode 100644
index 0000000..51f7278
--- /dev/null
+++ b/docs/explanation/defensive-measures.md
@@ -0,0 +1,165 @@
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**Note:** A point-in-time analysis of defensive measures in other Nostr relays (strfry, nostr-rs-relay, khatru) was conducted to inform these design decisions. The analysis examined connection limits, rate limiting approaches, and per-IP enforcement strategies across the ecosystem.
6
7## Overview
8
9ngit-grasp employs multiple layers of defense:
10
111. **Connection & Subscription Limits** - Per-connection limits on subscriptions and event publishing
122. **Content Filtering** - Blacklist/whitelist system for repositories and event authors
133. **Event Validation** - Strict GRASP-01 protocol validation
144. **Relay Health Management** - Intelligent handling of problematic remote relays
15
16## What's Implemented
17
18### Per-Connection Rate Limits
19
20**Source:** Built-in to rust-nostr relay-builder
21
22- **Subscription limit:** Max 500 concurrent subscriptions per connection
23- **Event publishing limit:** Max 60 events per minute per connection
24- **Subscription ID length:** Max 250 characters
25- **Filter limit:** Max 500 results per query (default)
26
27These limits prevent individual connections from overwhelming the relay.
28
29### Per-IP Connection Monitoring
30
31**Source:** Custom ngit-grasp implementation
32**Location:** `src/metrics/connection.rs`
33
34- **Status:** Monitoring only (does NOT enforce limits)
35- Tracks connections per IP address internally
36- Flags IPs exceeding threshold (default: 10 connections)
37- **Privacy:** IP addresses never exposed in Prometheus metrics, only aggregate counts
38- Logs warnings when threshold exceeded
39
40**Note on enforcement:** Per-IP connection limits are not built into rust-nostr relay-builder (tracks per WebSocket connection, not per IP). If abuse is detected via metrics, enforcement should be implemented as a PR to rust-nostr/relay-builder to benefit the entire Nostr ecosystem, rather than custom code in ngit-grasp.
41
42### Content Filtering (Blacklists/Whitelists)
43
44**Source:** Custom ngit-grasp implementation
45**Location:** `src/config.rs`, `src/nostr/builder.rs`
46
47**Event Blacklist:**
48- Block ALL events from specific authors (npubs)
49- Takes precedence over all other validation
50- Events never reach storage or purgatory
51
52**Repository Blacklist:**
53- Block specific repositories, developers, or identifiers
54- Takes precedence over whitelists
55- Three formats: `npub`, `npub/identifier`, `identifier`
56
57**Repository Whitelist:**
58- Curate which repositories are accepted (GRASP-01 mode)
59- Only accept announcements that both list your service AND match whitelist
60- Same three formats as blacklist
61
62**Archive Whitelist (GRASP-05):**
63- Mirror specific repositories even if they don't list your service
64- Same three formats as blacklist
65- Default: read-only mode when enabled
66
67**Privacy:** Blacklists not advertised in NIP-11 metadata.
68
69### Event Validation Plugin System
70
71**Source:** Built-in to rust-nostr relay-builder
72**Implementation:** Custom GRASP-01 validation in `src/nostr/builder.rs`
73
74- **WritePolicy trait:** Controls which events are accepted
75- **QueryPolicy trait:** Controls which queries are allowed (not currently used)
76- Access to client IP address for future per-IP rate limiting
77- Modular sub-policies for different event types (announcements, state events, PRs)
78
79### Relay Health Management (GRASP-02 Sync)
80
81**Source:** Custom ngit-grasp implementation
82**Location:** `src/sync/health.rs`
83
84**Exponential Backoff:**
85- Failed connections trigger increasing delays: 5s → 10s → 20s → ... → 1 hour max
86- Prevents hammering dead or slow relays
87
88**Naughty List:**
89- Tracks relays with persistent infrastructure issues (DNS, TLS, protocol errors)
90- Separate from normal connection failures
91- 12-hour expiration (configurable)
92- Reduces retry frequency for broken relays
93
94**Rate Limit Detection:**
95- Detects when remote relay rate limits us
96- Automatic 65-second cooldown
97- Prevents hammering relays that tell us to slow down
98
99**Domain Throttling (Git Data Fetching):**
100- Max 5 concurrent requests per domain
101- Max 30 requests per minute per domain
102- Respectful rate limiting when fetching missing git data
103
104## What's NOT Implemented
105
106### Per-IP Rate Limiting
107
108- **Per-IP connection limits:** Not enforced (only monitored)
109- **Per-IP subscription limits:** Not supported
110- **Per-IP event publishing limits:** Not supported
111
112**Why:** rust-nostr relay-builder tracks limits per WebSocket connection, not per IP address.
113
114**To implement:** Would require custom middleware/WritePolicy to aggregate across connections from the same IP.
115
116### Query Filtering
117
118**Status:** QueryPolicy trait available but not currently used.
119
120**Potential uses:** Rate limit queries per IP, block expensive queries, restrict access to certain event kinds.
121
122## Future Enhancements
123
124### Per-IP Rate Limiting
125
126Per-IP connection and event rate limiting were considered but deferred until abuse is detected in production. The current protections (per-connection limits, total connection limit, content filtering) are sufficient for the git relay use case.
127
128**Decision rationale:** The primary DoS vector is connection exhaustion, which is addressed by the total connection limit (`NGIT_MAX_CONNECTIONS`). Per-IP enforcement would require custom middleware in rust-nostr relay-builder (which currently tracks limits per WebSocket connection, not per IP). If abuse is detected via the per-IP monitoring metrics, enforcement should be implemented as a PR to rust-nostr/relay-builder to benefit the entire Nostr ecosystem.
129
130**Related:** Git endpoint throttling (issue ff38) is a separate concern with different requirements.
131
132## Summary Table
133
134| Feature | Status | Enforced? | Configurable? |
135|---------|--------|-----------|---------------|
136| **Per-Connection Limits** |
137| Max subscriptions (500) | ✅ Active | Yes | No (relay-builder default) |
138| Event rate limit (60/min) | ✅ Active | Yes | No (relay-builder default) |
139| **Total Connection Limit** |
140| Max connections (500) | ✅ Active | Yes | Yes (`NGIT_MAX_CONNECTIONS`) |
141| **Per-IP Monitoring** |
142| Connection tracking | ✅ Active | No (monitor only) | Threshold only |
143| **Content Filtering** |
144| Event blacklist | ✅ Active | Yes | Yes |
145| Repository blacklist | ✅ Active | Yes | Yes |
146| Repository whitelist | ✅ Active | Yes (if set) | Yes |
147| Archive whitelist | ✅ Active | Yes (if set) | Yes |
148| **Event Validation** |
149| GRASP-01 validation | ✅ Active | Yes | Via WritePolicy |
150| **Relay Sync Protection** |
151| Exponential backoff | ✅ Active | Yes | Yes |
152| Naughty list | ✅ Active | Yes | Yes (12h default) |
153| Rate limit detection | ✅ Active | Yes | Automatic |
154| Domain throttling | ✅ Active | Yes | Hardcoded (5/30) |
155| **Not Implemented** |
156| Per-IP connection limit | ⚠️ Deferred | No | - |
157| Per-IP rate limiting | ⚠️ Deferred | No | - |
158| Query filtering | ⚠️ Available | No | Not implemented |
159
160## Related Documentation
161
162- [Configuration Reference](../reference/configuration.md) - All config options for defensive features
163- [Monitoring Overview](monitoring.md) - Prometheus metrics for tracking abuse
164- [GRASP-05 Archive](grasp-05-archive.md) - Archive whitelist details
165- [Architecture](architecture.md) - Overall system design