v0.3.0 - Complete deployment documentation and examples - Added comprehensive deployment guide, automated deployment scripts, nginx SSL proxy setup, backup automation, and monitoring tools. Includes VPS deployment, cloud platform guides, and practical examples for production deployment of event-based configuration system.
This commit is contained in:
421
docs/configuration_guide.md
Normal file
421
docs/configuration_guide.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# Configuration Management Guide
|
||||
|
||||
Comprehensive guide for managing the C Nostr Relay's event-based configuration system.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Configuration Events](#configuration-events)
|
||||
- [Parameter Reference](#parameter-reference)
|
||||
- [Configuration Examples](#configuration-examples)
|
||||
- [Security Considerations](#security-considerations)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Overview
|
||||
|
||||
The C Nostr Relay uses a revolutionary **event-based configuration system** where all settings are stored as kind 33334 Nostr events in the database. This provides several advantages:
|
||||
|
||||
### Benefits
|
||||
- **Real-time updates**: Configuration changes applied instantly without restart
|
||||
- **Cryptographic security**: All changes must be cryptographically signed by admin
|
||||
- **Audit trail**: Complete history of all configuration changes
|
||||
- **Version control**: Each configuration change is timestamped and signed
|
||||
- **Zero files**: No configuration files to manage, backup, or version control
|
||||
|
||||
### How It Works
|
||||
1. **Admin keypair**: Generated on first startup, used to sign configuration events
|
||||
2. **Configuration events**: Kind 33334 Nostr events with relay settings in tags
|
||||
3. **Real-time processing**: New configuration events processed via WebSocket
|
||||
4. **Immediate application**: Changes applied to running system without restart
|
||||
|
||||
## Configuration Events
|
||||
|
||||
### Event Structure
|
||||
|
||||
Configuration events follow the standard Nostr event format with kind 33334:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "event_id_computed_from_content",
|
||||
"kind": 33334,
|
||||
"pubkey": "admin_public_key_hex",
|
||||
"created_at": 1699123456,
|
||||
"content": "C Nostr Relay Configuration",
|
||||
"tags": [
|
||||
["d", "relay_public_key_hex"],
|
||||
["relay_description", "My Nostr Relay"],
|
||||
["max_subscriptions_per_client", "25"],
|
||||
["pow_min_difficulty", "16"]
|
||||
],
|
||||
"sig": "signature_computed_with_admin_private_key"
|
||||
}
|
||||
```
|
||||
|
||||
### Required Tags
|
||||
- **`d` tag**: Must contain the relay's public key (identifies which relay this config is for)
|
||||
|
||||
### Event Properties
|
||||
- **Kind**: Must be exactly `33334`
|
||||
- **Content**: Should be descriptive (e.g., "C Nostr Relay Configuration")
|
||||
- **Pubkey**: Must be the admin public key generated at first startup
|
||||
- **Signature**: Must be valid signature from admin private key
|
||||
|
||||
## Parameter Reference
|
||||
|
||||
### Basic Relay Information
|
||||
|
||||
#### `relay_description`
|
||||
- **Description**: Human-readable relay description (shown in NIP-11)
|
||||
- **Default**: `"C Nostr Relay"`
|
||||
- **Format**: String, max 512 characters
|
||||
- **Example**: `"My awesome Nostr relay for the community"`
|
||||
|
||||
#### `relay_contact`
|
||||
- **Description**: Admin contact information (email, npub, etc.)
|
||||
- **Default**: `""` (empty)
|
||||
- **Format**: String, max 256 characters
|
||||
- **Example**: `"admin@example.com"` or `"npub1..."`
|
||||
|
||||
#### `relay_software`
|
||||
- **Description**: Software identifier for NIP-11
|
||||
- **Default**: `"c-relay"`
|
||||
- **Format**: String, max 64 characters
|
||||
- **Example**: `"c-relay v1.0.0"`
|
||||
|
||||
#### `relay_version`
|
||||
- **Description**: Software version string
|
||||
- **Default**: Auto-detected from build
|
||||
- **Format**: Semantic version string
|
||||
- **Example**: `"1.0.0"`
|
||||
|
||||
### Client Connection Limits
|
||||
|
||||
#### `max_subscriptions_per_client`
|
||||
- **Description**: Maximum subscriptions allowed per WebSocket connection
|
||||
- **Default**: `"25"`
|
||||
- **Range**: `1` to `100`
|
||||
- **Impact**: Prevents individual clients from overwhelming the relay
|
||||
- **Example**: `"50"` (allows up to 50 subscriptions per client)
|
||||
|
||||
#### `max_total_subscriptions`
|
||||
- **Description**: Maximum total subscriptions across all clients
|
||||
- **Default**: `"5000"`
|
||||
- **Range**: `100` to `50000`
|
||||
- **Impact**: Global limit to protect server resources
|
||||
- **Example**: `"10000"` (allows up to 10,000 total subscriptions)
|
||||
|
||||
### Message and Event Limits
|
||||
|
||||
#### `max_message_length`
|
||||
- **Description**: Maximum WebSocket message size in bytes
|
||||
- **Default**: `"65536"` (64KB)
|
||||
- **Range**: `1024` to `1048576` (1MB)
|
||||
- **Impact**: Prevents large messages from consuming resources
|
||||
- **Example**: `"131072"` (128KB)
|
||||
|
||||
#### `max_event_tags`
|
||||
- **Description**: Maximum number of tags allowed per event
|
||||
- **Default**: `"2000"`
|
||||
- **Range**: `10` to `10000`
|
||||
- **Impact**: Prevents events with excessive tags
|
||||
- **Example**: `"5000"`
|
||||
|
||||
#### `max_content_length`
|
||||
- **Description**: Maximum event content length in bytes
|
||||
- **Default**: `"65536"` (64KB)
|
||||
- **Range**: `1` to `1048576` (1MB)
|
||||
- **Impact**: Limits event content size
|
||||
- **Example**: `"131072"` (128KB for longer content)
|
||||
|
||||
### Proof of Work (NIP-13)
|
||||
|
||||
#### `pow_min_difficulty`
|
||||
- **Description**: Minimum proof-of-work difficulty required for events
|
||||
- **Default**: `"0"` (no PoW required)
|
||||
- **Range**: `0` to `40`
|
||||
- **Impact**: Higher values require more computational work from clients
|
||||
- **Example**: `"20"` (requires significant PoW)
|
||||
|
||||
#### `pow_mode`
|
||||
- **Description**: How proof-of-work is handled
|
||||
- **Default**: `"optional"`
|
||||
- **Values**:
|
||||
- `"disabled"`: PoW completely ignored
|
||||
- `"optional"`: PoW verified if present but not required
|
||||
- `"required"`: All events must meet minimum difficulty
|
||||
- **Example**: `"required"` (enforce PoW for all events)
|
||||
|
||||
### Event Expiration (NIP-40)
|
||||
|
||||
#### `nip40_expiration_enabled`
|
||||
- **Description**: Enable NIP-40 expiration timestamp support
|
||||
- **Default**: `"true"`
|
||||
- **Values**: `"true"` or `"false"`
|
||||
- **Impact**: When enabled, processes expiration tags and removes expired events
|
||||
- **Example**: `"false"` (disable expiration processing)
|
||||
|
||||
#### `nip40_expiration_strict`
|
||||
- **Description**: Strict mode for expiration handling
|
||||
- **Default**: `"false"`
|
||||
- **Values**: `"true"` or `"false"`
|
||||
- **Impact**: In strict mode, expired events are immediately rejected
|
||||
- **Example**: `"true"` (reject expired events immediately)
|
||||
|
||||
#### `nip40_expiration_filter`
|
||||
- **Description**: Filter expired events from query results
|
||||
- **Default**: `"true"`
|
||||
- **Values**: `"true"` or `"false"`
|
||||
- **Impact**: When enabled, expired events are filtered from responses
|
||||
- **Example**: `"false"` (include expired events in results)
|
||||
|
||||
#### `nip40_expiration_grace_period`
|
||||
- **Description**: Grace period in seconds before expiration takes effect
|
||||
- **Default**: `"300"` (5 minutes)
|
||||
- **Range**: `0` to `86400` (24 hours)
|
||||
- **Impact**: Allows some flexibility in expiration timing
|
||||
- **Example**: `"600"` (10 minute grace period)
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Basic Relay Setup
|
||||
```json
|
||||
{
|
||||
"kind": 33334,
|
||||
"content": "Basic Relay Configuration",
|
||||
"tags": [
|
||||
["d", "relay_pubkey_here"],
|
||||
["relay_description", "Community Nostr Relay"],
|
||||
["relay_contact", "admin@community-relay.com"],
|
||||
["max_subscriptions_per_client", "30"],
|
||||
["max_total_subscriptions", "8000"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### High-Security Relay
|
||||
```json
|
||||
{
|
||||
"kind": 33334,
|
||||
"content": "High Security Configuration",
|
||||
"tags": [
|
||||
["d", "relay_pubkey_here"],
|
||||
["relay_description", "High-Security Nostr Relay"],
|
||||
["pow_min_difficulty", "24"],
|
||||
["pow_mode", "required"],
|
||||
["max_subscriptions_per_client", "10"],
|
||||
["max_total_subscriptions", "1000"],
|
||||
["max_message_length", "32768"],
|
||||
["nip40_expiration_strict", "true"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Public Community Relay
|
||||
```json
|
||||
{
|
||||
"kind": 33334,
|
||||
"content": "Public Community Relay Configuration",
|
||||
"tags": [
|
||||
["d", "relay_pubkey_here"],
|
||||
["relay_description", "Open Community Relay - Welcome Everyone!"],
|
||||
["relay_contact", "community@relay.example"],
|
||||
["max_subscriptions_per_client", "50"],
|
||||
["max_total_subscriptions", "25000"],
|
||||
["max_content_length", "131072"],
|
||||
["pow_mode", "optional"],
|
||||
["pow_min_difficulty", "8"],
|
||||
["nip40_expiration_enabled", "true"],
|
||||
["nip40_expiration_grace_period", "900"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Private/Corporate Relay
|
||||
```json
|
||||
{
|
||||
"kind": 33334,
|
||||
"content": "Corporate Internal Relay",
|
||||
"tags": [
|
||||
["d", "relay_pubkey_here"],
|
||||
["relay_description", "Corporate Internal Communications"],
|
||||
["relay_contact", "it-admin@company.com"],
|
||||
["max_subscriptions_per_client", "20"],
|
||||
["max_total_subscriptions", "2000"],
|
||||
["max_message_length", "262144"],
|
||||
["nip40_expiration_enabled", "false"],
|
||||
["pow_mode", "disabled"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Admin Key Management
|
||||
|
||||
#### Secure Storage
|
||||
```bash
|
||||
# Store admin private key securely
|
||||
echo "ADMIN_PRIVKEY=your_admin_private_key_here" > .env
|
||||
chmod 600 .env
|
||||
|
||||
# Or use a password manager
|
||||
# Never store in version control
|
||||
echo ".env" >> .gitignore
|
||||
```
|
||||
|
||||
#### Key Rotation
|
||||
Currently, admin key rotation requires:
|
||||
1. Stopping the relay
|
||||
2. Removing the database (loses all events)
|
||||
3. Restarting (generates new keys)
|
||||
|
||||
Future versions will support admin key rotation while preserving events.
|
||||
|
||||
### Event Validation
|
||||
|
||||
The relay performs comprehensive validation on configuration events:
|
||||
|
||||
#### Cryptographic Validation
|
||||
- **Signature verification**: Uses `nostr_verify_event_signature()`
|
||||
- **Event structure**: Validates JSON structure with `nostr_validate_event_structure()`
|
||||
- **Admin authorization**: Ensures events are signed by the authorized admin pubkey
|
||||
|
||||
#### Content Validation
|
||||
- **Parameter bounds checking**: Validates numeric ranges
|
||||
- **String length limits**: Enforces maximum lengths
|
||||
- **Enum validation**: Validates allowed values for mode parameters
|
||||
|
||||
### Network Security
|
||||
|
||||
#### Access Control
|
||||
```bash
|
||||
# Limit access with firewall
|
||||
sudo ufw allow from 192.168.1.0/24 to any port 8888
|
||||
|
||||
# Or use specific IPs
|
||||
sudo ufw allow from 203.0.113.10 to any port 8888
|
||||
```
|
||||
|
||||
#### TLS/SSL Termination
|
||||
```nginx
|
||||
# nginx configuration for HTTPS termination
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name relay.example.com;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Configuration Not Applied
|
||||
|
||||
#### Check Event Signature
|
||||
```javascript
|
||||
// Verify event signature with nostrtool or similar
|
||||
const event = { /* your configuration event */ };
|
||||
const isValid = nostrTools.verifySignature(event);
|
||||
```
|
||||
|
||||
#### Verify Admin Pubkey
|
||||
```bash
|
||||
# Check current admin pubkey in database
|
||||
sqlite3 relay.nrdb "SELECT DISTINCT pubkey FROM events WHERE kind = 33334 ORDER BY created_at DESC LIMIT 1;"
|
||||
|
||||
# Compare with expected admin pubkey from first startup
|
||||
grep "Admin Public Key" relay.log
|
||||
```
|
||||
|
||||
#### Check Event Structure
|
||||
```bash
|
||||
# View the exact event stored in database
|
||||
sqlite3 relay.nrdb "SELECT json_pretty(json_object(
|
||||
'kind', kind,
|
||||
'pubkey', pubkey,
|
||||
'created_at', created_at,
|
||||
'content', content,
|
||||
'tags', json(tags),
|
||||
'sig', sig
|
||||
)) FROM events WHERE kind = 33334 ORDER BY created_at DESC LIMIT 1;"
|
||||
```
|
||||
|
||||
### Configuration Validation Errors
|
||||
|
||||
#### Invalid Parameter Values
|
||||
```bash
|
||||
# Check relay logs for validation errors
|
||||
journalctl -u c-relay | grep "Configuration.*invalid\|Invalid.*configuration"
|
||||
|
||||
# Common issues:
|
||||
# - Numeric values outside valid ranges
|
||||
# - Invalid enum values (e.g., pow_mode)
|
||||
# - String values exceeding length limits
|
||||
```
|
||||
|
||||
#### Missing Required Tags
|
||||
```bash
|
||||
# Ensure 'd' tag is present with relay pubkey
|
||||
sqlite3 relay.nrdb "SELECT tags FROM events WHERE kind = 33334 ORDER BY created_at DESC LIMIT 1;" | grep '"d"'
|
||||
```
|
||||
|
||||
### Performance Impact
|
||||
|
||||
#### Monitor Configuration Changes
|
||||
```bash
|
||||
# Track configuration update frequency
|
||||
sqlite3 relay.nrdb "SELECT datetime(created_at, 'unixepoch') as date,
|
||||
COUNT(*) as config_updates
|
||||
FROM events WHERE kind = 33334
|
||||
GROUP BY date(created_at, 'unixepoch')
|
||||
ORDER BY date DESC;"
|
||||
```
|
||||
|
||||
#### Resource Usage After Changes
|
||||
```bash
|
||||
# Monitor system resources after configuration updates
|
||||
top -p $(pgrep c_relay)
|
||||
|
||||
# Check for memory leaks
|
||||
ps aux | grep c_relay | awk '{print $6}' # RSS memory
|
||||
```
|
||||
|
||||
### Emergency Recovery
|
||||
|
||||
#### Reset to Default Configuration
|
||||
If configuration becomes corrupted or causes issues:
|
||||
|
||||
```bash
|
||||
# Create emergency configuration event
|
||||
nostrtool event \
|
||||
--kind 33334 \
|
||||
--content "Emergency Reset Configuration" \
|
||||
--tag d YOUR_RELAY_PUBKEY \
|
||||
--tag max_subscriptions_per_client 25 \
|
||||
--tag max_total_subscriptions 5000 \
|
||||
--tag pow_mode optional \
|
||||
--tag pow_min_difficulty 0 \
|
||||
--private-key YOUR_ADMIN_PRIVKEY \
|
||||
| nostrtool send ws://localhost:8888
|
||||
```
|
||||
|
||||
#### Database Recovery
|
||||
```bash
|
||||
# If database is corrupted, backup and recreate
|
||||
cp relay.nrdb relay.nrdb.backup
|
||||
rm relay.nrdb*
|
||||
./build/c_relay_x86 # Creates fresh database with new keys
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
This configuration guide covers all aspects of managing the C Nostr Relay's event-based configuration system. The system provides unprecedented flexibility and security for Nostr relay administration while maintaining simplicity and real-time responsiveness.
|
||||
Reference in New Issue
Block a user