Referencia de configuración

Referencia completa de nostrfy.toml: cada clave, su tipo, su valor predeterminado y exactamente qué hace — límites, base de datos, demonio, control de acceso y Blossom.

Conceptos básicos

La configuración es un archivo TOML, llamado por defecto nostrfy.toml. Créalo con init:

sh
nostrfy --config nostrfy.toml init

Valídalo (recomendado antes de cada inicio):

sh
nostrfy --config nostrfy.toml check

Cada comando acepta --config <path> (por defecto nostrfy.toml).

Sintaxis general:

toml
[section]
key = "string"
key = 8080
key = [1, 2]
key = true

Secciones de configuración

SecciónPropósito
[relay]Identidad, URL e interruptores NIP
[server]Enlace de red, separación de API, métricas
[rpc]RPC de gestión NIP-86 (autenticación, límite del cuerpo)
[limits]Todos los límites y protecciones contra sobrecarga
[database]Almacenamiento LMDB, índice de búsqueda, límites de cola
[daemon]Archivos PID, de registro y de estadísticas y rotación
[access]Listas iniciales de control de acceso (modificables en tiempo de ejecución)
[blossom]Servidor de archivos Blossom (alojamiento de medios)

Cada clave es opcional; una clave ausente usa su valor predeterminado.

Sección [relay] — identidad del relé

