# plan **Repository Path**: AyolK/plan ## Basic Information - **Project Name**: plan - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-02 - **Last Updated**: 2026-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Root Console Web Root Console Web 是一个本地优先的 Web SSH 管理终端。它提供一个极简黑白 Web 界面,在浏览器中通过受保护的 WebSocket 打开 `root@127.0.0.1:22` SSH shell。 默认开发地址: ```txt http://127.0.0.1:15755 ``` > 安全警告:这个项目提供 root Web 终端。拿到 Web 登录权限的人基本等同于拿到服务器 root 权限。请默认只在本机、VPN、Tailscale/WireGuard、SSH tunnel 或可信内网中使用,不要直接暴露到公网。 ## 功能 - `/login` 管理员登录页 - `/console` 受保护控制台页 - xterm.js 浏览器终端 - WebSocket 到 SSH shell 的双向桥接 - 默认 SSH 目标:`root@127.0.0.1:22` - bcrypt 密码哈希 - session cookie 认证 - WebSocket session / Origin / IP 校验 - 单用户默认最多 1 个 SSH 会话 - 15 分钟 idle timeout - 基础审计日志 - 黑白极简 UI,遵循 `DESIGN.md` ## 安装依赖 ```bash npm install ``` ## 生成管理员密码哈希 ```bash npm run hash-password -- 'your-strong-password' ``` 复制输出的 bcrypt hash,写入 `config/default.yaml`: ```yaml auth: adminUser: admin passwordHash: "$2b$12$..." sessionSecret: "replace-with-a-long-random-secret" ``` 生成 session secret 示例: ```bash openssl rand -base64 48 ``` ## 配置 SSH key 默认配置: ```yaml ssh: host: 127.0.0.1 port: 22 username: root privateKeyPath: /etc/root-console/id_ed25519 ``` 推荐为本工具创建专用 key: ```bash sudo mkdir -p /etc/root-console sudo ssh-keygen -t ed25519 -f /etc/root-console/id_ed25519 -N '' -C root-console-web sudo chmod 600 /etc/root-console/id_ed25519 sudo cat /etc/root-console/id_ed25519.pub | sudo tee -a /root/.ssh/authorized_keys ``` 建议 SSHD 配置使用 key 登录,禁用 root 密码登录: ```txt PermitRootLogin prohibit-password PasswordAuthentication no PubkeyAuthentication yes ``` ## 开发启动 ```bash npm run dev ``` 打开: ```txt http://127.0.0.1:15755 ``` 如果 `auth.passwordHash` 或 `auth.sessionSecret` 仍为 `CHANGE_ME`,服务会拒绝启动。 ## 构建生产版本 ```bash npm run build npm start ``` 生产默认仍监听: ```txt 127.0.0.1:15755 ``` 可以使用环境变量覆盖部分配置: ```bash PORT=15755 HOST=127.0.0.1 SESSION_SECRET='...' ADMIN_PASSWORD_HASH='...' npm start ``` ## systemd 示例 ```ini [Unit] Description=Root Console Web After=network.target ssh.service [Service] Type=simple WorkingDirectory=/opt/root-console-web Environment=NODE_ENV=production ExecStart=/usr/bin/npm start Restart=on-failure RestartSec=5 User=root Group=root [Install] WantedBy=multi-user.target ``` 启用: ```bash sudo systemctl daemon-reload sudo systemctl enable --now root-console-web ``` ## Nginx 反向代理示例 建议只从 VPN/内网入口代理,不要公网裸露。 ```nginx server { listen 443 ssl http2; server_name console.example.internal; ssl_certificate /etc/letsencrypt/live/console/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/console/privkey.pem; location / { proxy_pass http://127.0.0.1:15755; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` 如果启用 HTTPS 反代,请在配置中设置: ```yaml security: requireHttps: true trustedProxy: true ``` 并把 `server.publicUrl` 改成实际 HTTPS 地址,否则 WebSocket Origin 校验会失败。 ## Caddy 示例 ```caddyfile console.example.internal { reverse_proxy 127.0.0.1:15755 } ``` ## 为什么默认只监听 127.0.0.1 这是 root Web 终端。默认绑定 `127.0.0.1` 可以避免服务被公网或局域网其他机器直接访问。远程访问应通过加密私有通道完成。 ## 安全远程访问方式 ### SSH tunnel ```bash ssh -L 15755:127.0.0.1:15755 user@server ``` 然后在本机打开: ```txt http://127.0.0.1:15755 ``` ### VPN / Mesh 网络 推荐使用: - Tailscale - WireGuard - ZeroTier 并用防火墙限制访问来源。 ## 审计日志 服务会向 stdout 输出 JSON 审计日志,包括: - `server_start` - `login_success` - `login_failure` - `logout` - `ws_rejected` - `ssh_session_start` - `ssh_session_end` - `ssh_session_error` - `idle_timeout` 默认不记录完整命令内容,避免泄露密钥、token 或密码。 ## 常见问题 ### 服务启动时报 `auth.passwordHash is CHANGE_ME` 先生成密码哈希并更新配置: ```bash npm run hash-password -- 'your-strong-password' ``` ### 服务启动时报 `auth.sessionSecret is CHANGE_ME` 生成长随机 secret 并更新配置: ```bash openssl rand -base64 48 ``` ### 登录成功后又回到登录页 如果你在 HTTP 本地开发,不要设置 `security.requireHttps: true`,否则 secure cookie 不会在 HTTP 下保存。 ### WebSocket 被拒绝 检查: - 是否已经登录; - `server.publicUrl` 是否和浏览器访问地址一致; - 访问 IP 是否在 `security.allowedIps` 中; - 是否已有一个活动 SSH 会话。 ### SSH 连接失败 检查: - 本机 SSH 服务是否运行; - root 是否允许 key 登录; - `ssh.privateKeyPath` 是否存在; - 私钥权限是否为 `600`; - 公钥是否加入 `/root/.ssh/authorized_keys`。 ## 不做的事情 本项目不会实现: - 登录绕过后门; - 固定默认密码; - 明文 root 密码; - 任意公网 IP 扫描; - 批量 SSH 登录; - 暴力破解; - 权限绕过; - 隐藏审计或逃避检测功能。