feat: enhance anonymous access and long-term stability

Improvements for low-barrier anonymous access:
- Enhanced welcome message to clarify anonymous access
- Added EASY_SETUP.md guide in Chinese and English
- Updated README with anonymous access notes

Long-term stability enhancements:
- Improved systemd service with auto-restart and resource limits
- Added log rotation script (scripts/logrotate.sh)
- Added health check script (scripts/healthcheck.sh)
- Added cron setup script for automated maintenance
- Added anonymous access test suite

Testing:
- All security features verified (10/10 passed)
- Anonymous access tests passed (2/2)
- Health check verified

This ensures:
- Zero-barrier SSH access (any username, any password)
- Stable long-term operation with auto-restart
- Automated log management
- Continuous health monitoring
This commit is contained in:
m1ngsama 2026-01-22 15:06:54 +08:00
parent b658ab18a7
commit 5f8b8fd843
8 changed files with 522 additions and 4 deletions

275
EASY_SETUP.md Normal file
View file

@ -0,0 +1,275 @@
# TNT 匿名聊天室 - 快速部署指南 / TNT Anonymous Chat - Quick Setup Guide
[中文](#中文) | [English](#english)
---
## 中文
### 一键安装
```bash
curl -sSL https://raw.githubusercontent.com/m1ngsama/TNT/main/install.sh | sh
```
### 启动服务器
```bash
tnt # 监听 2222 端口
```
就这么简单!服务器已经运行了。
### 用户如何连接
用户只需要一个SSH客户端即可无需任何配置
```bash
ssh -p 2222 your.server.ip
```
**重要提示**
- ✅ 用户可以使用**任意用户名**连接
- ✅ 用户可以输入**任意密码**(甚至直接按回车跳过)
- ✅ **不需要SSH密钥**
- ✅ 不需要提前注册账号
- ✅ 完全匿名,零门槛
连接后,系统会提示输入显示名称(也可以留空使用默认名称)。
### 生产环境部署
使用 systemd 让服务器开机自启:
```bash
# 1. 创建专用用户
sudo useradd -r -s /bin/false tnt
sudo mkdir -p /var/lib/tnt
sudo chown tnt:tnt /var/lib/tnt
# 2. 安装服务
sudo cp tnt.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable tnt
sudo systemctl start tnt
# 3. 检查状态
sudo systemctl status tnt
```
### 防火墙设置
记得开放2222端口
```bash
# Ubuntu/Debian
sudo ufw allow 2222/tcp
# CentOS/RHEL
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
```
### 可选配置
通过环境变量进行高级配置:
```bash
# 修改端口
PORT=3333 tnt
# 限制最大连接数
TNT_MAX_CONNECTIONS=100 tnt
# 限制每个IP的最大连接数
TNT_MAX_CONN_PER_IP=10 tnt
# 只允许本地访问
TNT_BIND_ADDR=127.0.0.1 tnt
# 添加访问密码(所有用户共用一个密码)
TNT_ACCESS_TOKEN="your_secret_password" tnt
```
**注意**:设置 `TNT_ACCESS_TOKEN` 后,所有用户必须使用该密码才能连接,这会提高安全性但也会增加使用门槛。
### 特性
- 🚀 **零配置** - 开箱即用
- 🔓 **完全匿名** - 无需注册,无需密钥
- 🎨 **Vim风格界面** - 支持 INSERT/NORMAL/COMMAND 三种模式
- 📜 **消息历史** - 自动保存聊天记录
- 🌐 **UTF-8支持** - 完美支持中英文及其他语言
- 🔒 **可选安全特性** - 支持限流、访问控制等
---
## English
### One-Line Installation
```bash
curl -sSL https://raw.githubusercontent.com/m1ngsama/TNT/main/install.sh | sh
```
### Start Server
```bash
tnt # Listen on port 2222
```
That's it! Your server is now running.
### How Users Connect
Users only need an SSH client, no configuration required:
```bash
ssh -p 2222 your.server.ip
```
**Important**:
- ✅ Users can use **ANY username**
- ✅ Users can enter **ANY password** (or just press Enter to skip)
- ✅ **No SSH keys required**
- ✅ No registration needed
- ✅ Completely anonymous, zero barrier
After connecting, the system will prompt for a display name (can be left empty for default name).
### Production Deployment
Use systemd for auto-start on boot:
```bash
# 1. Create dedicated user
sudo useradd -r -s /bin/false tnt
sudo mkdir -p /var/lib/tnt
sudo chown tnt:tnt /var/lib/tnt
# 2. Install service
sudo cp tnt.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable tnt
sudo systemctl start tnt
# 3. Check status
sudo systemctl status tnt
```
### Firewall Configuration
Remember to open port 2222:
```bash
# Ubuntu/Debian
sudo ufw allow 2222/tcp
# CentOS/RHEL
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
```
### Optional Configuration
Advanced configuration via environment variables:
```bash
# Change port
PORT=3333 tnt
# Limit max connections
TNT_MAX_CONNECTIONS=100 tnt
# Limit connections per IP
TNT_MAX_CONN_PER_IP=10 tnt
# Bind to localhost only
TNT_BIND_ADDR=127.0.0.1 tnt
# Add password protection (shared password for all users)
TNT_ACCESS_TOKEN="your_secret_password" tnt
```
**Note**: Setting `TNT_ACCESS_TOKEN` requires all users to use that password to connect. This increases security but also raises the barrier to entry.
### Features
- 🚀 **Zero Configuration** - Works out of the box
- 🔓 **Fully Anonymous** - No registration, no keys
- 🎨 **Vim-Style Interface** - Supports INSERT/NORMAL/COMMAND modes
- 📜 **Message History** - Automatic chat log persistence
- 🌐 **UTF-8 Support** - Perfect for all languages
- 🔒 **Optional Security** - Rate limiting, access control, etc.
---
## 使用示例 / Usage Examples
### 基本使用 / Basic Usage
```bash
# 启动服务器
tnt
# 用户连接(从任何机器)
ssh -p 2222 chat.example.com
# 输入任意密码或直接回车
# 输入显示名称或留空
# 开始聊天!
```
### Vim风格操作 / Vim-Style Operations
连接后:
- **INSERT 模式**(默认):直接输入消息,按 Enter 发送
- **NORMAL 模式**:按 `ESC` 进入,使用 `j/k` 滚动历史,`g/G` 跳转顶部/底部
- **COMMAND 模式**:按 `:` 进入,输入 `:list` 查看在线用户,`:help` 查看帮助
### 故障排除 / Troubleshooting
#### 问题:端口已被占用
```bash
# 更换端口
tnt -p 3333
```
#### 问题:防火墙阻止连接
```bash
# 检查防火墙状态
sudo ufw status
sudo firewall-cmd --list-ports
# 确保已开放端口
sudo ufw allow 2222/tcp
```
#### 问题:连接超时
```bash
# 检查服务器是否运行
ps aux | grep tnt
# 检查端口监听
sudo lsof -i:2222
```
---
## 技术细节 / Technical Details
- **语言**: C
- **依赖**: libssh
- **并发**: 多线程,支持数百个同时连接
- **安全**: 可选限流、访问控制、密码保护
- **存储**: 简单的文本日志messages.log
- **配置**: 环境变量,无配置文件
---
## 许可证 / License
MIT License - 自由使用、修改、分发

View file

@ -20,6 +20,8 @@ PORT=3333 tnt # env var
Connect: `ssh -p 2222 localhost`
**Anonymous Access**: By default, users can connect with ANY username and ANY password (or empty password). No SSH keys required. This makes TNT perfect for public chat servers.
## Security
Configure via environment variables.
@ -101,6 +103,7 @@ tnt.service systemd unit
## Docs
- `README` - man page style
- `EASY_SETUP.md` - 🚀 **快速部署指南 / Quick Setup Guide**
- `HACKING` - dev guide
- `DEPLOYMENT.md` - production
- `CICD.md` - automation

76
scripts/healthcheck.sh Executable file
View file

@ -0,0 +1,76 @@
#!/bin/bash
# TNT Health Check Script
# Verifies the server is running and accepting connections
PORT="${1:-2222}"
TIMEOUT="${2:-5}"
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "TNT Health Check"
echo "=================="
echo ""
# Check if process is running
echo -n "Process check: "
if pgrep -x tnt > /dev/null; then
echo -e "${GREEN}${NC} TNT process is running"
PID=$(pgrep -x tnt)
echo " PID: $PID"
else
echo -e "${RED}${NC} TNT process is not running"
exit 1
fi
# Check if port is listening
echo -n "Port check: "
if lsof -i:$PORT -sTCP:LISTEN > /dev/null 2>&1 || netstat -ln 2>/dev/null | grep -q ":$PORT "; then
echo -e "${GREEN}${NC} Port $PORT is listening"
else
echo -e "${RED}${NC} Port $PORT is not listening"
exit 1
fi
# Try to connect via SSH
echo -n "Connection test: "
timeout $TIMEOUT ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=$TIMEOUT -p $PORT test@localhost exit 2>/dev/null &
CONNECT_PID=$!
wait $CONNECT_PID
CONNECT_RESULT=$?
if [ $CONNECT_RESULT -eq 0 ] || [ $CONNECT_RESULT -eq 255 ]; then
# Exit code 255 means SSH connection was established but auth failed, which is expected
echo -e "${GREEN}${NC} SSH connection successful"
else
echo -e "${YELLOW}${NC} SSH connection timeout or failed (but port is listening)"
fi
# Check log file
LOG_FILE="/var/lib/tnt/messages.log"
if [ -f "$LOG_FILE" ]; then
LOG_SIZE=$(du -h "$LOG_FILE" | cut -f1)
echo "Log file: $LOG_SIZE"
else
LOG_FILE="./messages.log"
if [ -f "$LOG_FILE" ]; then
LOG_SIZE=$(du -h "$LOG_FILE" | cut -f1)
echo "Log file: $LOG_SIZE"
else
echo "Log file: Not found (will be created on first message)"
fi
fi
# Memory usage
echo -n "Memory usage: "
if [ ! -z "$PID" ]; then
MEM=$(ps -p $PID -o rss= | awk '{printf "%.1f MB", $1/1024}')
echo "$MEM"
fi
echo ""
echo -e "${GREEN}Health check passed${NC}"
exit 0

44
scripts/logrotate.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
# TNT Log Rotation Script
# Keeps chat history manageable and prevents disk space issues
LOG_FILE="${1:-/var/lib/tnt/messages.log}"
MAX_SIZE_MB="${2:-100}"
KEEP_LINES="${3:-10000}"
# Check if log file exists
if [ ! -f "$LOG_FILE" ]; then
echo "Log file $LOG_FILE does not exist"
exit 0
fi
# Get file size in MB
FILE_SIZE=$(du -m "$LOG_FILE" | cut -f1)
# Rotate if file is too large
if [ "$FILE_SIZE" -gt "$MAX_SIZE_MB" ]; then
echo "Log file size: ${FILE_SIZE}MB, rotating..."
# Create backup
BACKUP="${LOG_FILE}.$(date +%Y%m%d_%H%M%S)"
cp "$LOG_FILE" "$BACKUP"
# Keep only last N lines
tail -n "$KEEP_LINES" "$LOG_FILE" > "${LOG_FILE}.tmp"
mv "${LOG_FILE}.tmp" "$LOG_FILE"
# Compress old backup
gzip "$BACKUP"
echo "Log rotated. Backup: ${BACKUP}.gz"
echo "Kept last $KEEP_LINES lines"
else
echo "Log file size: ${FILE_SIZE}MB (under ${MAX_SIZE_MB}MB limit)"
fi
# Clean up old compressed logs (keep last 5)
LOG_DIR=$(dirname "$LOG_FILE")
cd "$LOG_DIR" || exit
ls -t messages.log.*.gz 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null
echo "Log rotation complete"

35
scripts/setup_cron.sh Executable file
View file

@ -0,0 +1,35 @@
#!/bin/bash
# Setup cron jobs for TNT maintenance
echo "Setting up TNT maintenance cron jobs..."
# Create scripts directory if it doesn't exist
mkdir -p /var/lib/tnt/scripts
# Copy scripts
cp "$(dirname "$0")/logrotate.sh" /var/lib/tnt/scripts/
cp "$(dirname "$0")/healthcheck.sh" /var/lib/tnt/scripts/
chmod +x /var/lib/tnt/scripts/*.sh
# Add cron jobs
CRON_FILE="/etc/cron.d/tnt"
cat > "$CRON_FILE" << 'EOF'
# TNT Chat Server Maintenance Tasks
# Log rotation - daily at 3 AM
0 3 * * * root /var/lib/tnt/scripts/logrotate.sh /var/lib/tnt/messages.log 100 10000 >> /var/log/tnt-logrotate.log 2>&1
# Health check - every 5 minutes
*/5 * * * * root /var/lib/tnt/scripts/healthcheck.sh 2222 5 >> /var/log/tnt-health.log 2>&1
EOF
chmod 644 "$CRON_FILE"
echo "Cron jobs installed:"
cat "$CRON_FILE"
echo ""
echo "Done! Maintenance tasks will run automatically."
echo "- Log rotation: Daily at 3 AM"
echo "- Health check: Every 5 minutes"

View file

@ -389,7 +389,11 @@ static int read_username(client_t *client) {
char buf[4];
tui_clear_screen(client);
client_printf(client, "请输入用户名: ");
client_printf(client, "================================\r\n");
client_printf(client, " 欢迎来到 TNT 匿名聊天室\r\n");
client_printf(client, " Welcome to TNT Anonymous Chat\r\n");
client_printf(client, "================================\r\n\r\n");
client_printf(client, "请输入用户名 (留空默认为 anonymous): ");
while (1) {
int n = ssh_channel_read_timeout(client->channel, buf, 1, 0, 60000); /* 60 sec timeout */

62
test_anonymous_access.sh Executable file
View file

@ -0,0 +1,62 @@
#!/bin/bash
# Test anonymous SSH access
echo "Testing anonymous SSH access to TNT server..."
echo ""
# Test 1: Connection with any username and password
echo "Test 1: Connection with any username (should succeed)"
timeout 5 expect -c '
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2223 testuser@localhost
expect {
"password:" {
send "anypassword\r"
expect {
"请输入用户名:" {
send "TestUser\r"
send "\003"
exit 0
}
timeout { exit 1 }
}
}
timeout { exit 1 }
}
' 2>&1 | grep -q "请输入用户名"
if [ $? -eq 0 ]; then
echo "✓ Test 1 PASSED: Can connect with any password"
else
echo "✗ Test 1 FAILED: Cannot connect with any password"
fi
echo ""
# Test 2: Connection should work without special SSH options
echo "Test 2: Simple connection (standard SSH command)"
timeout 5 expect -c '
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2223 anonymous@localhost
expect {
"password:" {
send "\r"
expect {
"请输入用户名:" {
send "\r"
send "\003"
exit 0
}
timeout { exit 1 }
}
}
timeout { exit 1 }
}
' 2>&1 | grep -q "请输入用户名"
if [ $? -eq 0 ]; then
echo "✓ Test 2 PASSED: Can connect with empty password"
else
echo "✗ Test 2 FAILED: Cannot connect with empty password"
fi
echo ""
echo "Anonymous access test completed."

View file

@ -1,5 +1,6 @@
[Unit]
Description=TNT Chat Server
Description=TNT Terminal Chat Server (Anonymous)
Documentation=https://github.com/m1ngsama/TNT
After=network.target
[Service]
@ -8,17 +9,35 @@ User=tnt
Group=tnt
WorkingDirectory=/var/lib/tnt
ExecStart=/usr/local/bin/tnt
# Automatic restart on failure for long-term stability
Restart=always
RestartSec=10
# Security
# Limit restart rate to prevent thrashing
StartLimitInterval=300
StartLimitBurst=5
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/tnt
# Environment
# Resource limits for stability
LimitNOFILE=65536
LimitNPROC=512
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=tnt
# Graceful shutdown
TimeoutStopSec=30
# Environment (can be customized via systemctl edit)
Environment="PORT=2222"
[Install]