inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-control

Claude Code and agent skill by inspired-by-atmosphere/ops-troubleshooting-skills

Trust tier 3
  • community
Source check pending

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-control

SKILL.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)
bash
sudo apt update && sudo apt install -y openssh-server # 全新机必须先 apt update!
sudo systemctl enable --now ssh # Ubuntu 服务名是 ssh
sudo ufw allow ssh
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 主机当"落点机"分发脚本,用户只贴一行。

  1. 落点机放脚本并起 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 & 防重启后失效

  1. 双向可达必须实测:控制端 curl -s --noproxy "*" http://<落点机>:8899/live_ssh.sh | head;再从目标机所在网络拉一次(可借同网其他能 ssh 的机器试)——两边都通才让用户贴
  2. 用户侧一行:curl -s http://<落点机>:8899/live_ssh.sh | sudo bash(Ubuntu Live 会话默认用户 ubuntu,免密 sudo)
  3. 脚本要点:等 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
  4. 落点机必须常开的 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

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-control/badge)](https://verified-skill.com/skills/inspired-by-atmosphere/ops-troubleshooting-skills/ssh-remote-host-control)

Something wrong with this skill or its page? Tell us.