文档

快速开始 + 每部分每设备的功能说明(持续更新中)

SSH Everywhere 架构与技术栈

> 本文档说明 SSH Everywhere(SSH Everywhere Plus)的整体架构、用到的协议与技术栈,以及「为什么项目仍然叫 SSH Everywhere」。

---

一、项目定位

SSH Everywhere 是一套一站式服务器/设备远程运维面板,对标 1Panel / 宝塔。核心价值主张:无论设备在网络的哪个角落——有公网 IP、无公网 IP(NAT 后)、还是手机(Termux)——都能从这一个面板像 SSH 一样管理它。

面板本身部署在一台有公网 IP 的服务器上(本项目监听 0.0.0.0:5501),用户通过浏览器访问面板,再由面板通过不同协议「触达」目标设备。

---

二、整体架构(分层)

┌─────────────────────────────────────────────────────────────┐
│  浏览器前端(单页应用,模拟桌面操作系统)                        │
│  templates/desktop.html + static/js/*.js(17 个模块)         │
│  · 窗口管理器(WindowManager) · 任务栏 · 开始菜单 · 卡片仪表盘    │
│  · xterm.js 真终端 · Font Awesome 图标 · 原生 JS(无框架)      │
└──────────────────────────┬──────────────────────────────────┘
                           │ HTTP REST + SocketIO(默认 namespace)
┌──────────────────────────┴──────────────────────────────────┐
│  面板后端(Flask + Flask-SocketIO,Python)                   │
│  app.py(主应用/路由/SSH 连接池/健康检查)                      │
│  tunnel.py(反向隧道服务端,FRAME 协议)                        │
│  termux_sio.py(SocketIO /agent namespace 服务端)             │
│  transfer.py(文件传输) crashmon*.py(崩溃防护)               │
│  nginx_manager*.py(网站管理) backup*.py(备份)               │
│  SQLite 数据库(data/ssheverywhere.db)                       │
└───┬───────────────┬──────────────────┬──────────────────────┘
    │ SSH(paramiko)  │ FRAME 反向隧道    │ SocketIO(长轮询)
    │ 直连/经隧道      │ (0.0.0.0:4433)   │ (走 HTTP)
    ▼                ▼                  ▼
┌────────┐    ┌──────────────┐    ┌─────────────────┐
│ 有公网  │    │ 无公网 Linux  │    │ Android 手机     │
│ 服务器  │    │ /NAS/树莓派等  │    │ (Termux)        │
│ (sshd)  │    │ (tunnel_agent)│    │ (termux_agent)  │
└────────┘    └──────────────┘    └─────────────────┘

---

三、通信协议层(核心)

项目最初以 SSH 起家,如今内部实际运行着 4 种协议,各有分工:

1. SSH(paramiko)—— 主力通道

用途:所有「普通 Linux 服务器」的核心功能。

  • 系统管理(概览、进程、计划任务、防火墙、Docker、网站、镜像源、崩溃防护)
  • 终端(交互式 shell)
  • 文件管理(SFTP 上传/下载/编辑/压缩)
  • 健康检查(CPU/内存/磁盘/温度)
  • 命令执行

连接方式

  • 有公网 IP:面板直连 host:port
  • 无公网 IP:面板先通过反向隧道建一个本地代理端口,再 SSH 连 127.0.0.1:代理端口 → 设备 sshd。

> 换句话说,反向隧道的本质是「把 SSH 送到没有公网 IP 的设备上」,所以 SSH 仍然是最终落地协议。

2. FRAME 反向隧道协议 —— 穿透通道(自研)

用途:让「无公网 IP 的设备」能被面板触达。设备端主动「连出」到面板,建立一条反向 TCP 长连接,面板通过这条隧道下发命令、转发端口。

帧类型tunnel.py,加密模式,magic = b'SSHE'):

方向说明
FRAME_HEARTBEAT0x01双向心跳(10s 间隔,120s 超时)
FRAME_REGISTER0x02agent→服务端注册(上报 token/系统信息)
FRAME_FORWARD0x03服务端→agent建立 SSH 转发通道
FRAME_CLOSE0x04双向关闭通道
FRAME_INFO0x05agent→服务端健康信息上报
FRAME_FWD_OPEN0x06服务端→agent端口穿透:请求打开目标端口连接
FRAME_FWD_DATA0x07双向端口穿透:数据转发
FRAME_FWD_CLOSE0x08双向端口穿透:关闭
FRAME_CMD0x09服务端→agent远程命令执行
FRAME_CMD_RESP0x0Aagent→服务端命令结果返回

传输:TCP 长连接 + 加密(tunnel_crypto.py,Ed25519 密钥协商)。隧道服务端监听 0.0.0.0:4433

典型场景

  • 无公网 Linux 服务器的 SSH 穿透运维(隧道内再跑 SSH);
  • 端口穿透:把设备上的服务端口(如 8090)映射到面板公网端口,供外网访问。

> 易混概念:端口转发 vs 端口穿透

>

> 两者都是「把设备端口暴露出去」,但适用场景和实现完全不同:

>

> | | 端口转发(port-forward) | 端口穿透(port-tunnel) |

> |---|---|---|

> | 适用设备 | 有公网 IP 的服务器 | 无公网 IP 的穿透设备 |

> | 实现方式 | iptables/nftables DNAT,在目标服务器本机做 | 走 FRAME 反向隧道FRAME_FWD_OPEN/DATA/CLOSE 帧) |

> | 数据流 | 访问者 → 目标公网 → 目标端口 | 访问者 → 面板公网端口 → 反向隧道 → 设备端口 |

> | 依赖设备在线 | 不依赖(有公网 IP 随时可达) | 依赖(设备须保持 agent 在线) |

>

> 一句话:「转发」给有公网 IP 的服务器用(DNAT 直转);「穿透」给没公网 IP 的设备用(靠反向隧道搬运)。这也是项目里它们是两个独立功能面板的原因。

3. SocketIO(WebSocket 长轮询)—— Android 手机专用通道

用途:管理 Android 手机上的 Termux。手机移动网络 NAT 频繁切换、sshd 不稳,所以改用 SocketIO 稳定长轮询通道(方案照抄用户另一项目 phone2server,已在实机验证稳定)。

两个 namespace

  • /agent(手机 agent ↔ 面板服务端):register / monitor_data / p2s_ping / exec_result / pty_data / disconnect
  • 默认 namespace(浏览器 xterm ↔ 面板):agent_term_start / agent_term_input / agent_term_resize / agent_term_stop

跑在手机上的 termux_agent.py 通过 SocketIO 提供:

  • 系统管理(概览/进程/计划任务)
  • 终端(PTY 桥接)
  • 文件管理(exec 执行 python3 -c 出 JSON)
  • 健康监控(每 30s 上报:负载/内存/磁盘/电池/温度)

> 这是项目里唯一真正「不走 SSH」的通道——因为 Android 手机彻底去掉了 sshd。

4. HTTP REST —— 前端与后端之间

浏览器前端通过 REST API(/api/...)调用面板后端,同时用 SocketIO 默认 namespace 做终端等实时双向通信。

---

四、后端模块(Python,约 1.18 万行)

模块行数职责
app.py5217Flask 主应用:全部 API 路由(138 个)、SSH 连接池、健康检查、SocketIO 挂载
tunnel.py2412反向隧道服务端(FRAME 协议)、SSH 代理、端口转发管理
tunnel_agent.py713反向隧道 agent(跑在设备端)
tunnel_crypto.py隧道加密(Ed25519 密钥协商)
termux_agent.py445SocketIO agent(跑在手机 Termux 端)
termux_sio.py328SocketIO 服务端(/agent namespace + PTY 桥接)
transfer.py373文件传输(「发送到」功能,SFTP 中转)
crashmond.py575崩溃防护守护(部署到目标机)
crashmon.py214崩溃防护面板端逻辑
nginx_manager.py550Nginx 网站管理
nginx_sites_ext.py232Nginx 站点扩展(SSL/伪静态等)
backup.py283备份/还原
remote_backup.py443远程备份(跨设备)
languages.py多语言(i18n)

依赖requirements.txt,极简):flaskflask-socketioparamikowerkzeug

---

五、前端模块(原生 JS,17 个模块)

模块职责
desktop.js桌面主界面:窗口管理器、任务栏、开始菜单、卡片仪表盘
server.js服务器增删改查、通用弹窗(showModal)
system-panel.jsLinux 服务器系统管理面板(走 SSH)
agent-panel.jsTermux 手机系统管理面板(走 SocketIO)
filemgr.jsLinux 文件管理器(SFTP)
terminal.js终端(xterm.js)
tunnel.js穿透运维面板
port-tunnel.js端口穿透管理
docker.js / docker-gallery*.jsDocker 容器管理 + 镜像大全
app-store.js应用大全
task.js后台任务面板
backup.js备份面板
termux.jsTermux 安装/使用教程
i18n.js国际化
cms-install.jsCMS 一键安装

前端无框架,纯原生 JS + xterm.js(终端)+ Font Awesome(图标),整个界面模拟一个桌面操作系统(可拖拽窗口、任务栏、开始菜单)。

---

六、数据存储

  • SQLitedata/ssheverywhere.db):服务器卡片、端口转发、穿透记录、用户、任务等。
  • 文件系统:备份文件、隧道密钥(tunnel_keys/)、静态资源。

---

七、部署

  • 面板:systemd 服务 ssh-everywhere.service,监听 0.0.0.0:5501
  • 反向隧道:监听 0.0.0.0:4433(FRAME 协议)。
  • 目标设备端 agent 以服务形式常驻(Linux 用 systemd / Termux 用 termux-services)。

---

八、三种设备的触达路径一览

设备类型连接方式最终落地协议说明
有公网 IP 的 Linux 服务器面板直连SSH最直接的场景
无公网 IP 的 Linux 服务器(NAS/树莓派等)反向隧道建代理 → SSHSSH(经 FRAME 隧道搬运)FRAME 是 SSH 的「搬运工」
Android 手机(Termux)SocketIO 长轮询SocketIO(唯一不用 SSH 的)手机 sshd 已彻底移除

---

九、关于项目名称「SSH Everywhere」

结论:不建议改名。 理由:

1. SSH 仍是绝对主体:除了 Android 手机这一个子场景,其余所有功能(Linux 服务器管理、穿透运维、文件传输、健康检查)最终都落在 SSH 上。

2. FRAME 反向隧道的本质就是「把 SSH 送到任何地方」:它解决的是「设备没公网 IP 时,怎么让 SSH 触达」的问题,语义上仍是「SSH 无处不在」。

3. SocketIO 只是实现细节,不是品牌定位:它是「Android 手机因为 sshd 不稳」这一特定场景的技术兜底,用户不会因为「手机不走 SSH」而觉得项目名「名不副实」。

4. 改名成本高、收益低:项目名散布在代码、文档、安装脚本、README、用户认知里,改名反而制造困惑。

若要微调,可在品牌宣传语上强调「SSH 为核心、多协议协同」,或在文档(如 docs/termux.md)里明确标注「Android 手机走 SocketIO 稳定通道」,把「SSH Everywhere」理解为「像 SSH 一样随处可管理」,而非字面的「只用 SSH 协议」。