Files
smy-skills/linux-ssh-operator-skill/SKILL.md
shumengya 766eb935a9 improve linux-ssh-operator-skill: bug fixes, rsync support, tunneling docs
- Fix dry-run bug in ssh_alias_setup.sh (pub key check skipped when key was never generated)
- Remove dead code in ssh_run.sh (-- check after host arg was never reachable)
- Add --rsync/--delete flags to ssh_copy.sh for incremental rsync transfers
- Add -C/--compress flag to ssh_run.sh for slow-link connections
- Expand SKILL.md/SKILL.zh-CN.md: tunneling, jump host, SSH multiplexing, Docker ops
- Expand ssh-playbook.md: port forwarding, bastion, ControlMaster, structured troubleshooting table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 17:26:47 +08:00

198 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: linux-ssh-operator-skill
description: 通过 SSH 连接并操作 Linux 服务器:执行远程命令、查看日志、管理 systemd 服务、传输文件scp/rsync、配置 SSH 别名、安装公钥启用免密登录、SSH 隧道/端口转发、跳板机、内网穿透、排障。用户提到 ssh/scp/rsync、远程服务器 IP:端口、配置 ssh 别名、ssh-copy-id、免密登录、systemctl/journalctl、部署到服务器、在服务器上运行命令、远程拷贝文件、SSH 隧道、端口转发、跳板机、堡垒机、服务器上看一下、帮我连上服务器、查看服务器日志 等场景时使用。
---
# Linux SSH Operator
## Overview
Use SSH to connect to Linux servers and perform safe, repeatable remote operations (commands, logs, services, file transfer, alias bootstrap, passwordless login, tunnels).
## Workflow
1. Confirm authorization and the target (host, port, user).
2. Prefer SSH keys (recommended) for non-interactive runs; avoid storing passwords in files or chat logs.
3. Start with read-only checks, then apply changes, then verify.
4. If a password prompt or interactive tool is required, run the SSH command in a real terminal/TTY (or enable TTY in your runner).
## Quick Start
### Set up SSH keys (recommended)
Generate a key (ed25519):
```bash
ssh-keygen -t ed25519 -C "codex" -f ~/.ssh/id_ed25519
```
Install the public key on the server (example uses port 22):
```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 USER@SERVER_IP
```
Optional: create an alias in `~/.ssh/config`:
```sshconfig
Host my-server
HostName SERVER_IP
Port 22
User USER
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
```
Then connect:
```bash
ssh my-server
```
### Bootstrap alias + passwordless login
When the user provides an alias, host/IP, and password and wants `ssh alias` to work immediately:
1. Write or update the alias with the helper script:
```bash
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_alias_setup.sh my-server 192.168.1.10 --user root --install-key
```
2. If `ssh-copy-id` prompts for a password, run in a TTY and enter the password once.
3. Verify passwordless login:
```bash
ssh -o BatchMode=yes my-server 'echo SSH_OK; id -un 2>/dev/null || echo root'
```
4. Remind the user that `scp` and `rsync` can reuse the same alias:
```bash
scp ./file.txt my-server:/root/
rsync -av ./dir/ my-server:/root/dir/
```
Notes:
- `scripts/ssh_alias_setup.sh` auto-generates `~/.ssh/id_ed25519` if it does not exist.
- It updates `~/.ssh/config` idempotently and defaults to `root`, port `22`, and `StrictHostKeyChecking=accept-new`.
- For tests, set `SSH_CONFIG_FILE=/path/to/temp-config`.
### Run remote commands
- Direct:
```bash
ssh my-server uname -a
```
- With sudo (often needs a TTY):
```bash
ssh -tt my-server sudo systemctl status nginx --no-pager
```
- Via wrapper script (consistent options; supports env defaults like `REMOTE_USER`, `REMOTE_PORT`, `REMOTE_KEY`):
- If you installed this Skill globally in `~/.claude/skills/`, use the absolute paths below (recommended so both Claude Code + OpenCode can find it).
```bash
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_run.sh my-server -- uname -a
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_run.sh --tty --sudo my-server -- systemctl restart nginx
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_run.sh --compress my-server -- cat /var/log/big.log
```
### Transfer files
Upload (scp):
```bash
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_copy.sh push my-server ./local.txt /tmp/local.txt
```
Download (scp):
```bash
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_copy.sh pull my-server /var/log/syslog ./syslog
```
Incremental sync (rsync — preferred for directories or large files):
```bash
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_copy.sh --rsync push my-server ./dist/ /var/www/html/
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_copy.sh --rsync --delete push my-server ./dist/ /var/www/html/
~/.claude/skills/linux-ssh-operator-skill/scripts/ssh_copy.sh --rsync pull my-server /var/log/ ./logs/
```
### SSH Tunneling / Port Forwarding
Local forward (access remote service on a local port):
```bash
# Access remote MySQL (3306) at localhost:13306
ssh -L 13306:127.0.0.1:3306 my-server -N
```
Remote forward (expose a local port on the server):
```bash
# Make local :8080 accessible on server's :18080
ssh -R 18080:127.0.0.1:8080 my-server -N
```
Jump host (bastion → target):
```bash
ssh -J bastion-user@bastion:22 target-user@target-host
```
Or configure in `~/.ssh/config`:
```sshconfig
Host target-internal
HostName 10.0.0.50
User ubuntu
ProxyJump bastion
```
### SSH Multiplexing (faster repeated connections)
Add to `~/.ssh/config` to reuse the same TCP connection:
```sshconfig
Host *
ControlMaster auto
ControlPath ~/.ssh/ctrl-%h-%p-%r
ControlPersist 60s
```
The first `ssh my-server` opens a master connection; subsequent connections reuse it without re-handshaking.
## Common Ops (snippets)
- Disk: `df -h`, `du -sh /path/* | sort -h`
- Memory/CPU: `free -h`, `top`, `ps aux --sort=-%mem | head`
- Logs: `journalctl -u SERVICE -n 200 --no-pager`, `tail -n 200 -f /path/log`
- Services: `systemctl status|restart|stop|enable SERVICE`
- Networking: `ss -lntp`, `ip a`, `ip r`, `curl -v http://127.0.0.1:PORT/`
- Docker: `docker ps`, `docker logs -f CONTAINER`, `docker exec -it CONTAINER bash`
- Config test: `nginx -t`, `sshd -T`
- Open files: `lsof -i :PORT`, `fuser PORT/tcp`
## Safety
- Never store or paste passwords in repo files or chat logs.
- Avoid `StrictHostKeyChecking=no`; prefer verifying host keys (or use `accept-new` only when appropriate).
- For destructive commands (rm, shutdown, firewall changes), ask for explicit user confirmation and show the exact command first.
## References
- SSH security + troubleshooting: `references/ssh-playbook.md`
## Scripts
- `scripts/ssh_alias_setup.sh`: create/update SSH aliases and optionally run `ssh-copy-id`.
- `scripts/ssh_run.sh`: run remote commands with consistent options (supports `--compress`, `--tty`, `--sudo`).
- `scripts/ssh_copy.sh`: push/pull files via scp or rsync (use `--rsync` for incremental transfers).