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:20 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-14 13:40:20 +0000
commit2821578202d1313c23c30a5dbae39548822e3c55 (patch)
treecbe4d2447312b7bc7653bef874b6fb23d60a0ede /docs/explanation/defensive-measures.md
parent50000cd9d47681390c3c45feef98fe51c7b79a0f (diff)
docs: add defensive measures explanation
Add comprehensive documentation explaining the defensive features implemented in ngit-grasp. The detailed analysis of other relay implementations is now preserved in commit history (e3792b9).
Diffstat (limited to 'docs/explanation/defensive-measures.md')
-rw-r--r--docs/explanation/defensive-measures.md64
1 files changed, 9 insertions, 55 deletions
diff --git a/docs/explanation/defensive-measures.md b/docs/explanation/defensive-measures.md
index f7abc30..51f7278 100644
--- a/docs/explanation/defensive-measures.md
+++ b/docs/explanation/defensive-measures.md
@@ -2,6 +2,8 @@
2 2
3This document describes the defensive measures implemented in ngit-grasp to protect against abuse, spam, and denial-of-service attacks. 3This document describes the defensive measures implemented in ngit-grasp to protect against abuse, spam, and denial-of-service attacks.
4 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
5## Overview 7## Overview
6 8
7ngit-grasp employs multiple layers of defense: 9ngit-grasp employs multiple layers of defense:
@@ -35,7 +37,7 @@ These limits prevent individual connections from overwhelming the relay.
35- **Privacy:** IP addresses never exposed in Prometheus metrics, only aggregate counts 37- **Privacy:** IP addresses never exposed in Prometheus metrics, only aggregate counts
36- Logs warnings when threshold exceeded 38- Logs warnings when threshold exceeded
37 39
38**Future:** Could be extended to enforce per-IP connection limits. 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.
39 41
40### Content Filtering (Blacklists/Whitelists) 42### Content Filtering (Blacklists/Whitelists)
41 43
@@ -111,69 +113,21 @@ These limits prevent individual connections from overwhelming the relay.
111 113
112**To implement:** Would require custom middleware/WritePolicy to aggregate across connections from the same IP. 114**To implement:** Would require custom middleware/WritePolicy to aggregate across connections from the same IP.
113 115
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 116### Query Filtering
121 117
122**Status:** QueryPolicy trait available but not currently used. 118**Status:** QueryPolicy trait available but not currently used.
123 119
124**Potential uses:** Rate limit queries per IP, block expensive queries, restrict access to certain event kinds. 120**Potential uses:** Rate limit queries per IP, block expensive queries, restrict access to certain event kinds.
125 121
126## Future Enhancements: Per-IP Rate Limiting (Deferred) 122## Future Enhancements
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 123
142### Rationale for Deferral 124### Per-IP Rate Limiting
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 125
169**Trigger for Phase 2:** If abuse detected for 2-4 weeks after Phase 1 deployment 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.
170 127
171### Related Work 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.
172 129
173**Git endpoint throttling:** Separate concern, tracked in issue ff38 130**Related:** Git endpoint throttling (issue ff38) is a separate concern with different requirements.
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 131
178## Summary Table 132## Summary Table
179 133
@@ -198,7 +152,7 @@ Watch these metrics to determine if Phase 2 is needed:
198| Naughty list | ✅ Active | Yes | Yes (12h default) | 152| Naughty list | ✅ Active | Yes | Yes (12h default) |
199| Rate limit detection | ✅ Active | Yes | Automatic | 153| Rate limit detection | ✅ Active | Yes | Automatic |
200| Domain throttling | ✅ Active | Yes | Hardcoded (5/30) | 154| Domain throttling | ✅ Active | Yes | Hardcoded (5/30) |
201| **Deferred (Phase 2)** | 155| **Not Implemented** |
202| Per-IP connection limit | ⚠️ Deferred | No | - | 156| Per-IP connection limit | ⚠️ Deferred | No | - |
203| Per-IP rate limiting | ⚠️ Deferred | No | - | 157| Per-IP rate limiting | ⚠️ Deferred | No | - |
204| Query filtering | ⚠️ Available | No | Not implemented | 158| Query filtering | ⚠️ Available | No | Not implemented |