inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-control
Claude Code and agent skill by inspired-by-atmosphere/ops-troubleshooting-skills
- community
Checking that the SKILL.md file is still in the repository.
Use when controlling another host over SSH. 打通密钥免密+日常遥控+踩坑清单。
Install
npx vskill@latest install inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-controlSKILL.md
SSH 遥控局域网另一台主机
从 Hermes 所在机器(Windows 11 + git-bash)SSH 进入局域网内另一台主机(Ubuntu/Linux/Windows),实现"跨设备 agent 活动"。本技能=打通流程+日常遥控+坑位;各目标机的连接状态与密钥位置放 references/。
触发场景
- 用户说"你来操控那个小主机/服务器""跨设备""SSH 连过去"
- 需要在新主机上跑命令、装服务、起常驻进程,或日后在目标端装第二套 Hermes 当独立 agent
打通流程(Windows 控制端 → Ubuntu 目标端)
1. 识别目标设备(不要凭端口猜身份!)
- ping 扫段:
for i in $(seq 1 254); do ping -n 1 -w 200 192.168.1.$i >/dev/null 2>&1 && echo "UP $i"; done - arp 拿 MAC(中文 Windows 输出要转码):
arp -a | iconv -f GBK -t UTF-8 - 端口探测(无 nmap/nc 时用 bash /dev/tcp):
timeout 3 bash -c 'exec 3<>/dev/tcp/<ip>/<port>' - MAC OUI 上网查厂商(wireshark OUI 工具 / maclookup)
- ⚠️ 本会话实测教训:开着 SMB(445) 的 ≠ 目标主机(.3 开了 445 却不是小主机;.4 一开始全端口关、装好 SSH 才开 22,才是目标)。端口开放只说明"能不能连",目标身份必须让用户确认(问 IP/主机名),别猜。
2. 目标端开 SSH(Ubuntu 22.04)
Ubuntu Server 常自带 openssh-server:apt install若显示"已是最新版",跳过安装直接跑下面 systemctl 两步即可。
验证:控制端 timeout 3 bash -c 'exec 3<>/dev/tcp/<ip>/22' 通 = 服务已起。
3. 密钥免密(一次配好)
- 控制端生成专用密钥(独立文件名,不污染默认 key):
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_<主机名> -N "" -C "hermes@<来源>-to-<目标>"
- 授权命令让用户在目标端自己执行(Hermes 不碰密码,杜绝密码过聊天):
mkdir -p ~/.ssh && echo "<公钥内容>" >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
- 方式 B-0(最快,实测)——pty 里直接跑 `ssh-copy-id`:
terminal(background=true, pty=true)执行ssh-copy-id -i ~/.ssh/<key>.pub -o PreferredAuthentications=password <user>@<ip>→ poll 到password:提示后process(action='submit', data='<密码>')→ 回显Number of key(s) added: 1即完成。不用手工登录、不用贴公钥、不用建密码文件。 - 方式 B-1(pty 交互登录部署,用户直接给密码时):
terminal(background=true, pty=true)起ssh <user>@<ip>(全新机用密码;配好 key 后-i <key>),等password:提示后 process(write) 输密码 + process(submit) 回车(Windows PTY 裸\n不触发回车);登录后在目标端执行授权命令(mkdir -p ~/.ssh && echo '<pubkey>' >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys);exit后 BatchMode 验证免密。echo '<pw>' | sudo -S <cmd>在非交互 ssh 里可用:代价是每次调用都过一次 sudo 审批门(用户已授权自主操作时自动放行)——把它当常规手段用,别误以为被禁而绕远路;长任务先sudo -S -v缓存凭证,后续同连接内普通sudo即可。可行替代(实测):本地建密码文件printf 'pw\n' > <本地路径>,ssh host 'sudo -S <cmd>' < <本地密码文件>——stdin 重定向喂密码,命令串里不含密码,能过策略;密码文件放工作区(如 Documents/电脑管家),~/.ssh/是受保护路径写不进。注意远程命令里别再写< /dev/null(会覆盖 stdin,密码喂不进去) - 测试(BatchMode 防挂起等密码):
ssh -i ~/.ssh/id_ed25519_<主机名> -o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=8 <用户名>@<ip> 'hostname; whoami; uname -sr' - 钥匙是否装对:对端跑
ssh-keygen -lf ~/.ssh/authorized_keys,其指纹必须 == 本机ssh -v -i <key> <user>@<ip> 'true' 2>&1 | grep Offering的指纹;对端报 invalid format = 钥匙复制时坏了
4. 日常遥控
- 单条:
ssh -i <key> <user>@<ip> '命令' - 传文件:
scp -i <key> 本地文件 <user>@<ip>:/路径/ - 多步脚本:先 scp 过去再执行;长任务 ssh 里挂后台
5. 目标机还没有 SSH(Live USB / 全新系统 / PE)→ 一行命令自助开通
目标机此刻没有 sshd、也没有可用凭据时(Live USB 会话、全新系统、装机救援场景),不要让用户在机器前敲一长串命令:用局域网里常开的 Linux 主机当"落点机"分发脚本,用户只贴一行。
- 落点机放脚本并起 HTTP 服务(用户级即可,无需 sudo):
cd ~/usb_kit && setsid nohup python3 -m http.server 8899 >httpd.log 2>&1 < /dev/null & crontab -e 加 @reboot cd /home/<user>/usb_kit && setsid nohup python3 -m http.server 8899 >httpd.log 2>&1 < /dev/null & 防重启后失效
- 双向可达必须实测:控制端
curl -s --noproxy "*" http://<落点机>:8899/live_ssh.sh | head;再从目标机所在网络拉一次(可借同网其他能 ssh 的机器试)——两边都通才让用户贴 - 用户侧一行:
curl -s http://<落点机>:8899/live_ssh.sh | sudo bash(Ubuntu Live 会话默认用户ubuntu,免密 sudo) - 脚本要点:等 DHCP(最多 40s)→ 改写 apt 源为清华镜像(Live 直连 archive.ubuntu.com 很慢)→
apt-get install -y openssh-server→ 公钥追加进 live 用户与/root的authorized_keys(sort -u去重、chmod 700/600、chown回用户)→systemctl restart ssh,失败依次退service ssh restart//usr/sbin/sshd→ 打印hostname -I与ss -tln | grep :22结果。模板 →templates/live_ssh.sh - 落点机必须常开的 Linux 主机:Windows 笔记本入站被防火墙挡(实测同网服务器连 ping 都不通),别把笔记本当分发源或期望被反向连入
Pitfalls
- 复制命令全角坑(本会话实测):用户从聊天/手机复制命令时,
-y的横杠会变全角-y,报"无效选项"。→ 给用户命令要提醒"手动敲别复制";命令尽量无特殊符号;用户报"无效选项"先怀疑横杠字符。 - 全新 Ubuntu 未 `apt update` 直接 install → "无法定位软件包 / 缺少要操作的目标文件"。先
apt update再装。 - 非交互 SSH 不加载 ~/.bashrc(本会话实测):PATH 写在 .bashrc 的自定义安装(
~/.node/bin、~/.go/bin)在ssh host 'cmd'里找不到 →node: command not found但用户明明装了。解法:全路径调用 / 先export PATH=$PATH:~/.node/bin/bash -lc '...'。探测目标机装了啥,先看 .bashrc/.profile 的 PATH 追加,别用裸command -v就下"没装"结论。 - Permission denied → 先查 auth.log 的 "Invalid user"(本会话实测):
sudo grep sshd /var/log/auth.log | tail -5出现Invalid user X from <ip>= 用户名不存在(不是钥匙问题),用户名一个字母都不能猜(差一个字母就 Invalid user)。 - 同一 IP 换了系统 → host key 变化,ssh 直接拒连:目标机重启进 Live 会话/U 盘系统/重装系统时,同 IP 上等于一台"新机器",ssh 报
REMOTE HOST IDENTIFICATION HAS CHANGED并禁用密码/键盘交互认证(看起来像攻击告警,实际是预期行为)。一次性救援会话直接-o StrictHostKeyChecking=no;长期主机才值得ssh-keygen -R <ip>清旧行重种。 - 用了专用密钥文件后每次要
-i <key>;或写~/.ssh/config配 Host 别名免-i。 - 组网节点显示 `offline` ≠ 机器掉线:控制面长连接被校园网/门户网掐掉时数据面仍然通(
tailscale ping有 pong、SSH 照连),在目标机重启tailscaled即恢复;分层判断:局域网 IP 可达性 → 组网通道(tailscale ping)→ 控制面在线状态,逐层排除。 - Windows 控制端 git-bash 自带 ssh/scp(10.x)无需另装;无 nmap/nc,端口探测用 /dev/tcp。
- 目标端写操作(装服务/改配置)先向用户请示,按用户审批纪律执行。
- 目标机若是 Windows(反向 SSH,如笔记本被控端):需启用 Windows OpenSSH Server(默认未装,
sc query sshd报 1060 = 未安装)。 - 非交互 SSH 里 `sudo` 报 "a terminal is required to read the password":BatchMode 无 tty 跑不了 sudo——远程需要 sudo 的命令要么走本机 pty 交互,要么直接让用户在其本机终端执行,别在 BatchMode 里硬跑。
- 多 `sudo -S` 命令链共享 stdin 会卡(本会话实测):
ssh host 'sudo -S bash -c "a && b && c"' < pw这类多命令链不稳定——密码文件喂一次后 stdin 就 EOF,偶发卡在密码提示后直到超时。可靠模式:同连接内 `sudo -S -v` 缓存凭证后后续 sudo 免密:ssh host 'sudo -S -v && sudo cmd1 && sudo cmd2 && echo DONE' < pw(sudo -v 读一次密码,5 分钟窗口内同连接后续 sudo 免密)。⚠️ sudo 凭证按 tty 隔离,跨 ssh 连接不生效——每个新连接都要重新sudo -S -v;且 sudo 命令本身卡住时(如 systemctl stop 等一个杀不掉的进程)不要反复重试,先诊断再动。 - 给用户交付目标机操作命令时,用户常在目标机本机图形终端手动执行(非 SSH 远程):命令按"命令 + 预期输出"结构直接给(用户要的是能照着跑的终端结构,勿长篇解释原理),SSH 连接步骤标注"仅远程需要,本机可跳过";文件放目标机桌面(中文 Ubuntu 桌面路径是
~/桌面不是~/Desktop)。 - ssh 远程启动后台任务会挂住直到 timeout,但进程实际已启动:
ssh host 'cd ~/x && setsid bash run.sh > log 2>&1 < /dev/null & sleep 2; echo started'这类命令几乎必超时(ssh 等后台进程组的管道 EOF),超时≠失败——勿重复启动(会起两份),改用第二条短查询确认:pgrep -f <脚本名>+ 输出文件是否在增长。长驻服务(HTTP server 等)同理:命令尾部的sleep N; ss -tln | grep <port>会被一起拖住 → 拆成两条 ssh:第一条只管启动(允许它超时返回),第二条单独查端口/进程;确认已起就不要再启。 - 一条 SSH 连写多个 `setsid bash xxx.sh &` 只部分生效(实测一条 ssh 里 3 个后台启动只起 1-2 个,ssh 会话回收竞态):多条后台线必须每条单独一条 ssh 启动,起完
pgrep -f <特征串>核对进程数,缺哪条补哪条——与上条"挂住≠失败、勿重复启动"互补:先确认,再按缺补启。 - 长任务(编译/大下载/批量转换)要脱离调用方存活:agent 会话和
delegate_task子代理都是随网络中断/会话结束一起死,跑在它们里面的长活会连进度一起丢。做法:整套步骤写成远端脚本,ssh host 'cd /path && setsid nohup bash job.sh >/dev/null 2>&1 < /dev/null &'起成独立进程,脚本内部exec >> job.log 2>&1把所有输出落进日志;之后只轮询日志与产物(tail -20 job.log、pgrep -af job.sh、产物是否出现/变大、下载体积是否在长)判断进度,不再守着那条 ssh。子代理半途死掉时,它留下的中间物(已装好的工具链、已下好的源码)要接着用,别从头再来。 - `pkill -f <pattern>` 的 pattern 只要字面出现在同一命令行里就会自杀:-f 匹配完整命令行,执行这条 ssh 的 bash 自己也含该字符串 → 自杀断连,后半段命令不执行;更阴的是pattern 不一定是你想杀的那个东西(同一命令里后面跟着的 URL、文件名、日志名都会被匹配到)。症状是静默:输出为空、exit 0,别把"什么都没打印"读成"没有进程"。最可靠是按 PID 杀:
ps -eo pid,etime,cmd | grep <特征>拿 PID 后kill <pid>;要批量用pgrep -f <pattern> | grep -v $$ | xargs -r kill。且 pkill 与后续清理/重启分两条 ssh执行,别连在一条里赌它不自杀。 - 目标机无 venv 时装 Python 包:Ubuntu 缺 python3-venv(ensurepip 不可用,
python3 -m venv直接报错)→ 用python3 -m pip install --user -i https://pypi.tuna.tsinghua.edu.cn/simple <包>装系统 Python(22.04 的 pip 22.0.2 无 PEP668 externally-managed 限制)。小依赖缺失会静默出错:脚本 try-except 吞掉import dotenv失败 → .env 不加载 → 报"未设置 key"——先查 python-dotenv 是否装了再怀疑 key。
进阶
- 目标端装第二套 agent = 双 agent 跨设备。落地要点:远端无代理时直连 GitHub 会 429/超时 → 先配镜像或代理;装成 systemd 服务才有掉线自愈;桌面 GUI 组件在无显示器环境别装。
- 要访问的主机不在同一 LAN(宿舍/校园网/异地):先判直连可行性(netcheck 读数)、搞清认证对象(上行路由器)、portal 侦察(无头浏览器抓接口)、口令安全核验,再决定是否借道组网(Tailscale 之类)。
- 每台目标机的连接参数(IP/用户名/密钥文件名)自己另建文档记:
references/里只放通用方法,主机清单属于本地信息,不要跟着技能一起公开。 - 跨机大文件传输:局域网 scp vs Tailscale relay vs 公网中转站实测(gofile/litterbox/uguu/奶牛快传逐个坑位)→
references/cross-host-file-transfer.md
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ssh-remote-host-control/SKILL.md
Popularity
- 7-day trend score
- 5
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-control)