本机 SSH 入口
从任意电脑远程执行 OPPO 办公本的命令
连接信息
- 跳板机
- oppo.aipanghu.cn
- 外网端口
- 22222
- 用户名
- panghu
- 认证方式
- 仅公钥(密码登录已禁用)
- 实际目标
- NAw9082070(OPPO 办公本)
一条命令连上
ssh -p 22222 -i ~/.ssh/id_ed25519 panghu@oppo.aipanghu.cn "hostname"
注意:这个 SSH 只支持「执行命令」,不提供交互式 shell。
远端是 PowerShell,多条命令用 ; 连接,不能用 &&(会报「不是此版本中的有效语句分隔符」)。
# 跑 Python
ssh -p 22222 -i ~/.ssh/id_ed25519 panghu@oppo.aipanghu.cn "python -V"
# 多步命令(; 不是 &&)
ssh -p 22222 ... "cd D:\code\oppoToolBox; python ledger/verify_schema.py"
# 看目录
ssh -p 22222 ... "Get-ChildItem D:\code"
第一次使用:配置公钥
1
在你的电脑上生成密钥(如果还没有)
已经有 ~/.ssh/id_ed25519 就跳过这步。
ssh-keygen -t ed25519 -C "你的电脑名"
2
取出公钥内容
注意是 .pub 后缀那个,不是没有后缀的私钥。
# Windows
type %USERPROFILE%\.ssh\id_ed25519.pub
# macOS / Linux
cat ~/.ssh/id_ed25519.pub
只能发 .pub 文件的内容。私钥(没有 .pub 后缀)绝对不要发给任何人,包括我。
3
把公钥追加到本机的授权文件
这一步在 OPPO 办公本上执行。
# 方式一:手动追加(Windows PowerShell)
Add-Content -Path "$env:USERPROFILE\.ssh\authorized_keys" -Value "ssh-ed25519 AAAA...你的公钥"
# 方式二:让对方自己加(在有权限的机器上)
ssh -p 22222 ... "powershell -Command \"Add-Content ...\""
ssh -p 22222 -i ~/.ssh/id_ed25519 panghu@oppo.aipanghu.cn "hostname"
# 期望输出: NAw9082070
当前已授权
| 公钥 | 来源 | 状态 |
| ssh-ed25519 ...KjB0iw0cgq | 本机 auto_query@cindy | 已授权 |
加公钥:把 .pub 整行发我,或在本机跑
cd D:\code\oppoToolBox; .venv\Scripts\python.exe scriptsdd_ssh_key.py "ssh-ed25519 AAAA... 备注"
脚本会校验格式、拒绝私钥误贴、按指纹去重,写完立刻做一次真实握手验证。新钥匙立即生效,不用重启服务。
当前已授权(按指纹,注释仅作标识别)
| 指纹 | 备注 | 用途 |
SHA256:VW/MqJWBZVS5…+To0E | auto_query@cindy | 本机自测 |
SHA256:FXvO3oawNEv1…flD1E | panghu@macbookair-relay | Mac 采集器读本机指标 |
SHA256:DhIVFGOKy501…SpUz4 | root@iZ2vc9…sr0Z | VPS 反连 / 健康检查 |
注释不是身份,指纹才是。同一把钥匙注释写成什么指纹都不变;注释一样也可能是两把不同的钥匙(默认注释都是 用户名@主机名,很容易撞)。认机器只认指纹。
能做什么 / 不能做什么
| 能力 | 支持 | 说明 |
| 执行命令 | ✅ | PowerShell -Command,支持管道/重定向 |
| 跑 Python / Node / Java | ✅ | PATH 已内置这些工具目录 |
| 读当前用户文件 | ✅ | 工作目录是 C:\Users\w9082070 |
| 交互式 shell | ❌ | 只支持单条命令 |
| scp 传文件 | ❌ | 暂未开启,走 file.aipanghu.cn 中转 |
| 提权到管理员 | ❌ | 以普通用户身份运行 |
稳定性:看门狗自愈
本机 sshd 用 scripts/sshd_watchdog.py 守护,每 60 秒做一次真实握手(不是看端口),并检查 VPS 上 22222 是否在监听。连续 2 次失败就整棵进程树重启。
# 单次体检
.venv\Scripts\python.exe scripts\sshd_watchdog.py --once
# 看历史
Get-Content logs\local_sshd_watchdog.log -Tail 20
为什么不用 netstat 看端口:端口在监听 ≠ 服务可用。asyncssh 的 event loop 被打断后,进程还在、端口还在,但握手到 publickey 就永久不回包——旧方案对此完全无感,会一直认为健康。
工作原理
你的电脑
│ ssh -p 22222
▼
VPS oppo.aipanghu.cn:22222 (ufw 已放行)
│ SSH 反向隧道(本机主动建立)
▼
OPPO 办公本 :22022 (asyncssh 服务端,用户态)
│ PowerShell
▼
执行命令 → 原路返回结果
为什么这么绕:OPPO 办公本没有公网 IP,也没有管理员权限装 Windows 自带的 sshd。
所以用纯 Python 的 SSH 服务端(用户态)+ 主动连 VPS 建反向隧道,绕过这两个限制。
故障排查
| 现象 | 原因 / 处理 |
| Connection timed out | 本机关机或隧道断了。开机后会自动重连(启动项已配) |
| Permission denied (publickey) | 你的公钥没加到 authorized_keys |
| 命令能连但报「无法识别」 | 该命令不在 PATH 里,用绝对路径 |
| 连上但立刻断开 | 没带命令参数,这个入口不支持交互 shell |
安全说明
- 仅公钥认证,密码登录已禁用,无法被暴力破解
- 以普通用户身份运行,不能提权
- 端口 22222 对公网开放,但没有私钥进不来
- 私钥只保存在你自己的电脑上,不经过任何服务器