# fastapi-ssh-bbs
**Repository Path**: Lyong9102/fastapi-ssh-bbs
## Basic Information
- **Project Name**: fastapi-ssh-bbs
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-04
- **Last Updated**: 2026-08-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# FastAPI SSH BBS
SSH-native · SQLite · Markdown · Concurrent sessions
SSH 原生 · SQLite · Markdown · 高并发会话
English ·
中文
---
# 中文
**FastAPI SSH BBS** 是一个通过 **SSH 登录即可使用的全屏终端论坛(BBS)**。
无需浏览器、无需额外客户端:只要系统有 `ssh` 命令,就能发帖、回帖、搜索与私信。
本项目按真实线上 SSH BBS 的交互行为复刻实现(分析记录见 [ANALYSIS.md](./ANALYSIS.md)),技术栈选用 **Python 3.10+ / asyncssh / SQLite**,便于在 Windows 与 Linux 上快速部署。
```text
ssh guest@127.0.0.1 -p 2222
# 密码: guest123
```
---
## 功能特性
| 模块 | 说明 |
|------|------|
| **SSH 原生接入** | 内嵌 SSH 服务端,登录后直接进入 TUI,不是系统 shell |
| **全屏终端 UI** | 盒线边框、状态栏、底部快捷键提示;青/黄配色与 `▶` 选中标记 |
| **板块论坛** | 默认 6 大讨论区:Rust / Linux / AI / 开源 / 游戏 / 生活 |
| **帖子与回复** | 列表预览、详情阅读、树状回复、浏览量统计 |
| **互动** | 点赞帖子/回复、私信作者、删除自己的帖子(管理员可删任意帖) |
| **搜索** | 按标题、正文、用户名检索 |
| **账号** | 游客浏览;注册用户可写;密码 bcrypt 哈希存储 |
| **在线列表** | 实时查看当前会话与连接时间 |
| **持久化** | SQLite 本地库;首次启动自动建表并写入种子数据 |
### 权限模型
| 角色 | 能力 |
|------|------|
| **游客 `guest`** | 浏览板块/帖子、搜索、查看在线、进入注册流程 |
| **注册用户** | 发帖、回复、点赞、私信、删除自己的帖子 |
| **管理员 `admin`** | 注册用户全部能力 + 删除任意帖子 |
---
## 正确启动与运行流程
本项目是 **SSH 应用服务器**(不是 HTTP / 浏览器服务)。正确流程始终是:
1. 在一个终端里 **启动服务并保持运行**
2. 在 **另一个终端** 用 `ssh` 客户端登录
3. 用完后在 TUI 里退出会话,再在服务端终端 `Ctrl+C` 停止进程
---
### 第 0 步:环境要求
| 项 | 要求 |
|----|------|
| 操作系统 | Windows 10+ / Linux / macOS |
| Python | **3.10+**(建议 3.11 / 3.12 / 3.13) |
| SSH 客户端 | 系统自带 OpenSSH(`ssh` 命令可用) |
| 依赖 | `asyncssh`、`bcrypt`(见 `requirements.txt`) |
| 端口 | 默认 **2222**(可改) |
检查:
```bash
python --version # 或 python3 --version
ssh -V
```
---
### 第 1 步:进入项目目录
```bash
cd /path/to/terminal_bbs
```
Windows PowerShell / CMD 示例:
```bat
cd C:\AI\terminal_bbs
```
---
### 第 2 步:安装依赖
```bash
python -m pip install -r requirements.txt
```
Linux / macOS 若默认命令是 `python3`:
```bash
python3 -m pip install -r requirements.txt
```
---
### 第 3 步:启动服务(保持此终端不关)
#### 方式 A — 一键脚本(推荐)
**Windows**
```bat
run.bat
```
**Linux / macOS**
```bash
bash run.sh
# 或
chmod +x run.sh && ./run.sh
```
脚本会:安装依赖 → 在 **2222** 端口启动 `main.py`。
#### 方式 B — 手动启动
```bash
python main.py --host 0.0.0.0 --port 2222
```
仅本机访问可用:
```bash
python main.py --host 127.0.0.1 --port 2222
```
#### 启动成功标志
控制台应出现类似输出,且进程 **不退出、持续运行**:
```text
[bbs] FastAPI SSH BBS listening on 0.0.0.0:2222
[bbs] guest login: ssh guest@localhost -p 2222 (password: guest123)
[bbs] admin login: ssh admin@localhost -p 2222 (password: admin123)
[bbs] database: bbs.db
```
首次启动还会自动:
1. 生成 SSH 主机密钥文件 `ssh_host_key`
2. 创建 SQLite 数据库 `bbs.db`
3. 写入默认板块、演示帖子与账号
> **注意**:关掉该终端或 `Ctrl+C` 会停止服务,客户端将无法连接。开发时请单独开一个终端专门跑服务。
---
### 第 4 步:用 SSH 连接(新开一个终端)
#### 访客(推荐先试)
```bash
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no \
guest@127.0.0.1 -p 2222
```
密码:`guest123`
#### 管理员
```bash
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no \
admin@127.0.0.1 -p 2222
```
密码:`admin123`
#### Windows OpenSSH(避免本机 `~/.ssh/config` 干扰)
```bat
ssh -F NUL -o PreferredAuthentications=password -o PubkeyAuthentication=no guest@127.0.0.1 -p 2222
```
首次连接若提示主机密钥指纹,输入 `yes` 即可。
连接成功后应直接进入 **全屏 TUI**(不是系统 shell),顶栏类似:
```text
FastAPI SSH BBS · guest · Lv1 首页
```
---
### 第 5 步:基本操作
| 按键 | 作用 |
|------|------|
| `↑` / `↓` 或 `j` / `k` | 移动选择 |
| `Enter` | 进入 / 确认 |
| `q` | 返回上一级;**在首页再按 `q` 退出会话** |
| `ESC` | 返回 / 取消表单输入 |
| `Ctrl+C` | 强制断开当前 SSH 会话 |
| `/` | 搜索 |
| `1`–`5` | 首页快速进入对应菜单 |
发帖、回复等完整快捷键见下方「界面导览 → 快捷键」。
---
### 第 6 步:停止服务
1. 在 TUI 中 `q`(首页)或 `Ctrl+C` 退出 SSH 会话
2. 切到运行服务的终端,按 **`Ctrl+C`** 结束 `python main.py`
Windows 若端口仍被占用,可结束占用 2222 的进程后重启:
```powershell
Get-NetTCPConnection -LocalPort 2222 -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty OwningProcess -Unique |
ForEach-Object { Stop-Process -Id $_ -Force }
```
---
### 运行流程小结
```text
┌─────────────────────┐ ┌──────────────────────────────┐
│ 终端 A(服务端) │ │ 终端 B(客户端) │
│ │ │ │
│ pip install -r … │ │ │
│ python main.py … │◄────│ 保持监听 2222 │
│ (不要关) │ │ ssh guest@127.0.0.1 -p 2222 │
│ │ │ 密码 guest123 │
│ │ │ 全屏 TUI 操作 │
│ Ctrl+C 停止服务 │ │ q / Ctrl+C 断开会话 │
└─────────────────────┘ └──────────────────────────────┘
```
| 步骤 | 命令 / 动作 | 成功标志 |
|------|-------------|----------|
| 1. 进目录 | `cd …/terminal_bbs` | 能看到 `main.py` |
| 2. 装依赖 | `python -m pip install -r requirements.txt` | 无报错 |
| 3. 启服务 | `run.bat` / `run.sh` 或 `python main.py --port 2222` | 打印 `listening on …:2222` |
| 4. 登录 | `ssh guest@127.0.0.1 -p 2222` | 出现 TUI 首页 |
| 5. 使用 | `↑↓` / `Enter` / `q` | 选中标记 `▶` 会移动 |
| 6. 停止 | 客户端退出 → 服务端 `Ctrl+C` | 端口 2222 不再监听 |
---
## 界面导览
### 首页菜单
1. **板块浏览** — 进入讨论区列表
2. **搜索内容** — 搜索帖子与用户
3. **注册账号** — 用户名 → 密码 → 确认密码
4. **在线用户** — 当前 SSH 会话
5. **帮助** — 快捷键说明
### 默认板块
| 板块 | 描述 |
|------|------|
| Rust | Rust 语言、异步运行时与工程实践 |
| Linux | Linux、Shell、服务器与运维 |
| AI | 人工智能、模型与应用开发 |
| 开源 | 开源项目、工具与社区协作 |
| 游戏 | 游戏开发、主机与玩家闲聊 |
| 生活 | 工作、阅读、摄影与日常生活 |
### 快捷键
| 按键 | 作用 |
|------|------|
| `↑` / `↓` 或 `j` / `k` | 移动选择 |
| `Enter` | 进入 / 确认 |
| `q` | 返回上一级;**首页再按 `q` 退出会话** |
| `ESC` | 返回上一级;表单中取消输入 |
| `Ctrl+C` | 强制退出当前 SSH 会话 |
| `/` | 全局搜索 |
| `n` / `c` | 在板块帖子列表中发布新帖 |
| `Ctrl+S` | 保存帖子 / 回复 / 私信 |
| 单独一行 `.` 后回车 | 保存(兼容部分环境拦截 Ctrl+S) |
| `l` | 点赞当前帖子 |
| `L` | 点赞选中的回复 |
| `r` | 回复帖子 |
| `m` | 私信帖子作者 |
| `d` / `D` | 删除帖子(自己的;管理员可删全部) |
| 首页数字 `1`–`5` | 快速进入对应菜单项 |
### 发帖流程
1. 进入某板块的帖子列表
2. 按 `n` 或 `c`
3. 输入标题,`Enter`
4. 输入正文(多行)
5. `Ctrl+S`,或输入单独一行 `.` 再回车
---
## 命令行参数与配置
```bash
python main.py [--host HOST] [--port PORT] [--db PATH] [--host-key PATH]
```
| 参数 | 环境变量 | 默认 | 说明 |
|------|----------|------|------|
| `--host` | `BBS_HOST` | `0.0.0.0` | 监听地址 |
| `--port` | `BBS_PORT` | `2222` | SSH 端口 |
| `--db` | `BBS_DB` | `bbs.db` | SQLite 路径 |
| `--host-key` | `BBS_HOST_KEY` | `ssh_host_key` | SSH 主机私钥路径 |
| — | `BBS_CJK_SPACING` | `0` | 设为 `1` 时中文按远端风格插入字间距 |
示例:
```bash
# 仅本机、换端口、独立数据库
BBS_PORT=2223 python main.py --host 127.0.0.1 --db ./data/prod.db
```
---
## 项目结构
```text
terminal_bbs/
├── main.py # CLI 入口与事件循环
├── server.py # asyncssh SSH Server / Session
├── app.py # 会话状态机、页面路由、按键分发
├── tui.py # ANSI 全屏绘制(盒线 / 颜色 / 宽度)
├── db.py # SQLite schema、查询、种子数据
├── requirements.txt # Python 依赖
├── run.bat / run.sh # 一键启动脚本
├── ANALYSIS.md # 目标站交互逆向分析
├── README.md # 本文件(中英文)
├── captures/ # 远端界面抓取样例(分析用)
├── bbs.db # 运行时数据库(gitignore)
└── ssh_host_key # 运行时主机密钥(gitignore)
```
### 架构简述
```text
SSH Client ──► asyncssh Server ──► Session (app.py)
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
tui.py db.py sessions
(渲染帧) (SQLite) (在线列表)
```
每个 SSH 连接对应一个 `Session`:独立选中项、输入缓冲与视图栈;数据经 `Database` 共享,在线状态写入 `sessions` 表。
---
## 数据模型(概要)
| 表 | 用途 |
|----|------|
| `users` | 用户名、密码哈希、等级、角色 |
| `boards` | 板块名称与描述 |
| `posts` | 帖子标题/正文、浏览、点赞 |
| `replies` | 回复与点赞 |
| `likes` | 防重复点赞 |
| `messages` | 私信 |
| `sessions` | 当前在线连接 |
默认账号(种子数据,**生产环境务必修改**):
| 用户名 | 密码 | 角色 |
|--------|------|------|
| `guest` | `guest123` | 游客 |
| `admin` | `admin123` | 管理员 |
---
## 安全注意
1. **不要**把 `bbs.db`、`ssh_host_key`、真实密码提交到 Git(已由 `.gitignore` 忽略)。
2. 公网部署时:改默认密码、限制 `--host` / 防火墙、考虑仅内网或反代。
3. 密码使用 **bcrypt** 存储;注册用户名规则为 `3–32` 位字母/数字/`_`/`-`。
4. 本项目侧重教学与复刻演示,非银行级安全产品;上线前请自行审计。
---
## 故障排查
| 现象 | 建议 |
|------|------|
| `ssh` 连不上 / Connection refused | 确认服务端终端仍在运行且打印了 `listening`;检查端口是否为 2222 |
| 连接被公钥认证卡住 | 加 `-o PreferredAuthentications=password -o PubkeyAuthentication=no`;Windows 可加 `-F NUL` |
| 端口占用 | 换 `--port`,或结束占用 `2222` 的进程后重启 |
| **方向键 / 字母键无响应**,只有回车有时有用 | 必须使用当前版本:`server.py` 中 `line_editor=False`。更新代码后重启服务再连 |
| Windows 中文乱码 | 使用 Windows Terminal 或 `chcp 65001` |
| Ctrl+S 无响应 | 终端软件流控可能拦截;改用单独一行 `.` 再回车保存 |
| 游客无法发帖 | 预期行为;请先注册,用新账号重新 SSH 登录 |
| 首次连接主机密钥提示 | 输入 `yes` 接受;密钥文件变更后可删本机 `known_hosts` 中对应行 |
| `ModuleNotFoundError: asyncssh` | 未装依赖:`python -m pip install -r requirements.txt` |
---
## 相关文档
- [ANALYSIS.md](./ANALYSIS.md) — 目标站页面、快捷键与数据模型推导
- `captures/` — 远端 TUI 文本抓取样例
---
## 许可证
MIT License — 可自由使用、修改与再分发;请自担风险。
---
---
# English
**FastAPI SSH BBS** is a **full-screen bulletin board system served entirely over SSH**.
No browser and no special client: if you have an `ssh` command, you can browse boards, post, reply, search, and send private messages.
This repository reimplements the behavior of a live SSH BBS instance (see [ANALYSIS.md](./ANALYSIS.md) for the reverse-engineering notes). The stack is **Python 3.10+ / asyncssh / SQLite** so it runs easily on Windows and Linux.
```text
ssh guest@127.0.0.1 -p 2222
# password: guest123
```
---
## Features
| Area | Description |
|------|-------------|
| **SSH-native** | Embedded SSH server; login drops you into the TUI (not a system shell) |
| **Fullscreen TUI** | Box borders, header/footer chrome, cyan/yellow palette, `▶` selection |
| **Boards** | Six default boards: Rust, Linux, AI, Open Source, Games, Life |
| **Posts & replies** | List previews, detail view, threaded replies, view counters |
| **Social actions** | Like posts/replies, PM authors, delete own posts (admins delete any) |
| **Search** | Query titles, bodies, and usernames |
| **Accounts** | Guest browse; registered users can write; passwords hashed with bcrypt |
| **Who’s online** | Live session list with connect times |
| **Persistence** | SQLite; auto-schema + seed content on first run |
### Permission model
| Role | Capabilities |
|------|----------------|
| **Guest `guest`** | Browse, search, online list, registration flow |
| **Registered user** | Post, reply, like, PM, delete own posts |
| **Admin `admin`** | All of the above + delete any post |
---
## Correct startup & run flow
This project is an **SSH application server** (not HTTP / not a browser app). The correct flow is always:
1. **Start the server in one terminal and leave it running**
2. **Open a second terminal** and log in with an `ssh` client
3. When finished, leave the TUI session, then stop the server with `Ctrl+C` in the server terminal
---
### Step 0: Requirements
| Item | Requirement |
|------|-------------|
| OS | Windows 10+ / Linux / macOS |
| Python | **3.10+** (3.11 / 3.12 / 3.13 recommended) |
| SSH client | System OpenSSH (`ssh` available on PATH) |
| Dependencies | `asyncssh`, `bcrypt` (see `requirements.txt`) |
| Port | Default **2222** (configurable) |
Check:
```bash
python --version # or python3 --version
ssh -V
```
---
### Step 1: Enter the project directory
```bash
cd /path/to/terminal_bbs
```
Windows PowerShell / CMD example:
```bat
cd C:\AI\terminal_bbs
```
---
### Step 2: Install dependencies
```bash
python -m pip install -r requirements.txt
```
On Linux / macOS if the default binary is `python3`:
```bash
python3 -m pip install -r requirements.txt
```
---
### Step 3: Start the server (keep this terminal open)
#### Option A — one-shot scripts (recommended)
**Windows**
```bat
run.bat
```
**Linux / macOS**
```bash
bash run.sh
# or
chmod +x run.sh && ./run.sh
```
Scripts will install dependencies, then start `main.py` on port **2222**.
#### Option B — manual start
```bash
python main.py --host 0.0.0.0 --port 2222
```
Local-only bind:
```bash
python main.py --host 127.0.0.1 --port 2222
```
#### Success criteria
The console should print something like the following and the process must **stay running**:
```text
[bbs] FastAPI SSH BBS listening on 0.0.0.0:2222
[bbs] guest login: ssh guest@localhost -p 2222 (password: guest123)
[bbs] admin login: ssh admin@localhost -p 2222 (password: admin123)
[bbs] database: bbs.db
```
On first start the server also:
1. Generates host key file `ssh_host_key`
2. Creates SQLite database `bbs.db`
3. Seeds default boards, sample posts, and accounts
> **Note:** Closing that terminal or pressing `Ctrl+C` stops the service; clients will fail to connect. Keep a dedicated terminal for the server while developing.
---
### Step 4: Connect with SSH (new terminal)
#### Guest (try this first)
```bash
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no \
guest@127.0.0.1 -p 2222
```
Password: `guest123`
#### Admin
```bash
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no \
admin@127.0.0.1 -p 2222
```
Password: `admin123`
#### Windows OpenSSH (avoid local `~/.ssh/config` interference)
```bat
ssh -F NUL -o PreferredAuthentications=password -o PubkeyAuthentication=no guest@127.0.0.1 -p 2222
```
On first connect, accept the host key fingerprint with `yes`.
A successful login drops you into the **fullscreen TUI** (not a system shell). The header looks like:
```text
FastAPI SSH BBS · guest · Lv1 首页
```
---
### Step 5: Basic controls
| Key | Action |
|-----|--------|
| `↑` / `↓` or `j` / `k` | Move selection |
| `Enter` | Open / confirm |
| `q` | Go back; **on the home screen, `q` exits the session** |
| `ESC` | Go back / cancel form input |
| `Ctrl+C` | Force-disconnect the SSH session |
| `/` | Search |
| `1`–`5` | Jump to a home menu item |
Full key map: see **UI tour → Keybindings** below.
---
### Step 6: Stop the service
1. In the TUI, press `q` on home (or `Ctrl+C`) to leave the SSH session
2. In the server terminal, press **`Ctrl+C`** to stop `python main.py`
If port 2222 is still held on Windows after a crash:
```powershell
Get-NetTCPConnection -LocalPort 2222 -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty OwningProcess -Unique |
ForEach-Object { Stop-Process -Id $_ -Force }
```
---
### Flow summary
```text
┌─────────────────────┐ ┌──────────────────────────────┐
│ Terminal A (server) │ │ Terminal B (client) │
│ │ │ │
│ pip install -r … │ │ │
│ python main.py … │◄────│ listening on 2222 │
│ (keep open) │ │ ssh guest@127.0.0.1 -p 2222 │
│ │ │ password guest123 │
│ │ │ use fullscreen TUI │
│ Ctrl+C stop server │ │ q / Ctrl+C leave session │
└─────────────────────┘ └──────────────────────────────┘
```
| Step | Command / action | Success signal |
|------|------------------|----------------|
| 1. Enter dir | `cd …/terminal_bbs` | `main.py` is visible |
| 2. Install | `python -m pip install -r requirements.txt` | No errors |
| 3. Start | `run.bat` / `run.sh` or `python main.py --port 2222` | Prints `listening on …:2222` |
| 4. Login | `ssh guest@127.0.0.1 -p 2222` | Fullscreen TUI home |
| 5. Use | `↑↓` / `Enter` / `q` | Selection mark `▶` moves |
| 6. Stop | Client disconnect → server `Ctrl+C` | Port 2222 no longer listening |
---
## UI tour
### Home menu
1. **Browse boards**
2. **Search**
3. **Register** — username → password → confirm
4. **Online users**
5. **Help**
### Default boards
| Board | Description |
|-------|-------------|
| Rust | Language, async runtimes, engineering practice |
| Linux | Linux, Shell, servers & ops |
| AI | Models and application development |
| 开源 (Open Source) | Projects, tools, collaboration |
| 游戏 (Games) | Game dev, consoles, casual chat |
| 生活 (Life) | Work, reading, photography, daily life |
### Keybindings
| Key | Action |
|-----|--------|
| `↑` / `↓` or `j` / `k` | Move selection |
| `Enter` | Open / confirm |
| `q` | Back; **on home, press `q` again to exit the session** |
| `ESC` | Back; cancel form input |
| `Ctrl+C` | Force-disconnect the SSH session |
| `/` | Global search |
| `n` / `c` | New post (from a board’s post list) |
| `Ctrl+S` | Save post / reply / PM |
| Lone line `.` + Enter | Save (fallback when Ctrl+S is swallowed) |
| `l` | Like post |
| `L` | Like selected reply |
| `r` | Reply |
| `m` | Private message to author |
| `d` / `D` | Delete post (own; admin: any) |
| Digits `1`–`5` on home | Jump to menu item |
### Posting flow
1. Open a board’s post list
2. Press `n` or `c`
3. Enter title, then `Enter`
4. Write body (multi-line)
5. `Ctrl+S`, or a line containing only `.` then Enter
---
## CLI & configuration
```bash
python main.py [--host HOST] [--port PORT] [--db PATH] [--host-key PATH]
```
| Flag | Env var | Default | Meaning |
|------|---------|---------|---------|
| `--host` | `BBS_HOST` | `0.0.0.0` | Bind address |
| `--port` | `BBS_PORT` | `2222` | SSH port |
| `--db` | `BBS_DB` | `bbs.db` | SQLite path |
| `--host-key` | `BBS_HOST_KEY` | `ssh_host_key` | Host private key path |
| — | `BBS_CJK_SPACING` | `0` | `1` = spaced CJK rendering (reference style) |
Example:
```bash
BBS_PORT=2223 python main.py --host 127.0.0.1 --db ./data/prod.db
```
---
## Project layout
```text
terminal_bbs/
├── main.py # CLI entry & event loop
├── server.py # asyncssh server / sessions
├── app.py # State machine, views, key dispatch
├── tui.py # ANSI fullscreen renderer
├── db.py # SQLite schema, queries, seeds
├── requirements.txt
├── run.bat / run.sh
├── ANALYSIS.md # Behavioral analysis of the reference BBS
├── README.md # This file (ZH + EN)
├── captures/ # Captured TUI samples from the reference host
├── bbs.db # Runtime DB (gitignored)
└── ssh_host_key # Runtime host key (gitignored)
```
### Architecture sketch
```text
SSH Client ──► asyncssh Server ──► Session (app.py)
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
tui.py db.py sessions
(frames) (SQLite) (online list)
```
Each SSH connection owns a `Session` (selection, buffers, view stack). Content is shared via `Database`; presence is tracked in the `sessions` table.
---
## Data model (summary)
| Table | Purpose |
|-------|---------|
| `users` | Username, password hash, level, role |
| `boards` | Board names & descriptions |
| `posts` | Titles/bodies, views, likes |
| `replies` | Replies & likes |
| `likes` | Deduplicated like records |
| `messages` | Private messages |
| `sessions` | Live connections |
Seeded accounts (**change these in production**):
| Username | Password | Role |
|----------|----------|------|
| `guest` | `guest123` | guest |
| `admin` | `admin123` | admin |
---
## Security notes
1. **Never commit** `bbs.db`, `ssh_host_key`, or real credentials (covered by `.gitignore`).
2. On a public network: change defaults, lock down bind address/firewall, prefer private nets.
3. Passwords are stored with **bcrypt**; usernames must match `[A-Za-z0-9_-]{3,32}`.
4. This project is for learning/demo cloning—not a hardened multi-tenant product. Audit before production.
---
## Troubleshooting
| Symptom | What to try |
|---------|-------------|
| `ssh` fails / Connection refused | Ensure the server terminal is still running and printed `listening`; confirm port 2222 |
| Stuck on public-key auth | Add `-o PreferredAuthentications=password -o PubkeyAuthentication=no`; on Windows also try `-F NUL` |
| Port already in use | Change `--port`, or free `2222` and restart |
| **Arrows / letter keys do nothing**; Enter sometimes works | Use current code with `line_editor=False` in `server.py`. Restart the server after updating |
| Garbled Chinese on Windows | Use Windows Terminal or `chcp 65001` |
| Ctrl+S does nothing | Soft flow-control may eat `0x13`; use a lone `.` line + Enter to save |
| Guest cannot post | Expected; register and reconnect as the new user |
| Host key prompt on first connect | Type `yes`; if the key file changed, remove the old line from `known_hosts` |
| `ModuleNotFoundError: asyncssh` | Install deps: `python -m pip install -r requirements.txt` |
---
## Related docs
- [ANALYSIS.md](./ANALYSIS.md) — reference UI, keybindings, inferred schema
- `captures/` — text captures of the reference TUI
---
## License
MIT — free to use, modify, and redistribute; use at your own risk.