190 lines
6.1 KiB
Markdown
190 lines
6.1 KiB
Markdown
# Linux SSH Operator
|
||
|
||
通过 SSH 连接并操作 Linux 服务器的 Claude Code 技能——执行远程命令、查看日志、管理 systemd 服务、传输文件。
|
||
|
||
## 触发场景
|
||
|
||
当你说这些时会激活此技能:
|
||
- `ssh` / `scp` / `rsync`
|
||
- 远程服务器 IP 和端口
|
||
- `systemctl` / `journalctl`
|
||
- 部署到服务器
|
||
- 在服务器上运行命令
|
||
- 向/从远程服务器拷贝文件
|
||
|
||
## 快速上手
|
||
|
||
### 1. 配置 SSH 密钥(推荐)
|
||
|
||
```bash
|
||
# 生成 ed25519 密钥
|
||
ssh-keygen -t ed25519 -C "codex" -f ~/.ssh/id_ed25519
|
||
|
||
# 将公钥复制到服务器
|
||
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 USER@SERVER_IP
|
||
|
||
# 可选:在 ~/.ssh/config 中添加主机别名
|
||
Host my-server
|
||
HostName SERVER_IP
|
||
Port 22
|
||
User USER
|
||
IdentityFile ~/.ssh/id_ed25519
|
||
IdentitiesOnly yes
|
||
```
|
||
|
||
### 2. 执行远程命令
|
||
|
||
```bash
|
||
# 直接执行
|
||
ssh my-server uname -a
|
||
|
||
# 使用 sudo(需要 TTY)
|
||
ssh -tt my-server sudo systemctl restart nginx
|
||
|
||
# 通过包装脚本执行(统一选项)
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_run.sh my-server -- uname -a
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_run.sh --tty --sudo my-server -- systemctl restart nginx
|
||
```
|
||
|
||
### 3. 传输文件
|
||
|
||
```bash
|
||
# 上传(push)
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh push my-server ./local.txt /tmp/local.txt
|
||
|
||
# 下载(pull)
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh pull my-server /var/log/syslog ./syslog
|
||
|
||
# 强制 rsync 方式同步目录
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh --method rsync -r push my-server ./dir /tmp/dir
|
||
|
||
# 强制 tar 打包传输(大量小文件)
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh --tar push my-server ./many-small-files/ /tmp/
|
||
|
||
# Rsync 排除文件并同步
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh --method rsync -r \
|
||
--exclude '.git' --exclude 'node_modules' --exclude '*.log' \
|
||
--delete push my-server ./project/ /tmp/project/
|
||
|
||
# 显示传输进度和统计
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh --method rsync -r \
|
||
--progress --stats push my-server ./dir /tmp/
|
||
|
||
# 预演模式(不执行,只显示命令)
|
||
~/.claude/skills/linux-ssh-operator/scripts/ssh_copy.sh --method tar \
|
||
--dry-run push my-server ./dir /tmp/
|
||
```
|
||
|
||
## 脚本说明
|
||
|
||
### ssh_run.sh
|
||
|
||
统一选项的远程命令执行脚本。
|
||
|
||
```bash
|
||
ssh_run.sh [选项] 主机 -- 命令 [参数...]
|
||
|
||
选项:
|
||
-u, --user 用户名 指定 SSH 用户
|
||
-p, --port 端口 SSH 端口(默认 22)
|
||
-i, --key 路径 私钥文件路径
|
||
-t, --tty 强制分配 pseudo-tty
|
||
--sudo 命令前加 sudo
|
||
--sudo-non-interactive 使用 sudo -n(密码需要时失败)
|
||
--connect-timeout 秒 连接超时(默认 10 秒)
|
||
--dry-run 仅打印 ssh 命令,不执行
|
||
-h, --help 显示帮助
|
||
|
||
环境变量默认值:
|
||
REMOTE_USER, REMOTE_PORT, REMOTE_KEY, REMOTE_CONNECT_TIMEOUT
|
||
```
|
||
|
||
### ssh_copy.sh
|
||
|
||
统一选项的文件传输脚本(支持 scp/rsync/sftp,自动选择最优方式)。
|
||
|
||
```bash
|
||
ssh_copy.sh [选项] push 主机 本地路径 远程路径
|
||
ssh_copy.sh [选项] pull 主机 远程路径 本地路径
|
||
|
||
选项:
|
||
-u, --user 用户名 指定 SSH 用户
|
||
-p, --port 端口 SSH 端口(默认 22)
|
||
-i, --key 路径 私钥文件路径
|
||
--connect-timeout 秒 连接超时(默认 10 秒)
|
||
-r, --recursive 递归拷贝目录
|
||
--accept-new 设置 StrictHostKeyChecking=accept-new
|
||
|
||
# 传输方式
|
||
-m, --method {auto,scp,rsync,sftp}
|
||
传输方式(默认 auto)
|
||
--tar 强制 tar+scp 打包传输
|
||
--tar-format {tar,tar.gz,tar.xz}
|
||
tar 格式(默认 tar.gz)
|
||
--tar-threshold N 触发打包的文件数量阈值(默认 20)
|
||
|
||
# 压缩
|
||
--compress {auto,yes,no}
|
||
启用压缩(默认 auto)
|
||
--compress-level N 压缩级别 1-9(默认 6)
|
||
|
||
# Rsync 专用
|
||
--exclude 模式 排除匹配(可多次指定)
|
||
--delete 同步后删除目标多余文件
|
||
--whole-file 强制全量传输
|
||
|
||
# 输出
|
||
--progress 显示传输进度
|
||
--stats 显示传输统计
|
||
--dry-run 仅打印命令,不执行
|
||
-h, --help 显示帮助
|
||
|
||
环境变量默认值:
|
||
REMOTE_USER, REMOTE_PORT, REMOTE_KEY, REMOTE_CONNECT_TIMEOUT
|
||
|
||
自动选择规则:
|
||
- 单文件 → scp
|
||
- 目录同步 → rsync -a
|
||
- 大量小文件 (>20个) → tar.gz + scp
|
||
- 大文件 (>100MB) → rsync -z
|
||
- 需要排除文件 → rsync --exclude
|
||
|
||
注意:`--tar` 与 `--method rsync/scp/sftp` 不要混用。
|
||
|
||
## 常用操作
|
||
|
||
| 任务 | 命令 |
|
||
|------|------|
|
||
| 磁盘使用 | `df -h`, `du -sh /路径/* \| sort -h` |
|
||
| 内存/进程 | `free -h`, `ps aux --sort=-%mem \| head` |
|
||
| 查看日志 | `journalctl -u 服务名 -n 200 --no-pager` |
|
||
| 服务状态 | `systemctl status 服务名 --no-pager` |
|
||
| 重启服务 | `systemctl restart 服务名`(需要 sudo + tty) |
|
||
| 网络状态 | `ss -lntp`, `ip a`, `ip r` |
|
||
|
||
## 安全规范
|
||
|
||
- **禁止** 在文件或聊天记录中存储密码
|
||
- **避免** `StrictHostKeyChecking=no`——优先验证 host key,或仅对临时主机使用 `accept-new`
|
||
- **破坏性命令**(rm、shutdown、防火墙变更)需要用户明确确认,并先展示完整命令
|
||
- **先读后写**——先做只读检查,再执行变更,最后验证
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
linux-ssh-operator/
|
||
├── SKILL.md # 技能定义和触发条件
|
||
├── README.md # 本文件
|
||
├── agents/
|
||
│ └── openai.yaml # Agent 接口配置
|
||
├── references/
|
||
│ └── ssh-playbook.md # SSH 操作参考文档
|
||
└── scripts/
|
||
├── ssh_run.sh # 远程命令执行包装脚本
|
||
└── ssh_copy.sh # 文件传输包装脚本(scp/rsync/sftp)
|
||
```
|
||
|
||
## 参考资料
|
||
|
||
- [SSH 操作参考](references/ssh-playbook.md) — 常用 SSH 任务、故障排查和安全最佳实践
|