Справочник по конфигурации

Полный справочник по nostrfy.toml: каждый ключ, его тип, значение по умолчанию и точное назначение — лимиты, база данных, демон, контроль доступа и Blossom.

Основы

Конфигурация — это TOML файл, по умолчанию с именем nostrfy.toml. Создайте его командой init:

sh
nostrfy --config nostrfy.toml init

Проверьте его (рекомендуется перед каждым запуском):

sh
nostrfy --config nostrfy.toml check

Каждая команда принимает --config <path> (по умолчанию nostrfy.toml).

Общий синтаксис:

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

Разделы конфигурации

РазделНазначение
[relay]Идентичность, URL и переключатели NIP
[server]Сетевая привязка, разделение API, метрики
[rpc]NIP-86 управляющий RPC (аутентификация, лимит тела)
[limits]Все лимиты и защита от перегрузки
[database]Хранилище LMDB, поисковый индекс, лимиты очередей
[daemon]PID-, лог- и stats-файлы и ротация
[access]Начальные списки контроля доступа (изменяемые в процессе работы)
[blossom]Файловый сервер Blossom (хостинг медиа)

Каждый ключ необязателен; отсутствующий ключ использует значение по умолчанию.

Раздел [relay] — идентичность релея

КлючТипПо умолчаниюОписание
namestring"nostrfy"Имя релея, показываемое клиентам через NIP-11
descriptionstring"A minimal and stable Nostr relay"Описание релея (NIP-11)
pubkeystring (64 hex)""Публичный ключ администратора (поле pubkey в NIP-11)
contactstring""Контактный URI администратора (mailto: или https://)
iconstring""URL изображения-иконки релея
post_policystring""URL на политику публикации релея
private_keystring (64 hex)""Собственный секретный ключ релея; нужен для групп NIP-29
public_urlstring""Публичный URL, напр. wss://relay.example.com
livekit_urlstring""URL сервера LiveKit для аудио/видео комнат NIP-29
livekit_api_keystring""API-ключ LiveKit
livekit_api_secretstring""API-секрет LiveKit (для подписи JWT)
enabled_nipsarray of integers[]Явный список разрешённых NIP
disabled_nipsarray of integers[]NIP для отключения (игнорируется, если enabled_nips не пуст)
reject_ephemeralbooleanfalseОтклонять эфемерные события NIP-01 (kinds 20000-29999)
enabled_gitbooleanfalseПринимать git-события NIP-34 (kinds 1617-1633, 30617/30618)
require_powinteger0Требуемое доказательство работы в ведущих нулевых битах
new_pubkey_min_age_secsinteger0Отклонять события от ключей моложе этого (секунды; 0 = выкл.)
max_events_per_min_per_pubkeyinteger0Лимит публикации на ключ (в минуту; 0 = без лимита)
max_groupsinteger1000Лимит in-memory хранилища групп NIP-29
require_authbooleanfalseТребовать аутентификацию NIP-42 для REQ/EVENT/COUNT/NEG
send_auth_challengebooleantrueОтправлять AUTH-challenge при подключении
enabled_nip78_authbooleantrueТребовать NIP-42 AUTH перед приёмом событий kind 78/30078
enabled_command_eventsbooleanfalseВыполнять операторские команды kind:1 от admin-ключа

Детали ключей

  • private_key — собственный секретный ключ релея, которым подписываются сгенерированные релеем события: метаданные групп NIP-29 (39000-39005) и события ролей/участников NIP-43. Создайте командой nostrfy genkey; храните в секрете. Читается один раз при запуске, поэтому его изменение требует перезапуска.
  • public_url — используется для проверки тегов с URL от клиентов: NIP-42 AUTH, NIP-62 vanish и NIP-98 admin auth. Если пусто, релей откатывается к host:port, который никогда не совпадёт с реальным URL клиента при привязке 0.0.0.0 или 127.0.0.1 (пишется предупреждение). Всегда задавайте его.
  • enabled_nips против disabled_nips — побеждает список разрешённых: когда enabled_nips не пуст, рекламируются только его NIP, а disabled_nips игнорируется. Оба требуют перезапуска.
  • reject_ephemeral — kinds 20000-29999 отклоняются, но освобождённые kinds, которые NIP требуют ретранслировать, всё равно пересылаются: 22242, 27235, 28934/28935/28936, 24133, 23194/23195, 24242 и 21059. Применяется по SIGHUP.
  • enabled_git — опциональный NIP-34: принимает kinds 1617-1633 и 30617/30618 и рекламирует NIP-34. По умолчанию выключен, т.к. патчи могут быть большими. Применяется по SIGHUP.

Раздел [server] — настройки сервера

КлючТипПо умолчаниюОписание
hoststring"127.0.0.1"Адрес привязки; 0.0.0.0 принимает соединения отовсюду
portinteger8080Порт (1-65535); порт 80 требует root
api_hoststring""Имя хоста, выделенное под REST API
metrics_enabledbooleantrueОтдавать метрики Prometheus на /metrics
ws_pathsstring"root"Пути конечных точек WebSocket: root, inbox-outbox или all
inbox_write_policystring"any"Кто может писать в /inbox: «any» или «relay» (события всё равно должны нести p-тег)
outbox_write_policystring"any"Кто может писать в /outbox: «any» (собственные события NIP-42-аутентифицированного ключа) или «relay»
trusted_proxiesarray of strings[]Адреса/CIDR обратных прокси, чьему X-Forwarded-For доверяем (пусто = не доверять никому)

Детали ключей

  • host — 0.0.0.0 привязывает все интерфейсы IPv4; 127.0.0.1 — только локально.
  • port — 1-65535; порт 80 требует root. Этот один порт обслуживает WebSocket-релей, NIP-11 документ, REST API и NIP-86 RPC вместе.
  • api_host — выделяет REST API под одно имя хоста, чтобы API и релей могли делить один порт за обратным прокси. Фиксируется при запуске — требует перезапуска.
  • ws_paths — root обслуживает только /, inbox-outbox обслуживает только /inbox и /outbox, all — и то, и другое. Фиксируется при запуске — требует перезапуска.
  • trusted_proxies — перечисляйте только собственные адреса прокси (loopback для nginx/Caddy на том же хосте, диапазон источника балансировщика в облаке). Если задано, IP клиента выводится из последней недоверенной записи X-Forwarded-For для лимитов на IP, ограничения скорости, blockip и журналов. Никогда не добавляйте адрес, доступный клиентам напрямую — они смогут подделать заголовок и обойти per-IP лимиты. Фиксируется при запуске — требует перезапуска.

Раздел [rpc] — управление NIP-86

КлючТипПо умолчаниюОписание
management_tokenstring""Bearer-токен для управляющих API
admin_pubkeystring (64 hex)""Публичный ключ администратора для NIP-98 auth управления
max_admin_body_bytesinteger65536Лимит тела для управляющего RPC NIP-86

NIP-86 RPC смонтирован на публичных маршрутах релея POST / — отдельного управляющего порта нет. management_token и admin_pubkey иногда встречаются под [server] в старых гайдах; эти написания — устаревшие алиасы этих ключей [rpc].

Раздел [limits] — лимиты и защита

Соединения и сообщения

КлючТипПо умолчаниюОписание
max_connectionsinteger10000Максимум одновременных соединений
max_connections_per_ipinteger64Максимум соединений на исходный IP
max_ws_message_bytesinteger1048576Максимум байт на WebSocket-сообщение/фрейм
socket_recv_buffer_kbinteger64Ядерный приёмный буфер на соединение (KiB)
max_out_queue_bytesinteger262144Лимит исходящей очереди на соединение (байты)
ws_idle_timeout_secsinteger300Закрывать простаивающие соединения через это время
http_read_timeout_secsinteger30Таймаут заголовка HTTP-запроса (защита от slow-loris)
max_connections_per_sec_per_ipinteger0Максимум новых соединений в секунду на исходный IP

Подписки и запросы

КлючТипПо умолчаниюОписание
max_filtersinteger20Максимум фильтров на REQ
max_subscriptionsinteger20Максимум подписок на соединение
max_limitinteger500Потолок для REQ limit
max_countinteger2000Потолок для результатов COUNT
max_sub_id_leninteger64Макс. длина id подписки (символы, не байты)
max_sub_bytesinteger1048576Суммарный размер фильтров подписок на соединение
max_req_response_bytesinteger33554432 (32 MB)Потолок суммарных байт, которые может отправить один ответ REQ

События

КлючТипПо умолчаниюОписание
max_content_bytesinteger65536Макс. длина content события в символах
max_tagsinteger2000Максимум тегов на событие
max_tag_value_bytesinteger1024Максимум байт на значение тега
max_created_at_future_secsinteger3600Допустимый уход created_at в будущее
group_late_publish_secsinteger3600Допустимое отставание админ-событий групп NIP-29 (секунды)
max_neg_itemsinteger100000Максимум записей на NIP-77 negentropy-синхронизацию

Устаревшие алиасы: limits.require_pow, limits.new_pubkey_min_age_secs и limits.max_indexed_words по-прежнему принимаются как алиасы relay.require_pow, relay.new_pubkey_min_age_secs и database.max_indexed_words.

REST API

КлючТипПо умолчаниюОписание
max_api_concurrentinteger8Максимум одновременных запросов /api/v1
max_api_limitinteger5000Потолок параметра limit API
max_api_offsetinteger50000Потолок параметра offset API
max_api_fetchinteger55001Макс. окно предвыборки для offset-запросов — должно покрывать max_api_offset + max_api_limit + 1 (0 = без ограничения)
max_api_search_bytesinteger2048Максимум байт параметра search API

Живая рассылка

КлючТипПо умолчаниюОписание
live_batch_interval_msinteger20Как часто сбрасываются живые события (мс)
live_batch_sizeinteger32Максимум событий на живой батч
live_bufferinteger65536Размер очереди живой рассылки

Раздел [database] — база данных

КлючТипПо умолчаниюОписание
pathstring"./data"Каталог базы данных (LMDB)
max_dbsinteger32Максимум именованных баз LMDB
max_readersinteger128Максимум одновременных читателей LMDB
map_sizeinteger1073741824 (1 GB)Нижняя граница размера memory map (байты)
max_map_sizeinteger1099511627776 (1 TB)Потолок memory-map (байты)
purge_interval_secsinteger300Интервал очистки NIP-40 (секунды)
search_indexbooleantrueВключить словесный индекс NIP-50
reader_threadsinteger2Выделенные потоки сканирования
max_indexed_wordsinteger32Слов content каждого события индексируется для поиска
meta_indexbooleantrueПисать заголовок метаданных события для предфильтра сканирования
disabled_fsyncbooleanfalseПропускать синхронный сброс на диск после каждого батча записи
db_buffer_sizeinteger2048Начальный WebSocket-буфер на соединение (байты)
db_request_timeout_secsinteger30Сколько запрос к базе может ждать перед ошибкой
max_db_queue_msgsinteger4096Максимум сообщений в очереди перед быстрым отказом
max_db_queue_eventsinteger262144Максимум событий в батчах очереди перед быстрым отказом
max_db_queue_bytesinteger268435456 (256 MiB)Максимум байт запросов к базе в очереди перед быстрым отказом (0 = без байтового лимита)

Детали ключей

  • map_size — нижняя граница memory map: карта всегда открывается не меньше этого размера.
  • max_map_size — потолок, открывается как разреженное виртуальное резервирование: физический диск растёт только с реально записанными данными. Повысьте его при database map is full.
  • search_index = false — поиск всё равно работает (полнословное сопоставление с content), но сканирования становятся медленнее; на крошечном VPS это вдвое уменьшает базу. Рекомендуется на маленьких инстансах.
  • disabled_fsync — компромисс надёжности ради пропускной способности: записи фиксируются в page cache ОС, и потеря питания может уничтожить самые свежие записи.

Раздел [daemon] — демон

КлючТипПо умолчаниюОписание
pid_filestring"./nostrfy.pid"Путь к PID-файлу
log_filestring"./nostrfy.log"Путь к лог-файлу
stats_filestring"./nostrfy.stats.json"Путь к файлу статистики
stats_interval_secsinteger5Интервал записи статистики (секунды)
max_log_size_bytesinteger52428800 (50 MB)Размер ротации лога (0 = без ротации)
max_log_filesinteger5Сколько поколений ротированных логов хранить

Пути разрешаются относительно каталога файла конфигурации, поэтому остаются корректными после смены рабочего каталога демоном.

Раздел [access] — контроль доступа

КлючТипПо умолчаниюОписание
restrict_relaybooleanfalseПубликовать могут только ключи из списка разрешённых
blocked_kindsarray of integers[]Kinds для отклонения
allowed_kindsarray of integers[]Список разрешённых kinds; если не пуст, принимаются только эти kinds
blocked_ipsarray of strings[]IP-адреса, отклоняемые при подключении
method_grantstable: pubkey → array of strings{}Гранты методов NIP-86 для не-админ ключей (управляются в процессе работы через assignmethod)

Списки разрешённых/запрещённых ключей — не ключи конфигурации — они хранятся в базе релея (LMDB) и управляются в процессе работы:

sh
nostrfy relay allow npub1...
nostrfy relay deny npub1...
nostrfy relay list
  • restrict_relay = true — только ключи из списка разрешённых могут публиковать, а чтение остаётся открытым для всех (любой клиент может подписываться и читать).
  • Запрещённый ключ всегда отклоняется при публикации и никогда не обслуживается при чтении.
  • method_grants — гранты методов NIP-86 для не-админ ключей (ключ → имена методов, напр. модератору разрешены banevent и listbannedevents). При первом запуске засеиваются из конфигурации, затем управляются в процессе работы через NIP-86 assignmethod/unassignmethod (просмотр через listmethodassignees). Выдавать можно только модерационные и читающие методы — управление правами, ролями, инвайтами и идентичностью релея остаётся только админским, а забаненный ключ отклоняется даже с грантами. См. управляющий API.

Раздел [blossom] — файловый сервер Blossom

КлючТипПо умолчаниюОписание
hoststring""Имя хоста сервера Blossom (пусто = отключено)
storagestring"local"Бэкенд: «local» (local_path) или «s3» (S3-совместимый бакет)
local_pathstring"/var/lib/nostrfy/images"Локальный корень хранилища медиафайлов
max_upload_bytesinteger20971520 (20 MB)Макс. размер медиафайла
min_free_bytesinteger33554432 (32 MB)Свободного места ниже — загрузки отклоняются
s3_endpointstring""S3-совместимая конечная точка (напр. R2)
s3_regionstring""Регион S3 (R2 использует «auto»)
s3_bucketstring""Имя S3-бакета
s3_access_keystring""Ключ доступа S3
s3_secret_keystring""Секретный ключ S3
restrict_uploadsbooleanfalseЗагружать могут только ключи из списка разрешённых

Горячая перезагрузка (SIGHUP)

Отредактируйте файл и отправьте kill -HUP $(cat nostrfy.pid) — конфигурация перезагрузится без перезапуска. Большинство настроек вступают в силу сразу; несколько зафиксированы при запуске:

Применяется по SIGHUPТребует перезапуска
relay.name, description, pubkey, contact, icon, post_policy, public_urlrelay.private_key
reject_ephemeral, enabled_git, enabled_nip78_authrelay.livekit_*, enabled_nips / disabled_nips
большая часть [limits]api_host, trusted_proxies, metrics_enabled, ws_paths, database.*, размеры демона, лимиты, blossom.*

[access] перезагрузкой не применяется — списки засеиваются один раз при запуске и затем управляются в процессе работы через NIP-86. Журнал предупреждает, когда изменилась настройка, требующая перезапуска, а несколько захваченных при запуске настроек проверкой перезагрузки не охватываются.

Частые ошибки
ОшибкаИсправление
public_url не заданзадайте wss://...
host остался 127.0.0.1внешние клиенты не могут подключиться
private_key не задан при NIP-29выполните nostrfy genkey + перезапуск
restrict_relay true при пустом списке разрешённыхвсе заблокированы
изменили ключи только-для-перезапуска и послали лишь SIGHUPиспользуйте nostrfy restart