siqi2000/ShellPort
GitHub: siqi2000/ShellPort
基于 Node.js 的多终端 Web 管理面板,支持通过 SSH 反向隧道从公网随时访问和控制本地或远程设备的 Shell 会话。
Stars: 0 | Forks: 0
### 快速开始(仅局域网)
```
npm install
```
在项目根目录创建 `.env` 文件:
```
SHELLPORT_PASSWORD=你的密码
```
然后启动服务器:
```
npm start
```
服务器默认运行在 3000 端口。访问地址:
- **本机访问**: http://localhost:3000
- **局域网其他设备**: http://\<局域网IP\>:3000(启动时控制台会打印)
打开后会跳转到 `/login` 输入密码。
### 远程访问(公网)
目标:让家里那台**没有公网 IP**(在路由器/NAT 后面)的机器上跑 ShellPort,依然可以从任何地方访问 —— 4G 上的手机、咖啡馆里的笔记本,等等。
核心思路是用一台你已有(或者花点小钱租)的云服务器做**中转**,通过 **SSH 反向隧道**把家里的端口透出去。哪怕是最便宜的 1 核 VPS 也够用,因为它只是在转发 TCP:
```
[你的手机 / 笔记本]
│
│ http://<中转服务器IP>:8080
▼
┌───────────────────┐
│ 中转服务器 │ (有公网 IP,比如月付几块的 VPS)
│ 端口 8080 ◄─────┼──┐
└───────────────────┘ │
│ SSH 反向隧道(从家里发起)
│ ssh -R 0.0.0.0:8080:localhost:3000 relay
│
┌───────────────────┐ │
│ 家里的机器 │──┘
│ ShellPort :3000 │
└───────────────────┘
```
**为什么用这种方案?**
- ✅ **不需要在家里路由器上做端口映射** —— 任何 NAT 都能用,包括宿舍、酒店、手机热点
- ✅ **不需要 DDNS** —— 你家公网 IP 怎么变都无所谓
- ✅ **中转服务器不存任何东西** —— 它只转发字节流;隧道一停,入口立刻消失
- ✅ **完全按需开关** —— 由你决定什么时候开放远程访问,启动/关闭 `tunnel.bat` 即可
- ✅ **便宜** —— 任何带公网 IP 的云 VPS 都可以(腾讯云轻量、阿里云、AWS Lightsail、DigitalOcean 都行)
#### 配置步骤
**1. 中转服务器**(一次性):
确保已安装 OpenSSH server 且可以用密钥登录。然后修改 `sshd_config` 允许远程端口绑定:
- **Linux**:`/etc/ssh/sshd_config` → 加 `GatewayPorts yes` → `sudo systemctl restart sshd`
- **Windows Server**:`C:\ProgramData\ssh\sshd_config` → 加 `GatewayPorts yes` → `Restart-Service sshd`
放行 8080 端口(或任何你选的端口):
- 云厂商的**安全组 / 防火墙**:入站 TCP 8080,来源 `0.0.0.0/0`
- 操作系统防火墙:
- Windows: `New-NetFirewallRule -DisplayName ShellPort -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow`
- Linux: `ufw allow 8080`
**2. 家里的机器**(一次性):
在 `~/.ssh/config` 配一个 SSH 别名,省得每次输完整地址:
```
Host myrelay
HostName 1.2.3.4
User your_user
Port 22
IdentityFile ~/.ssh/id_ed25519
```
把示例脚本复制一份,然后设置 `SERVER_ALIAS` 为你的别名:
```
cp tunnel.bat.example tunnel.bat
# 然后编辑 tunnel.bat,把 SERVER_ALIAS=myrelay 改成你的别名
```
(`tunnel.bat` 已加入 `.gitignore`,不会泄露你的个人配置。)
**3. 每次想要远程访问时:**
```
# 终端 1 —— 本地启动 ShellPort
npm start
# 终端 2(或者直接双击)—— 开启隧道
tunnel.bat
```
然后在任何地方打开浏览器访问 `http://<中转服务器IP>:8080`,输密码登录,就进到你家里的 shell 了。
要**关闭**远程访问:直接关掉 `tunnel.bat` 的黑窗口(或 `Ctrl+C`)。公网入口立即消失。本地的 ShellPort 不受影响,继续在局域网可用。
#### 安全说明
- `.env` 里的登录密码是你家 shell 暴露在公网时**唯一的防线** —— 务必用强密码。`.env` 已加入 `.gitignore`。
- Token 只存在内存里,服务器一重启就全失效。
- 这套方案走的是 **HTTP**,不是 HTTPS。对个人使用通常够用,因为关键是密码,而流量本身已经在公网上跑了。如果想加 TLS,可以在中转服务器上用 nginx + Let's Encrypt 终止 HTTPS,再反代到 `127.0.0.1:8080`。
- 想再保守一点?把隧道改成只绑定到中转服务器的 `127.0.0.1:8080`(去掉 `0.0.0.0:`),然后在客户端用 SSH 端口转发访问 —— 这样公网上根本看不到任何端口。
### 技术栈
- **后端**: Node.js、Express、ws(WebSocket)、node-pty
- **前端**: xterm.js、原生 JavaScript
- **远程访问**: SSH 反向隧道(`ssh -R`)
### 工作原理
服务器为每个终端会话生成一个 PTY 进程(Windows 上为 PowerShell,Linux/macOS 上为 bash)。浏览器通过 WebSocket 连接服务器,使用 xterm.js 渲染终端输出。多个客户端可以连接到同一个会话 —— 任意客户端的键盘输入都会转发到 PTY,输出广播给所有连接者。
至于远程访问部分,`ssh -R 0.0.0.0:8080:localhost:3000 relay` 这条命令告诉中转服务器的 sshd:在它自己的 8080 端口监听,并把每一个收到的字节通过已经建立的 SSH 连接,转发回家里机器的 `localhost:3000`。中转服务器上不需要装任何额外的程序,只要 OpenSSH 就够了。
### 版本历史
完整的版本记录在 [GitHub Releases](https://github.com/siqi2000/ShellPort/releases)。重点版本:
- **[v1.3.0](https://github.com/siqi2000/ShellPort/releases/tag/v1.3.0)** —— 多问题验证登录、目标实时可达性指示器、TCP 桥接目标(无需在远端机器装 OpenSSH server 也能把它当成目标)
- **[v1.2.0](https://github.com/siqi2000/ShellPort/releases/tag/v1.2.0)** —— 多目标会话:每个 tab 可以是本地 shell,也可以是 `~/.ssh/config` 里任意一台服务器的 SSH 连接
- **[v1.1.0](https://github.com/siqi2000/ShellPort/releases/tag/v1.1.0)** —— 密码登录 + 通过中转服务器的 SSH 反向隧道远程访问
### 许可证
ISC标签:Awesome, GNU通用公共许可证, IP 地址批量处理, MITM代理, Node.js, SSH客户端, TCP隧道, Web工具, Web终端, XXE攻击, 中继服务器, 内存分配, 内网穿透, 反向代理, 后端开发, 在线终端, 局域网共享, 系统管理, 终端复用, 远程Shell, 远程控制