docs: troubleshooting section for "Connection closed by remote host" (UX-10)

The original UX-10 was "give the client a readable reason on
disconnect" — turns out the libssh server API doesn't let us send
SSH_MSG_USERAUTH_BANNER, ssh_set_banner is GET-only on the linked
versions (0.9.6 on oss, 0.10.6 on ali), and pre-auth rejections
(max_connections / ratelimit / firewall) happen before any SSH
exchange the client could parse.

The realistic improvement is documentation: README now has a
troubleshooting table mapping the generic close to the actual cause
and how to verify (journalctl) + fix.  Also documents the idle
timeout disconnect for completeness.

Server-side stderr already prints rejection reason with the
offending IP, so journalctl gives the admin enough to debug.
This commit is contained in:
m1ngsama 2026-05-17 14:24:35 +08:00
parent 6a36cbcb82
commit 70718482f3

View file

@ -317,6 +317,32 @@ Delete `motd.txt` to disable the MOTD.
- **Concurrency**: Supports 100+ concurrent connections
- **Throughput**: 1000+ messages/second
## Troubleshooting
### "Connection closed by remote host" right after `ssh -p 2222 host`
TNT has very little it can say to the SSH client before disconnecting,
so any pre-auth rejection just looks like a generic close. Common
causes, fastest to slowest fix:
| Likely cause | Why | Fix |
|---|---|---|
| Per-IP concurrent limit | `TNT_MAX_CONN_PER_IP` (default 5) | Close other sessions, or raise the env var |
| Per-IP connection rate | More than `TNT_MAX_CONN_RATE_PER_IP` attempts in 60 s | Wait 5 min (block window), or raise the limit |
| Auth-failure ban | 5 wrong passwords / failed kex in a row | Wait 5 min |
| Global cap | `TNT_MAX_CONNECTIONS` (default 64) is full | Wait for someone to leave |
| Firewall | The host's ufw / iptables doesn't open 2222 | Open the port |
The server admin can confirm which by checking the systemd journal
(`sudo journalctl -u tnt -n 50 --no-pager`) — the rejection reason is
logged to stderr with the offending IP.
### Idle disconnect
After `TNT_IDLE_TIMEOUT` seconds (default 1800 = 30 min) of no
keystrokes, TNT prints `Disconnected: idle timeout (N min)` and closes
the channel. Set the env var to `0` to disable.
## Known Limitations
- Single chat room (no multi-room support yet)