summaryrefslogtreecommitdiffstats
path: root/man/meshbay-node.1
blob: 92067a27f43dfa0155e789d13b600c950d78d523 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
.\" meshbay-node(1) man page
.TH MESHBAY\-NODE 1 "August 2026" "meshbay-node 0.6.0" "MeshBay Manual"
.
.SH NAME
meshbay\-node \- MeshBay Node daemon, local file host, streaming server, and group manager
.
.SH SYNOPSIS
.B meshbay\-node
.RI [ command ]
.RI [ subcommand ]
.RI [ target ]
.RI [ options ]
.
.SH DESCRIPTION
.B meshbay\-node
is the local daemon of the MeshBay decentralized platform.
It hosts shared directories, indexes files, serves video streams to peers,
manages group membership, and provides a local control API.
.PP
When invoked without a command, the daemon starts in the foreground.
It loads its configuration from
.IR ~/.config/meshbay/node.toml ,
unlocks (or creates) its Ed25519 keystore, connects to the hub,
starts the directory indexer, the QUIC chunk server,
the WebRTC transport, and the local control API.
.PP
The daemon runs until interrupted by
.B SIGINT
or
.BR SIGTERM .
.
.SH COMMANDS
If no command is given, the daemon starts normally.
.
.TP
.B init
Write an example configuration file and create the keystore if they do
not already exist.
.
.TP
.B status
Print node state: hub connection, node key, running daemon information,
configured groups and their roots, operator pairing status, and pending
invitations. Works whether the daemon is running or stopped.
.
.TP
.B calibrate\-argon2
Benchmark Argon2id with several memory cost values and suggest the one
closest to a 500\ ms target on the current hardware.
.
.TP
.B reload
Ask systemd to send SIGHUP to the running daemon, causing it to re\-read
.I node.toml
and pick up new or changed groups without dropping live connections.
Equivalent to
.BR "systemctl \-\-user reload meshbay\-node" .
.
.TP
.B restart\-daemon
Restart the daemon via systemd. Equivalent to
.BR "systemctl \-\-user restart meshbay\-node" .
.
.SS Group management
.TP
.B group list
List all hosted groups with their roots, key status, file count, and
connected peers.
.
.TP
\fBgroup add\fR \fIname\fR \fB\-\-dir\fR \fIpath\fR
Attach a hub\-side group to this node by writing a
.B [[groups]]
entry to
.IR node.toml .
The group must already exist on the hub.
The directory becomes the group's first root, and is
.B read\-write
so that a new group can receive an upload without further configuration;
pass
.B \-\-no\-writable
for a group that only publishes.
Run
.B meshbay\-node reload
afterwards, then
.BR "meshbay\-node gek init" .
.
.TP
\fBgroup remove\fR \fIname\fR
Remove a group from
.I node.toml
and stop hosting it after the next restart.
Asks for confirmation unless
.B \-\-yes
is given.
.
.SS Root management
A group has one or more named roots: directories on this machine that its
members see. Each is read\-only or read\-write, independently; a group whose
roots are all read\-only is valid and accepts no uploads at all.
.
.TP
.B root list
List this group's roots with their flags and current availability.
.
.TP
\fBroot add\fR \fIpath\fR [\fB\-\-name\fR \fIname\fR] [\fB\-\-writable\fR] [\fB\-\-removable\fR]
Add a directory to the group. The name defaults to the directory's
basename; two roots in a group cannot share a name, compared without
regard to case, and no root may sit inside another.
Run
.B meshbay\-node reload
afterwards to start indexing it.
.
.TP
\fBroot remove\fR \fIname\fR
Remove a root from the group. Files on disk are untouched; only
.I node.toml
changes. The last remaining root cannot be removed.
Asks for confirmation unless
.B \-\-yes
is given.
.
.TP
\fBroot set\fR \fIname\fR [\fB\-\-writable\fR|\fB\-\-no\-writable\fR] [\fB\-\-removable\fR|\fB\-\-no\-removable\fR]
Change a root's flags without removing it. Takes effect immediately; no
reload is needed.
.
.TP
\fBroot eject\fR \fIname\fR
Mark a removable root as ejected before physically disconnecting the
device. Its files are hidden from members and its index entries are
frozen \(em nothing is deleted \(em and the directory watcher stops, so
the unplug produces no deletions to propagate. The device can then be
removed safely. Refused on a root that is not marked
.BR removable .
.
.TP
\fBroot plug\fR \fIname\fR
Re\-enable an ejected root once the device is back. Refused if the
directory is not readable, since clearing the flag while the device is
still absent would hand the next scan an empty directory. The root is
rescanned, so anything that changed while it was away is picked up.
.
.SS Member management
.TP
.B member list
List all admitted members and pending invitation codes, showing role,
status, group scope, and when each identity was pinned.
.
.TP
\fBmember invite\fR \fIusername\fR
Generate a one\-time invitation code for the named user.
The code is printed to the terminal and written to a file under the
data directory.
It is valid for the period set by
.B invite_ttl_hours
(default: 168 hours / 7\ days).
.
.TP
\fBmember revoke\fR \fIusername\fR
Revoke a member's access to the group. They stop receiving the group
encryption key on their next connection. Rotate the GEK afterwards with
.BR "meshbay\-node gek rotate" .
.
.TP
\fBmember unpin\fR \fIusername\fR
Forget a member's pinned key, allowing them to pair again with a new one.
.
.SS Group encryption key (GEK)
.TP
.B gek init
Initialize the group encryption key. Alias:
.BR gek\-init .
.
.TP
.B gek rotate
Replace the current GEK. Every active member re\-receives the new key
automatically. Revoked members keep only the old key. Asks for
confirmation unless
.B \-\-yes
is given.
.
.SS Operator
.TP
.B operator pair
Generate a one\-time pairing code that authorizes a browser as this
node's operator. The operator can invite members and delete files.
Pairing is node\-wide (not per\-group). The code is valid for
.B pair_ttl_hours
(default: 24 hours).
.
.SS File management
.TP
\fBfile list\fR [\fB\-\-group\fR \fIid\fR]
List all indexed files with their id, size, and path.
.
.TP
\fBfile rm\fR \fIfile\-id\fR [\fB\-\-yes\fR]
Delete a file from disk (not just from the index). The file id can be a
prefix as long as it matches exactly one file.
Asks for confirmation unless
.B \-\-yes
is given.
.
.SS Denylist
.TP
.B denylist show
Display all denied users, groups, and JTIs. Entries survive daemon restarts.
.
.TP
\fBdenylist clear\fR [\fIidentifier\fR] [\fB\-\-yes\fR]
Remove entries from the denylist. If an identifier is given, only that entry
is removed; otherwise the entire list is cleared.
.
.SS STUN servers
.TP
.B stun list
Display the STUN servers currently used for ICE candidate gathering.
.
.TP
\fBstun add\fR \fIurl\fR
Add a STUN server. The URL must start with
.BR stun: ,
e.g.\&
.BR stun:stun.example.com:3478 .
.
.TP
\fBstun remove\fR \fIurl\fR
Remove a STUN server from the list.
.
.TP
.B stun reset
Reset the STUN server list to the built\-in defaults (four public servers).
.
.SH OPTIONS
.TP
\fB\-\-config\fR \fIpath\fR
Path to the configuration file. Defaults to
.IR ~/.config/meshbay/node.toml .
.
.TP
\fB\-\-group\fR \fIid\fR
Select a group by id or name when the node hosts multiple groups.
Optional when only one group is configured.
.
.TP
\fB\-\-dir\fR \fIpath\fR
Shared directory, used with
.BR "group add" .
.
.TP
.BR \-\-writable ", " \-\-no\-writable
Whether a root accepts uploads from group members, used with
.BR "root add" ", " "root set" " and " "group add" .
Uploads land in an
.I uploads
subdirectory of the root; existing files are never replaced.
A new root is read\-only unless
.B \-\-writable
is given; the directory passed to
.B "group add"
is the exception and is writable by default.
.
.TP
.BR \-\-removable ", " \-\-no\-removable
Whether a root lives on a device that gets disconnected, used with
.BR "root add" " and " "root set" .
Enables
.BR "root eject" " and " "root plug" ,
and makes the node treat the directory suddenly disappearing as an
unannounced eject rather than as a deletion.
.
.TP
\fB\-\-name\fR \fIname\fR
Explicit name for a root, used with
.BR "root add" .
Default: the directory's basename. Required for a drive or filesystem
root, which has no basename to derive one from.
.
.TP
.B \-\-yes
Skip confirmation prompts for destructive commands
.RB ( "gek rotate" ,
.BR "group remove" ,
.BR "file rm" ,
.BR "denylist clear" ).
.
.TP
\fB\-\-log\-level\fR \fIlevel\fR
Logging level for daemon mode. One of
.BR DEBUG ,
.BR INFO " (default),"
.BR WARNING ,
.BR ERROR .
Ignored for query commands, which always suppress library logging.
.
.SH CONFIGURATION
The daemon reads its configuration from
.I ~/.config/meshbay/node.toml
(overridable with
.BR \-\-config ).
Run
.B meshbay\-node init
to generate an example file.
.PP
Certain settings can be overridden by environment variables prefixed with
.BR MESHBAY_ .
.
.SS [hub]
.TP
.B url
Hub server URL. Default:
.BR https://meshbay.org .
Override:
.BR MESHBAY_HUB_URL .
.
.TP
.B username
Hub account username. Override:
.BR MESHBAY_USERNAME .
.
.SS [node]
.TP
.B quic_port
QUIC (MNP) port for LAN, port\-forwarded, or hub\-less direct access.
Default:
.BR 19010 .
Override:
.BR MESHBAY_QUIC_PORT .
.
.TP
.B ui_port
Local control API port (loopback only, token\-gated). Default:
.BR 18000 .
.
.TP
.B invite_ttl_hours
How long a member invitation code remains valid. Default:
.BR 168
(7\ days).
.
.TP
.B pair_ttl_hours
How long an operator pairing code remains valid. Default:
.BR 24 .
.
.TP
.B device_request_ttl_minutes
How long a device\-add request may wait for approval from an existing device.
Default:
.BR 60 .
.
.TP
.B max_concurrent_streams
Maximum number of simultaneous video streams. One ffmpeg process runs per
viewer; it remuxes rather than re\-encodes so CPU cost is low, but each
uses about 50\ MB of memory. When reached, new viewers are told the
server is busy. Default:
.BR 8 .
Override:
.BR MESHBAY_MAX_CONCURRENT_STREAMS .
Must be a positive integer; zero or negative values are ignored with a
warning.
.
.TP
.B transcode_incompatible_video
When
.BR true " (default),"
HEVC and other browser\-incompatible video codecs are transcoded to H.264
during streaming so browsers can play them. Unlike remuxing, this costs
real CPU per concurrent viewer. Set to
.B false
only when all viewers are known to decode the source codec natively.
.
.TP
.B ice_interfaces
Whitelist of network interface names for WebRTC ICE candidate gathering.
When empty (default), virtual and VPN adapters are auto\-excluded:
Tailscale (tailscale*, wt*), libvirt (virbr*), Docker (docker*, veth*,
br\-*), Podman (podman*), and CNI (cni*). CGNAT\-range addresses
(100.64.0.0/10) are also excluded in auto mode.
Set to an explicit list to override auto\-detection:
.RS
.nf
ice_interfaces = ["wlp0s20f3", "eth0"]
.fi
.RE
.
.TP
.B stun_servers
List of STUN server URLs for WebRTC ICE candidate gathering (NAT
traversal). Each entry must start with
.BR stun: .
When empty (default), four public servers are used:
.IR stun.l.google.com:19302 ,
.IR stun1.l.google.com:19302 ,
.IR stun.cloudflare.com:3478 ,
and
.IR stun.services.mozilla.com:3478 .
Set to an explicit list to override:
.RS
.nf
stun_servers = ["stun:stun.l.google.com:19302", "stun:stun.cloudflare.com:3478"]
.fi
.RE
.
.SS [[groups]]
One or more group sections, each hosting a set of named directories
.RI ( roots ).
.
.TP
.B id
Group identifier, obtained from the hub after creating the group there.
.
.TP
.B name
Human\-readable group name.
.
.TP
.B shared_dir
Single\-directory shorthand: equivalent to declaring one read\-write root
named after the directory's basename. Cannot be combined with
.BR [[groups.roots]] .
.
.TP
.B upload_dir
Deprecated. A separate filesystem path for uploads, from before roots
carried their own read\-write flag. A configuration still using it is
read as a second, writable root and every other root is forced
read\-only. Use
.B writable
on the intended root instead.
.
.TP
.B visibility
.BR private " (default) or " public .
A public group is discoverable on the hub; visibility does not control
admission.
.
.TP
.B join_policy
.BR invite " (default) or " open .
With
.BR invite ,
newcomers need a one\-time code from
.BR "meshbay\-node member invite" .
With
.BR open ,
anyone the hub presents is served without a code. Read from the local
configuration only, never from the hub.
.
.TP
.B quic_port
Per\-group QUIC port override. Default: inherits from
.BR [node].quic_port .
.
.SS [[groups.roots]]
Each root is a named directory inside a group.
.
.TP
.B path
Filesystem path to the directory.
.
.TP
.B name
Display name for this root. Default: the directory's basename.
Two roots in the same group cannot share a name (case\-insensitive),
and no root may sit inside another.
.
.TP
.B kind
A view hint: one of
.BR generic " (default),"
.BR video ,
.BR audio ,
.BR photo .
Currently unused.
.
.TP
.B writable
Boolean. Whether members may upload into this root. Uploads land in an
.I uploads
subdirectory; an existing file is never replaced. Any number of roots in
a group may be writable, including none. Default:
.BR false .
.
.TP
.B removable
Boolean. Whether this root lives on a device that gets disconnected.
Enables
.BR "meshbay\-node root eject" ,
and makes the directory suddenly disappearing freeze the root rather
than look like a deletion of everything in it. Default:
.BR false .
.
.TP
.B upload
Deprecated spelling of
.BR writable ,
read for configurations written before the two were separated.
.B writable
wins where both appear.
.
.SS [keystore]
.TP
.B path
Path to the encrypted keystore file. Default:
.IR ~/.config/meshbay/keystore.enc .
.
.TP
.B unlock_file
Path to a file containing the keystore passphrase, for unattended
startup. Alternatively, set the
.B MESHBAY_UNLOCK_KEY
environment variable.
.
.SH ENVIRONMENT
.TP
.B MESHBAY_HUB_URL
Override the hub URL from the configuration file.
.
.TP
.B MESHBAY_USERNAME
Override the hub username.
.
.TP
.B MESHBAY_QUIC_PORT
Override the QUIC port.
.
.TP
.B MESHBAY_MAX_CONCURRENT_STREAMS
Override the maximum number of concurrent video streams.
.
.TP
.B MESHBAY_UNLOCK_KEY
Keystore passphrase for unattended startup (alternative to
.BR unlock_file ).
.
.TP
.B MESHBAY_TMDB_DEFAULT_TOKEN
TMDB API token for the Videos app metadata enrichment (optional).
.
.TP
.B MESHBAY_MUSICBRAINZ_CONTACT_DEFAULT
Contact address (email or URL) sent in the User-Agent for the Music app's
MusicBrainz lookups (optional). Not a credential — MusicBrainz needs none —
but still never a literal value in source: it is a personal contact string,
same handling as an API token. Absent means MusicBrainz lookups are inert.
.
.SH FILES
.TP
.I ~/.config/meshbay/node.toml
Default configuration file.
.
.TP
.I ~/.config/meshbay/node.env
Environment file read by the systemd service. Contains secrets such as
.BR MESHBAY_UNLOCK_KEY ,
and, optionally,
.BR MESHBAY_TMDB_DEFAULT_TOKEN
and
.BR MESHBAY_MUSICBRAINZ_CONTACT_DEFAULT .
The node authenticates to the hub with its own Ed25519 identity key, not a
password, so no hub credential lives here.
.
.TP
.I ~/.config/meshbay/keystore.enc
Encrypted Ed25519 + X25519 keystore, protected by Argon2id.
.
.TP
.I ~/.local/share/meshbay/
Data directory: chat databases, index caches, bundle store, roster,
denylist, and the control API session token.
.
.TP
.I ~/.local/share/meshbay/ui\-token
Per\-run token for the local control API. Written by the daemon at startup
and read by the
.B meshbay\-node
CLI and the desktop client's Node page.
.
.SH SYSTEMD INTEGRATION
A user service unit is provided at
.IR packaging/systemd/meshbay\-node.service .
Install and enable with:
.PP
.RS
.nf
sudo cp meshbay\-node.service /etc/systemd/system/meshbay\-node@.service
sudo systemctl enable \-\-now meshbay\-node@$USER
.fi
.RE
.PP
Or as a per\-user unit:
.PP
.RS
.nf
cp meshbay\-node\-user.service ~/.config/systemd/user/meshbay\-node.service
systemctl \-\-user enable \-\-now meshbay\-node
.fi
.RE
.PP
The unit reads secrets from
.I ~/.config/meshbay/node.env
and supports
.B reload
(SIGHUP, re\-reads configuration) and
.BR restart .
.
.SH SECURITY
.IP \(bu 2
The control API binds to
.B 127.0.0.1
only and is protected by a per\-run token.
.IP \(bu 2
Operator authority is established locally via
.BR "meshbay\-node operator pair" ,
never learned from the hub.
.IP \(bu 2
Group join policy
.RB ( invite / open )
is read from the local configuration only, never from the hub. A hub
cannot declare a group open.
.IP \(bu 2
The keystore is encrypted with Argon2id. Run
.B meshbay\-node calibrate\-argon2
to tune parameters for your hardware.
.IP \(bu 2
The denylist is persisted to disk and survives daemon restarts.
.
.SH EXAMPLES
Initialize a new node:
.PP
.RS
.nf
meshbay\-node init
meshbay\-node
.fi
.RE
.PP
Check node status:
.PP
.RS
.nf
meshbay\-node status
.fi
.RE
.PP
Host a group:
.PP
.RS
.nf
meshbay\-node group add "My Media" \-\-dir /home/user/Media
meshbay\-node reload
meshbay\-node gek init \-\-group "My Media"
.fi
.RE
.PP
Invite a member:
.PP
.RS
.nf
meshbay\-node member invite alice
.fi
.RE
.PP
Pair an operator browser:
.PP
.RS
.nf
meshbay\-node operator pair
.fi
.RE
.PP
Stream up to 4 concurrent videos (in node.toml):
.PP
.RS
.nf
[node]
max_concurrent_streams = 4
transcode_incompatible_video = false
.fi
.RE
.PP
Override STUN servers (in node.toml):
.PP
.RS
.nf
[node]
stun_servers = ["stun:stun.l.google.com:19302", "stun:stun.cloudflare.com:3478"]
.fi
.RE
.
.SH SEE ALSO
.BR meshbay\-hub (1),
.BR systemctl (1),
.BR ffmpeg (1)
.
.SH AUTHORS
MeshBay contributors.
.br
.UR https://meshbay.org
.UE