配置参考
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、日志和统计文件及轮转 |
[access] | 初始访问控制列表(运行时可更改) |
[blossom] | Blossom 文件服务器(媒体托管) |
每个键都是可选的;缺少的键使用其默认值。
[relay] 段 — 中继身份
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
name | string | "nostrfy" | 通过 NIP-11 向客户端显示的中继名称 |
description | string | "A minimal and stable Nostr relay" | 中继描述(NIP-11) |
pubkey | string (64 hex) | "" | 管理员公钥(NIP-11 pubkey 字段) |
contact | string | "" | 管理员联系 URI(mailto: 或 https://) |
icon | string | "" | 中继图标图片 URL |
post_policy | string | "" | 指向中继发布政策的 URL |
private_key | string (64 hex) | "" | 中继自身的密钥;NIP-29 群组需要 |
public_url | string | "" | 公共 URL,例如 wss://relay.example.com |
livekit_url | string | "" | 用于 NIP-29 音视频房间的 LiveKit 服务器 URL |
livekit_api_key | string | "" | LiveKit API key |
livekit_api_secret | string | "" | LiveKit API secret(用于签发 JWT) |
enabled_nips | array of integers | [] | 显式 NIP 白名单 |
disabled_nips | array of integers | [] | 要禁用的 NIP(enabled_nips 非空时忽略) |
reject_ephemeral | boolean | false | 拒绝 NIP-01 临时事件(类型 20000-29999) |
enabled_git | boolean | false | 接受 NIP-34 git 事件(类型 1617-1633、30617/30618) |
require_pow | integer | 0 | 要求的工作量证明前导零位数 |
new_pubkey_min_age_secs | integer | 0 | 拒绝来自比该值更“年轻”的公钥的事件(秒;0 = 关闭) |
max_events_per_min_per_pubkey | integer | 0 | 每个公钥的发布速率限制(每分钟;0 = 无限制) |
max_groups | integer | 1000 | 内存中 NIP-29 群组存储的上限 |
require_auth | boolean | false | 对 REQ/EVENT/COUNT/NEG 要求 NIP-42 认证 |
send_auth_challenge | boolean | true | 连接时发送 AUTH 挑战 |
enabled_nip78_auth | boolean | true | 接受 kind 78/30078 事件前要求 NIP-42 AUTH |
enabled_command_events | boolean | false | 执行由管理员公钥发布的 kind:1 运维命令 |
键详情
- private_key — 中继自身的密钥,用于签署中继生成的事件:NIP-29 群组元数据(39000-39005)和 NIP-43 角色/成员事件。用
nostrfy genkey生成;请保密。它只在启动时读取一次,因此更改它需要重启。 - public_url — 用于校验客户端发来的带 URL 标签:NIP-42 AUTH、NIP-62 消除和 NIP-98 管理认证。为空时,中继回退到
host:port,而绑定0.0.0.0或127.0.0.1时它永远不会匹配真实客户端 URL(会记录警告)。务必设置它。 - enabled_nips 与 disabled_nips — 白名单优先:当
enabled_nips非空时,只公布其中的 NIP,disabled_nips被忽略。两者都需要重启。 - reject_ephemeral — 类型 20000-29999 被拒绝,但 NIP 要求转发的豁免类型仍会转发:22242、27235、28934/28935/28936、24133、23194/23195、24242 和 21059。SIGHUP 时生效。
- enabled_git — 可选的 NIP-34:接受类型 1617-1633 和 30617/30618 并公布 NIP-34。默认关闭,因为补丁负载可能很大。SIGHUP 时生效。
[server] 段 — 服务器设置
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
host | string | "127.0.0.1" | 绑定地址;0.0.0.0 接受来自任何位置的连接 |
port | integer | 8080 | 端口(1-65535);80 端口需要 root |
api_host | string | "" | 专用于 REST API 的主机名 |
metrics_enabled | boolean | true | 在 /metrics 提供 Prometheus 指标 |
ws_paths | string | "root" | WebSocket 端点路径:root、inbox-outbox 或 all |
inbox_write_policy | string | "any" | 谁可以写入 /inbox:"any" 或 "relay"(事件仍须带 p 标签) |
outbox_write_policy | string | "any" | 谁可以写入 /outbox:"any"(NIP-42 认证公钥自己的事件)或 "relay" |
trusted_proxies | array of strings | [] | 其 X-Forwarded-For 受信任的反向代理地址/CIDR(空 = 不信任任何代理) |
键详情
- 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 — 只列出代理自身的地址(同主机上 nginx/Caddy 用回环地址,云端用负载均衡器的源网段)。设置后,客户端 IP 从最后一个不受信任的
X-Forwarded-For条目推导,用于按 IP 的上限、速率限制、blockip和日志。切勿添加客户端能直接访问的地址 — 它们可以伪造该头并绕过按 IP 限制。启动时固定 — 需要重启。
[rpc] 段 — NIP-86 管理
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
management_token | string | "" | 管理 API 的 Bearer token |
admin_pubkey | string (64 hex) | "" | 用于 NIP-98 管理认证的管理员公钥 |
max_admin_body_bytes | integer | 65536 | NIP-86 管理 RPC 的请求体限制 |
NIP-86 RPC 挂载在中继的公共 POST / 路由上 — 没有单独的管理端口。旧指南中 management_token 和 admin_pubkey 有时出现在 [server] 下;那些写法是这些 [rpc] 键的遗留别名。
[limits] 段 — 限制与保护
连接与消息
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
max_connections | integer | 10000 | 最大并发连接数 |
max_connections_per_ip | integer | 64 | 每个源 IP 的最大连接数 |
max_ws_message_bytes | integer | 1048576 | 每条 WebSocket 消息/帧的最大字节数 |
socket_recv_buffer_kb | integer | 64 | 每连接内核接收缓冲区(KiB) |
max_out_queue_bytes | integer | 262144 | 每连接出站队列上限(字节) |
ws_idle_timeout_secs | integer | 300 | 空闲连接在此时间后关闭 |
http_read_timeout_secs | integer | 30 | HTTP 请求头超时(slow-loris 防御) |
max_connections_per_sec_per_ip | integer | 0 | 每个源 IP 每秒最大新连接数 |
订阅与查询
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
max_filters | integer | 20 | 每个 REQ 的最大过滤器数 |
max_subscriptions | integer | 20 | 每连接的最大订阅数 |
max_limit | integer | 500 | REQ limit 的上限 |
max_count | integer | 2000 | COUNT 结果的上限 |
max_sub_id_len | integer | 64 | 订阅 id 最大长度(字符,非字节) |
max_sub_bytes | integer | 1048576 | 每连接的订阅过滤器总字节数 |
max_req_response_bytes | integer | 33554432 (32 MB) | 单个 REQ 响应可发送的总字节上限 |
事件
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
max_content_bytes | integer | 65536 | 事件内容最大字符数 |
max_tags | integer | 2000 | 每个事件的最大标签数 |
max_tag_value_bytes | integer | 1024 | 每个标签值的最大字节数 |
max_created_at_future_secs | integer | 3600 | 容忍的 created_at 未来偏移 |
group_late_publish_secs | integer | 3600 | 容忍的 NIP-29 群组管理事件延迟(秒) |
max_neg_items | integer | 100000 | 每次 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_concurrent | integer | 8 | 最大并发 /api/v1 请求数 |
max_api_limit | integer | 5000 | API limit 参数的上限 |
max_api_offset | integer | 50000 | API offset 参数的上限 |
max_api_fetch | integer | 55001 | offset 查询的最大预取窗口 — 必须覆盖 max_api_offset + max_api_limit + 1(0 = 无限制) |
max_api_search_bytes | integer | 2048 | API search 参数的最大字节数 |
实时扇出
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
live_batch_interval_ms | integer | 20 | 实时事件刷新频率(毫秒) |
live_batch_size | integer | 32 | 每个实时批次的最大事件数 |
live_buffer | integer | 65536 | 实时扇出队列大小 |
[database] 段 — 数据库
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
path | string | "./data" | 数据库目录(LMDB) |
max_dbs | integer | 32 | LMDB 最大命名数据库数 |
max_readers | integer | 128 | LMDB 最大并发读取者数 |
map_size | integer | 1073741824 (1 GB) | 内存映射大小的下限(字节) |
max_map_size | integer | 1099511627776 (1 TB) | 内存映射上限(字节) |
purge_interval_secs | integer | 300 | NIP-40 清除间隔(秒) |
search_index | boolean | true | 启用 NIP-50 词索引 |
reader_threads | integer | 2 | 专用扫描线程 |
max_indexed_words | integer | 32 | 每个事件内容被索引的单词数 |
meta_index | boolean | true | 写入扫描预过滤使用的每事件元数据头 |
disabled_fsync | boolean | false | 跳过每个写入批次后的同步磁盘刷新 |
db_buffer_size | integer | 2048 | 每连接 WebSocket 初始缓冲区(字节) |
db_request_timeout_secs | integer | 30 | 数据库请求在失败前可等待的时长 |
max_db_queue_msgs | integer | 4096 | 快速失败前排队的待处理消息上限 |
max_db_queue_events | integer | 262144 | 快速失败前排队批次内的事件上限 |
max_db_queue_bytes | integer | 268435456 (256 MiB) | 快速失败前排队的数据库请求字节上限(0 = 无字节上限) |
键详情
- map_size — 内存映射的下限:映射始终至少以该大小打开。
- max_map_size — 上限,以稀疏虚拟预留方式打开:物理磁盘只随实际写入的数据增长。当遇到
database map is full时提高它。 - search_index = false — 搜索仍然可用(针对内容的全词匹配)但扫描会更慢;在微型 VPS 上它可将数据库减半。小型实例推荐。
- disabled_fsync — 以持久性换取吞吐量:写入提交到操作系统页缓存,断电可能丢失最近的写入。
[daemon] 段 — 守护进程
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
pid_file | string | "./nostrfy.pid" | PID 文件路径 |
log_file | string | "./nostrfy.log" | 日志文件路径 |
stats_file | string | "./nostrfy.stats.json" | 统计文件路径 |
stats_interval_secs | integer | 5 | 统计写入间隔(秒) |
max_log_size_bytes | integer | 52428800 (50 MB) | 日志轮转大小(0 = 不轮转) |
max_log_files | integer | 5 | 保留的轮转日志代数 |
路径相对于配置文件所在目录解析,因此守护进程更改工作目录后它们仍然有效。
[access] 段 — 访问控制
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
restrict_relay | boolean | false | 只有白名单中的公钥可以发布 |
blocked_kinds | array of integers | [] | 要拒绝的类型 |
allowed_kinds | array of integers | [] | 类型白名单;非空时只接受这些类型 |
blocked_ips | array of strings | [] | 连接时拒绝的 IP 地址 |
method_grants | table: 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-86assignmethod/unassignmethod管理(用listmethodassignees查看)。只有审核和读取方法可被授权 — 权限、角色、邀请码和中继身份管理保持仅管理员,且被封禁的公钥即使有授权也会被拒绝。参见管理 API。
[blossom] 段 — Blossom 文件服务器
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
host | string | "" | Blossom 服务器的主机名(空 = 禁用) |
storage | string | "local" | 后端:"local"(local_path)或 "s3"(S3 兼容存储桶) |
local_path | string | "/var/lib/nostrfy/images" | 媒体文件的本地存储根目录 |
max_upload_bytes | integer | 20971520 (20 MB) | 媒体文件最大大小 |
min_free_bytes | integer | 33554432 (32 MB) | 低于该磁盘空间时拒绝上传 |
s3_endpoint | string | "" | S3 兼容端点(例如 R2) |
s3_region | string | "" | S3 区域(R2 使用 "auto") |
s3_bucket | string | "" | S3 存储桶名称 |
s3_access_key | string | "" | S3 access key |
s3_secret_key | string | "" | S3 secret key |
restrict_uploads | boolean | false | 只有白名单中的公钥可以上传 |
运行时重载(SIGHUP)
编辑文件并发送 kill -HUP $(cat nostrfy.pid) 会无需重启重载配置。大多数设置立即生效;少数在启动时固定:
| SIGHUP 时生效 | 需要重启 |
|---|---|
| relay.name、description、pubkey、contact、icon、post_policy、public_url | relay.private_key |
| reject_ephemeral、enabled_git、enabled_nip78_auth | relay.livekit_*、enabled_nips / disabled_nips |
| 大部分 [limits] | api_host、trusted_proxies、metrics_enabled、ws_paths、database.*、daemon 大小、限制上限、blossom.* |
[access] 不会由重载应用 — 列表在启动时播种一次,之后通过 NIP-86 在运行时管理。当需要重启的设置发生变化时日志会警告,少数启动时捕获的设置不会被重载检查。