ClaveTipoPredeterminadoDescripción
namestring"nostrfy"Nombre del relé mostrado a los clientes vía NIP-11
descriptionstring"A minimal and stable Nostr relay"Descripción del relé (NIP-11)
pubkeystring (64 hex)""Clave pública del administrador (campo pubkey de NIP-11)
contactstring""URI de contacto del administrador (mailto: o https://)
iconstring""URL de la imagen del icono del relé
post_policystring""URL que apunta a la política de publicación del relé
private_keystring (64 hex)""Clave secreta propia del relé; necesaria para grupos NIP-29
public_urlstring""URL pública, p. ej. wss://relay.example.com
livekit_urlstring""URL del servidor LiveKit para salas de audio/vídeo NIP-29
livekit_api_keystring""Clave API de LiveKit
livekit_api_secretstring""Secreto API de LiveKit (usado para firmar JWT)
enabled_nipsarray of integers[]Lista explícita de NIP permitidos
disabled_nipsarray of integers[]NIP a desactivar (se ignora cuando enabled_nips no está vacío)
reject_ephemeralbooleanfalseRechazar eventos efímeros NIP-01 (kinds 20000-29999)
enabled_gitbooleanfalseAceptar eventos git NIP-34 (kinds 1617-1633, 30617/30618)
require_powinteger0Prueba de trabajo requerida en bits cero iniciales
new_pubkey_min_age_secsinteger0Rechazar eventos de pubkeys más recientes que esto (segundos; 0 = desactivado)
max_events_per_min_per_pubkeyinteger0Límite de publicación por pubkey (por minuto; 0 = sin límite)
max_groupsinteger1000Límite del almacén de grupos NIP-29 en memoria
require_authbooleanfalseRequerir autenticación NIP-42 para REQ/EVENT/COUNT/NEG
send_auth_challengebooleantrueEnviar el desafío AUTH al conectar
enabled_nip78_authbooleantrueRequerir AUTH NIP-42 antes de aceptar eventos kind 78/30078
enabled_command_eventsbooleanfalseEjecutar comandos de operador kind:1 firmados por la pubkey del administrador

Detalles de claves

  • private_key — la clave secreta propia del relé, usada para firmar eventos generados por el relé: metadatos de grupos NIP-29 (39000-39005) y eventos de rol/miembros NIP-43. Genérala con nostrfy genkey; mantenla en secreto. Se lee una vez al iniciar, por lo que cambiarla requiere reiniciar.
  • public_url — se usa para validar etiquetas con URL de los clientes: AUTH NIP-42, vanish NIP-62 y auth de administración NIP-98. Cuando está vacía, el relé recurre a host:port, que nunca coincide con una URL real de cliente al enlazar 0.0.0.0 o 127.0.0.1 (se registra una advertencia). Configúrala siempre.
  • enabled_nips frente a disabled_nips — la lista de permitidos gana: cuando enabled_nips no está vacío, solo se anuncian sus NIP y disabled_nips se ignora. Ambos requieren reinicio.
  • reject_ephemeral — los kinds 20000-29999 se rechazan, pero los kinds exentos que los NIP exigen retransmitir siguen reenviándose: 22242, 27235, 28934/28935/28936, 24133, 23194/23195, 24242 y 21059. Se aplica con SIGHUP.
  • enabled_git — NIP-34 opcional: acepta los kinds 1617-1633 y 30617/30618 y anuncia NIP-34. Desactivado por defecto porque los parches pueden ser grandes. Se aplica con SIGHUP.

Sección [server] — ajustes del servidor

ClaveTipoPredeterminadoDescripción
hoststring"127.0.0.1"Dirección de enlace; 0.0.0.0 acepta conexiones de cualquier lugar
portinteger8080Puerto (1-65535); el puerto 80 requiere root
api_hoststring""Nombre de host dedicado a la API REST
metrics_enabledbooleantrueServir métricas Prometheus en /metrics
ws_pathsstring"root"Rutas del endpoint WebSocket: root, inbox-outbox o all
inbox_write_policystring"any"Quién puede escribir en /inbox: "any" o "relay" (los eventos deben llevar etiqueta p)
outbox_write_policystring"any"Quién puede escribir en /outbox: "any" (los propios eventos de la pubkey autenticada NIP-42) o "relay"
trusted_proxiesarray of strings[]Direcciones/CIDR de proxies inversos cuyo X-Forwarded-For es confiable (vacío = no confiar en ningún proxy)

Detalles de claves

  • host — 0.0.0.0 enlaza todas las interfaces IPv4; 127.0.0.1 es solo local.
  • port — 1-65535; el puerto 80 requiere root. Este único puerto sirve el relé WebSocket, el documento NIP-11, la API REST y el RPC NIP-86 juntos.
  • api_host — dedica la API REST a un único nombre de host para que la API y el relé puedan compartir un puerto detrás de un proxy inverso. Fijo al iniciar — requiere reinicio.
  • ws_paths — root sirve solo /, inbox-outbox sirve solo /inbox y /outbox, all sirve ambos. Fijo al iniciar — requiere reinicio.
  • trusted_proxies — incluye solo las direcciones propias del proxy (loopback para nginx/Caddy en el mismo host, el rango de origen del balanceador en la nube). Con esta opción, la IP del cliente se deriva de la última entrada no confiable de X-Forwarded-For para los límites por IP, el límite de tasa, blockip y los registros. Nunca añadas una dirección accesible directamente por los clientes — podrían falsificar la cabecera y eludir los límites por IP. Fijo al iniciar — requiere reinicio.

Sección [rpc] — gestión NIP-86

ClaveTipoPredeterminadoDescripción
management_tokenstring""Token Bearer para las API de gestión
admin_pubkeystring (64 hex)""Pubkey del administrador para la auth de gestión NIP-98
max_admin_body_bytesinteger65536Límite del cuerpo para el RPC de gestión NIP-86

El RPC NIP-86 está montado en las rutas públicas POST / del relé — no hay un puerto de gestión separado. management_token y admin_pubkey a veces aparecen bajo [server] en guías antiguas; esas grafías son alias heredados de estas claves [rpc].

Sección [limits] — límites y protecciones

Conexiones y mensajes

ClaveTipoPredeterminadoDescripción
max_connectionsinteger10000Conexiones concurrentes máximas
max_connections_per_ipinteger64Conexiones máximas por IP de origen
max_ws_message_bytesinteger1048576Bytes máximos por mensaje/frame WebSocket
socket_recv_buffer_kbinteger64Búfer de recepción del kernel por conexión (KiB)
max_out_queue_bytesinteger262144Límite de cola de salida por conexión (bytes)
ws_idle_timeout_secsinteger300Cerrar conexiones inactivas tras este tiempo
http_read_timeout_secsinteger30Tiempo de espera de cabecera HTTP (defensa slow-loris)
max_connections_per_sec_per_ipinteger0Conexiones nuevas máximas por segundo por IP de origen

Suscripciones y consultas

ClaveTipoPredeterminadoDescripción
max_filtersinteger20Filtros máximos por REQ
max_subscriptionsinteger20Suscripciones máximas por conexión
max_limitinteger500Tope para el limit de REQ
max_countinteger2000Tope para resultados COUNT
max_sub_id_leninteger64Longitud máxima del id de suscripción (caracteres, no bytes)
max_sub_bytesinteger1048576Bytes totales de filtros de suscripción por conexión
max_req_response_bytesinteger33554432 (32 MB)Tope de bytes totales que una sola respuesta REQ puede enviar

Eventos

ClaveTipoPredeterminadoDescripción
max_content_bytesinteger65536Longitud máxima del contenido del evento en caracteres
max_tagsinteger2000Etiquetas máximas por evento
max_tag_value_bytesinteger1024Bytes máximos por valor de etiqueta
max_created_at_future_secsinteger3600Desviación futura tolerada de created_at
group_late_publish_secsinteger3600Retraso tolerado para eventos de administración de grupos NIP-29 (segundos)
max_neg_itemsinteger100000Registros máximos por sincronización de negentropía NIP-77

Alias heredados: limits.require_pow, limits.new_pubkey_min_age_secs y limits.max_indexed_words aún se aceptan como alias de relay.require_pow, relay.new_pubkey_min_age_secs y database.max_indexed_words.

API REST

ClaveTipoPredeterminadoDescripción
max_api_concurrentinteger8Solicitudes /api/v1 concurrentes máximas
max_api_limitinteger5000Tope para el parámetro limit de la API
max_api_offsetinteger50000Tope para el parámetro offset de la API
max_api_fetchinteger55001Ventana máxima de sobrecarga para consultas con offset — debe cubrir max_api_offset + max_api_limit + 1 (0 = sin límite)
max_api_search_bytesinteger2048Bytes máximos del parámetro search de la API

Distribución en vivo

ClaveTipoPredeterminadoDescripción
live_batch_interval_msinteger20Frecuencia de vaciado de eventos en vivo (ms)
live_batch_sizeinteger32Eventos máximos por lote en vivo
live_bufferinteger65536Tamaño de la cola de distribución en vivo

Sección [database] — base de datos

ClaveTipoPredeterminadoDescripción
pathstring"./data"Directorio de la base de datos (LMDB)
max_dbsinteger32Máximo de bases de datos nombradas LMDB
max_readersinteger128Máximo de lectores concurrentes LMDB
map_sizeinteger1073741824 (1 GB)Piso del tamaño del mapa de memoria (bytes)
max_map_sizeinteger1099511627776 (1 TB)Techo del mapa de memoria (bytes)
purge_interval_secsinteger300Intervalo de purga NIP-40 (segundos)
search_indexbooleantrueHabilitar el índice de palabras NIP-50
reader_threadsinteger2Hilos dedicados de escaneo
max_indexed_wordsinteger32Palabras del contenido de cada evento indexadas para búsqueda
meta_indexbooleantrueEscribir la cabecera de metadatos por evento usada por el prefiltro de escaneo
disabled_fsyncbooleanfalseOmitir el vaciado síncrono a disco tras cada lote de escritura
db_buffer_sizeinteger2048Búfer WebSocket inicial por conexión (bytes)
db_request_timeout_secsinteger30Tiempo máximo que una solicitud a la base de datos puede esperar antes de fallar
max_db_queue_msgsinteger4096Mensajes pendientes máximos en cola antes de fallar rápido
max_db_queue_eventsinteger262144Eventos máximos en lotes en cola antes de fallar rápido
max_db_queue_bytesinteger268435456 (256 MiB)Bytes máximos de solicitudes a la base de datos en cola antes de fallar rápido (0 = sin límite de bytes)

Detalles de claves

  • map_size — el piso del mapa de memoria: el mapa siempre se abre al menos con este tamaño.
  • max_map_size — el techo, abierto como reserva virtual dispersa: el disco físico solo crece con los datos realmente escritos. Auméntalo cuando veas database map is full.
  • search_index = false — la búsqueda sigue funcionando (coincidencia de palabras completas contra el contenido) pero los escaneos son más lentos; en un VPS pequeño reduce la base de datos a la mitad. Recomendado en instancias pequeñas.
  • disabled_fsync — cambia durabilidad por rendimiento: las escrituras se confirman en la caché de páginas del SO y un corte de energía puede perder las escrituras más recientes.

Sección [daemon] — demonio

ClaveTipoPredeterminadoDescripción
pid_filestring"./nostrfy.pid"Ruta del archivo PID
log_filestring"./nostrfy.log"Ruta del archivo de registro
stats_filestring"./nostrfy.stats.json"Ruta del archivo de estadísticas
stats_interval_secsinteger5Intervalo de escritura de estadísticas (segundos)
max_log_size_bytesinteger52428800 (50 MB)Tamaño de rotación del registro (0 = sin rotación)
max_log_filesinteger5Generaciones de registros rotados a conservar

Las rutas se resuelven respecto al directorio del archivo de configuración, por lo que siguen siendo válidas después de que el demonio cambie su directorio de trabajo.

Sección [access] — control de acceso

ClaveTipoPredeterminadoDescripción
restrict_relaybooleanfalseSolo las pubkeys en lista permitida pueden publicar
blocked_kindsarray of integers[]Kinds a rechazar
allowed_kindsarray of integers[]Lista de kinds permitidos; solo se aceptan estos kinds cuando no está vacía
blocked_ipsarray of strings[]Direcciones IP rechazadas al conectar
method_grantstable: pubkey → array of strings{}Concesiones de métodos NIP-86 para pubkeys no administradoras (gestionadas en tiempo de ejecución con assignmethod)

Las listas de pubkeys permitidas/denegadas no son claves de configuración — viven en la base de datos del relé (LMDB) y se gestionan en tiempo de ejecución:

sh
nostrfy relay allow npub1...
nostrfy relay deny npub1...
nostrfy relay list
  • restrict_relay = true — solo las pubkeys en lista permitida pueden publicar, mientras la lectura sigue abierta para todos (cualquier cliente aún puede suscribirse y obtener datos).
  • Una pubkey denegada siempre se rechaza al publicar y nunca se sirve al leer.
  • method_grants — concesiones de métodos NIP-86 para pubkeys no administradoras (pubkey → nombres de método, p. ej. un moderador con banevent y listbannedevents). Se siembran desde la configuración en la primera ejecución, luego se gestionan en tiempo de ejecución con assignmethod/unassignmethod de NIP-86 (inspeccionadas con listmethodassignees). Solo los métodos de moderación y lectura son delegables — la gestión de permisos, roles, invitaciones e identidad del relé sigue siendo solo de admin, y una pubkey baneada se rechaza incluso con concesiones. Ver la API de gestión.

Sección [blossom] — servidor de archivos Blossom

ClaveTipoPredeterminadoDescripción
hoststring""Nombre de host para el servidor Blossom (vacío = desactivado)
storagestring"local"Backend: "local" (local_path) o "s3" (bucket compatible con S3)
local_pathstring"/var/lib/nostrfy/images"Raíz de almacenamiento local para archivos multimedia
max_upload_bytesinteger20971520 (20 MB)Tamaño máximo de archivo multimedia
min_free_bytesinteger33554432 (32 MB)Espacio en disco por debajo del cual se rechazan subidas
s3_endpointstring""Endpoint compatible con S3 (p. ej. R2)
s3_regionstring""Región S3 (R2 usa "auto")
s3_bucketstring""Nombre del bucket S3
s3_access_keystring""Clave de acceso S3
s3_secret_keystring""Clave secreta S3
restrict_uploadsbooleanfalseSolo las pubkeys en lista permitida pueden subir archivos

Recarga en caliente (SIGHUP)

Editar el archivo y enviar kill -HUP $(cat nostrfy.pid) recarga la configuración sin reiniciar. La mayoría de los ajustes surten efecto de inmediato; unos pocos están fijados al iniciar:

Se aplica con SIGHUPRequiere reinicio
relay.name, description, pubkey, contact, icon, post_policy, public_urlrelay.private_key
reject_ephemeral, enabled_git, enabled_nip78_authrelay.livekit_*, enabled_nips / disabled_nips
la mayoría de [limits]api_host, trusted_proxies, metrics_enabled, ws_paths, database.*, tamaños de demonio, topes de límites, blossom.*

[access] no se aplica con una recarga — las listas se siembran una vez al iniciar y luego se gestionan en tiempo de ejecución vía NIP-86. El registro avisa cuando cambia un ajuste que requiere reinicio, y algunos ajustes capturados al iniciar no son comprobados por la recarga.

Errores comunes
ErrorSolución
public_url sin definirdefine wss://...
host dejado en 127.0.0.1los clientes externos no pueden conectar
private_key sin definir con NIP-29ejecuta nostrfy genkey + reinicia
restrict_relay true con allowlist vacíatodos bloqueados
cambiar claves que solo requieren reinicio y solo hacer SIGHUPusa nostrfy restart