.\" 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 search message history, .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 Up/Down Browse sent message history Tab Complete @mention 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 / Search message history i/a/o 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 :reply \fItext\fR Reply to latest private message :r \fItext\fR Short alias for :reply :inbox Show private messages, newest first :inbox clear Clear private messages for this session :last [\fIN\fR] Show last N messages from history (1\-50, default 10) :search \fIkeyword\fR Case\-insensitive search; shows the last 15 matches :mute\-joins Toggle join/leave system notifications on/off :lang Show current UI language :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 the same paging keys as the help screen. .TS l l. q, ESC Close output j/k, arrows Scroll down/up Ctrl+D/Ctrl+U Scroll half page down/up Ctrl+F/Ctrl+B Scroll full page down/up Space/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 r Refresh live output (:inbox) .TE .PP The .B :inbox page shows incoming messages and local sent-message copies for the current session. It refreshes automatically when a new private message arrives while it is open. Incoming unread messages are marked with .B * and counted in the inbox title until the inbox renders them. Use .B :reply or .B :r to answer the latest private-message peer. .B :inbox clear removes private messages and the reply target for this session. Private messages are not written to .IR messages.log . .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 Public chat history in the TNT message log v1 format: RFC\ 3339 UTC pipe\-delimited records .RI ( timestamp | username | content ). Stored in the state directory. Private messages and in-memory inbox state are excluded. 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 .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)