TNT/tnt.1

397 lines
9.2 KiB
Groff

.\" tnt(1) - Terminal Network Talk
.TH TNT 1 "2026-05-24" "TNT 1.0.1" "User Commands"
.SH NAME
tnt \- anonymous SSH chat server with Vim\-style TUI
.SH SYNOPSIS
.B tnt
.RB [ \-p | \-\-port
.IR port ]
.RB [ \-d | \-\-state\-dir
.IR dir ]
.RB [ \-\-bind
.IR addr ]
.RB [ \-\-public\-host
.IR host ]
.RB [ \-\-max\-connections
.IR n ]
.RB [ \-\-max\-conn\-per\-ip
.IR n ]
.RB [ \-\-max\-conn\-rate\-per\-ip
.IR n ]
.RB [ \-\-rate\-limit
.IR 0|1 ]
.RB [ \-\-idle\-timeout
.IR seconds ]
.RB [ \-\-ssh\-log\-level
.IR level ]
.RB [ \-V | \-\-version ]
.RB [ \-h | \-\-help ]
.br
.B tnt
.B \-\-log\-check
.I file
.br
.B tnt
.B \-\-log\-recover
.I file
.SH DESCRIPTION
.B tnt
is a multi\-user anonymous chat server accessed over SSH.
It provides a Vim\-style terminal user interface with INSERT, NORMAL, and
COMMAND modes.
Users connect with any standard SSH client; no account or registration is
needed.
.PP
In the 1.x series,
.B tnt
is the stable server process name.
Use
.BR tntctl (1)
for local control commands against a running server.
.PP
Messages are persisted to a log file and restored on server restart.
The server supports CJK and emoji input, rate limiting, access tokens, and
a non\-interactive exec interface for scripting.
.SH OPTIONS
.TP
.BR \-p ", " \-\-port " " \fIport\fR
Listen on
.I port
instead of the default 2222.
Overrides the
.B PORT
environment variable.
.TP
.BR \-d ", " \-\-state\-dir " " \fIdir\fR
Store the host key and message log in
.IR dir .
Overrides the
.B TNT_STATE_DIR
environment variable.
Defaults to the current working directory.
.TP
.BR \-\-bind " " \fIaddr\fR
Bind the SSH listener to
.IR addr .
Overrides the
.B TNT_BIND_ADDR
environment variable.
The default is 0.0.0.0.
.TP
.BR \-\-public\-host " " \fIhost\fR
Show
.I host
in the startup connection hint.
Overrides the
.B TNT_PUBLIC_HOST
environment variable.
.TP
.BR \-\-max\-connections " " \fIn\fR
Set the global connection limit.
Overrides the
.B TNT_MAX_CONNECTIONS
environment variable.
.TP
.BR \-\-max\-conn\-per\-ip " " \fIn\fR
Set the concurrent session limit per source IP.
Overrides the
.B TNT_MAX_CONN_PER_IP
environment variable.
.TP
.BR \-\-max\-conn\-rate\-per\-ip " " \fIn\fR
Set the connection-rate limit per source IP per 60-second window.
Overrides the
.B TNT_MAX_CONN_RATE_PER_IP
environment variable.
.TP
.BR \-\-rate\-limit " " \fI0|1\fR
Disable or enable rate-based blocking and auth-failure IP blocking.
Explicit capacity limits still apply.
Overrides the
.B TNT_RATE_LIMIT
environment variable.
.TP
.BR \-\-idle\-timeout " " \fIseconds\fR
Disconnect inactive interactive sessions after
.I seconds
seconds. Use 0 to disable.
Overrides the
.B TNT_IDLE_TIMEOUT
environment variable.
.TP
.BR \-\-ssh\-log\-level " " \fIlevel\fR
Set libssh log verbosity from 0 to 4.
Overrides the
.B TNT_SSH_LOG_LEVEL
environment variable.
.TP
.BR \-\-log\-check " " \fIfile\fR
Check a
.I messages.log
v1 file and print record counts.
Exits non-zero when invalid records are found or the file cannot be read.
.TP
.BR \-\-log\-recover " " \fIfile\fR
Write valid
.I messages.log
v1 records to standard output and print a recovery summary to standard error.
The source file is not modified.
.TP
.BR \-V ", " \-\-version
Print version and exit.
.TP
.BR \-h ", " \-\-help
Print a short usage summary and exit.
.SH CONNECTING
.nf
ssh any\-username@hostname \-p 2222
.fi
.PP
If an access token is configured, supply it as the SSH password.
The username entered in the SSH handshake is ignored; a chat\-room
nickname is chosen interactively after login.
.SH MODES
.TP
.B INSERT
Type and send messages.
Press
.B Enter
to send,
.B ESC
to switch to NORMAL mode.
.TP
.B NORMAL
Scroll through chat history with Vim keybindings.
Press
.B i
to return to INSERT,
.B :
to enter COMMAND mode,
.B ?
to open the full key reference.
.TP
.B COMMAND
Execute commands prefixed with
.BR : .
.SH KEYBINDINGS
.SS INSERT mode
.TS
l l.
Enter Send message
ESC Switch to NORMAL
Ctrl+W Delete last word
Ctrl+U Clear input line
Ctrl+C Switch to NORMAL
Paste Keep multi-line paste in the input buffer
/me \fIaction\fR Send action message (e.g. /me waves)
@\fIusername\fR Mention user (bell notification + highlight)
.TE
.PP
The input line shows remaining bytes near the message limit. Extra input
past the limit is ignored with a terminal bell.
.SS NORMAL mode
.TS
l l.
j/k Scroll down/up one line
Ctrl+D/Ctrl+U Scroll half page down/up
Ctrl+F/Ctrl+B Scroll full page down/up
PageDown/PageUp Scroll full page down/up
End/Home Jump to bottom/top
g/G Jump to top/bottom
i Switch to INSERT
: Enter COMMAND mode
? Open full key reference
Ctrl+C Disconnect
.TE
.PP
NORMAL mode opens on the latest visible messages and stays pinned there
until you scroll up. Use k, Ctrl+U, Ctrl+B, or PageUp to move toward
older history; use G or End to return to the latest messages.
.SS COMMAND mode
.TS
l l.
:list Show online users
:nick \fIname\fR Change nickname
:name \fIname\fR Alias for :nick
:msg \fIuser message\fR Send private message
:w \fIuser text\fR Short alias for :msg
:inbox Show private messages
:last [\fIN\fR] Show last N messages from history (1\-50, default 10)
:search \fIkeyword\fR Case\-insensitive search across full message history
:mute\-joins Toggle join/leave system notifications on/off
:lang \fIen|zh\fR Switch UI language for this session
:help Show concise manual
:clear Clear command output
:q, :quit, :exit Disconnect
Up/Down Browse command history
ESC Cancel and return to NORMAL
.TE
.PP
Command output pages use j/k, Ctrl+D/Ctrl+U, and g/G for paging.
The
.B :inbox
page can also be refreshed with
.B r
and refreshes automatically when a new private message arrives while it is
open.
.SH EXEC INTERFACE
Commands can be run non\-interactively for scripting:
.PP
.nf
ssh host \-p 2222 help
ssh host \-p 2222 users \-\-json
ssh host \-p 2222 stats \-\-json
ssh host \-p 2222 tail 20
ssh host \-p 2222 dump \-n 100
ssh host \-p 2222 post "Hello from a script"
ssh host \-p 2222 post "/me deploys v2.0"
ssh host \-p 2222 health
.fi
.PP
Exit codes follow
.BR sysexits (3)
conventions.
.SH EXIT STATUS
.TP
.B 0
Success.
.TP
.B 1
Runtime error, such as I/O failure, allocation failure, or persistence failure.
.TP
.B 64
Usage error, such as an unknown command, invalid option, or invalid argument
shape.
.TP
.B 69
Reserved for the local
.BR tntctl (1)
wrapper when SSH transport is unavailable.
.TP
.B 78
Reserved for future local
.BR tntctl (1)
configuration errors.
.PP
The SSH exec JSON field contract is documented in
.IR docs/INTERFACE.md .
.SH ENVIRONMENT
.TP
.B PORT
Default listening port (default: 2222).
.TP
.B TNT_STATE_DIR
Directory for host key and message log (default: current directory).
.TP
.B TNT_BIND_ADDR
Address to bind (default: 0.0.0.0).
.TP
.B TNT_PUBLIC_HOST
Host name shown in startup connection hints (default: localhost).
.TP
.B TNT_ACCESS_TOKEN
If set, clients must supply this string as their SSH password.
Compared in constant time.
.TP
.B TNT_LANG
Default interactive UI language.
Accepts
.B en
or
.BR zh .
When unset, TNT detects the process locale and falls back to English.
.TP
.B TNT_MAX_CONNECTIONS
Global connection limit (default: 64, max: 1024).
.TP
.B TNT_MAX_CONN_PER_IP
Max concurrent sessions from one IP (default: 5).
.TP
.B TNT_MAX_CONN_RATE_PER_IP
Max new connections per IP per 60\-second window (default: 10).
.TP
.B TNT_RATE_LIMIT
Set to 0 to disable rate\-based blocking and auth\-failure IP blocking.
Explicit capacity limits still apply (default: 1).
.TP
.B TNT_IDLE_TIMEOUT
Disconnect clients after this many seconds of inactivity.
Set to 0 to disable (default: 1800, i.e. 30 minutes).
.TP
.B TNT_SSH_LOG_LEVEL
libssh log verbosity from 0 to 4 (default: 1).
.SH FILES
.TP
.I messages.log
Chat history in the TNT message log v1 format:
RFC\ 3339 UTC pipe\-delimited records
.RI ( timestamp | username | content ).
Stored in the state directory.
See
.I docs/MESSAGE_LOG.md
in the source distribution for parser and recovery rules.
.TP
.I host_key
RSA 4096\-bit host key, auto\-generated on first run.
Stored in the state directory with mode 0600.
.TP
.I motd.txt
Optional Message of the Day.
When present in the state directory, its contents are shown to each user
immediately on connect before the chat screen appears.
Delete the file to disable the MOTD.
.SH SYSTEMD
A unit file
.I tnt.service
is provided.
Typical setup:
.PP
.nf
sudo useradd \-r \-s /bin/false tnt
sudo cp tnt.service /etc/systemd/system/
sudo systemctl daemon\-reload
sudo systemctl enable \-\-now tnt
.fi
.PP
Runtime overrides can be placed in
.IR /etc/default/tnt .
.SH SECURITY
.IP \(bu 2
Reference\-counted client lifecycle prevents use\-after\-free.
.IP \(bu 2
Per\-IP rate limiting with auth\-failure blocking (5 failures = 5\-minute ban).
.IP \(bu 2
Access\-token comparison uses constant\-time algorithm.
.IP \(bu 2
Host key created with restrictive permissions (0600).
.IP \(bu 2
systemd hardening: NoNewPrivileges, PrivateTmp, ProtectSystem=strict.
.SH EXAMPLES
Start on port 3000 with state in /var/lib/tnt:
.PP
.nf
tnt \-p 3000 \-d /var/lib/tnt
.fi
.PP
Start with an access token:
.PP
.nf
TNT_ACCESS_TOKEN=s3cret tnt
.fi
.PP
Connect from another machine:
.PP
.nf
ssh user@chat.example.com \-p 2222
.fi
.SH AUTHORS
m1ngsama <contact@m1ng.space>
.SH BUGS
Report bugs at
.UR https://github.com/m1ngsama/TNT/issues
the project issue tracker
.UE .
.SH SEE ALSO
.BR ssh (1),
.BR sshd (8),
.BR systemctl (1)