Files
server-manager/tools/skill-ssh.md
chrome-storm-c442 c21b263b24 v1.9.25: show server group in --list and --info CLI output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 06:55:32 -05:00

339 lines
18 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.
# Скилл /ssh — управление удалёнными серверами
Ты управляешь удалёнными серверами через универсальную CLI-утилиту.
Поддерживаются: SSH, SQL (MariaDB/MSSQL/PostgreSQL), Redis, S3/MinIO, Grafana, Prometheus, WinRM (PowerShell/CMD).
## ВАЖНО — Безопасность
- **НИКОГДА не читай файлы** в директории `~/.server-connections/` напрямую
- **НИКОГДА не читай** файлы `encryption.py`, `servers.json`, `settings.json`
- **НИКОГДА не выводи пароли, IP-адреса, логины, порты** пользователю и в контекст нейронки
- **НИКОГДА не используй** `--list-full` — он выводит IP/порты/логины в контекст AI
- **Все операции только через** `python ~/.server-connections/ssh.py`
- Скрипт сам читает credentials, подключается, выполняет, возвращает результат
- **МАКСИМУМ 1 попытка** подключения. Если timeout/ошибка — сообщи, НЕ повторяй
- fail2ban банит IP после 5-10 неудач — спам попытками УБЬЁТ доступ к серверу
- **Серверы можно добавлять** через `--add` (см. ниже) или через GUI ServerManager
## Аргументы
Пользователь передаёт через `$ARGUMENTS`. Разбери и выполни.
## КРИТИЧНО — СНАЧАЛА ПРОВЕРЬ ТИП СЕРВЕРА
**ПЕРЕД ЛЮБОЙ операцией** с сервером — **ОБЯЗАТЕЛЬНО** выполни `--list` и посмотри колонку `Type`.
**ЗАПРЕЩЕНО** угадывать тип сервера. MinIO/S3 — это НЕ SSH, Redis — это НЕ SSH, MariaDB — это НЕ SSH.
**Тип сервера определяет КАКИЕ команды использовать. Использование команд не того типа — СЛОМАЕТ операцию.**
| Тип | Команды | НЕ использовать |
|-----|---------|-----------------|
| `ssh` | `ALIAS "command"`, `--upload`, `--download`, `--ping`, `--install-key` | — |
| `telnet` | `ALIAS "command"` (без SFTP/sudo/ключей) | `--upload`, `--download` |
| `mariadb` / `mssql` / `postgresql` | `--sql`, `--sql-databases`, `--sql-tables` | `ALIAS "command"` |
| `redis` | `--redis`, `--redis-info`, `--redis-keys` | `ALIAS "command"` |
| `s3` (MinIO, AWS S3, и др.) | `--s3-buckets`, `--s3-ls`, `--s3-upload`, `--s3-download`, `--s3-delete`, `--s3-url`, `--s3-create-bucket` | `ALIAS "command"`, `--upload`, `--download` |
| `grafana` | `--grafana-dashboards`, `--grafana-alerts` | `ALIAS "command"` |
| `prometheus` | `--prom-query`, `--prom-targets`, `--prom-alerts` | `ALIAS "command"` |
| `winrm` | `--ps`, `--cmd` | `ALIAS "command"` |
| `rdp` / `vnc` | Только GUI | всё |
**`ALIAS "command"` (shell-команды типа ls, cat, mkdir) — ТОЛЬКО для типов `ssh` и `telnet`.**
```bash
# ❌ НЕПРАВИЛЬНО — MinIO/S3 это НЕ SSH, нельзя выполнять shell-команды
python ~/.server-connections/ssh.py "minio-alias" "ls /bucket"
python ~/.server-connections/ssh.py "minio-alias" "mkdir /bucket/folder"
# ✅ ПРАВИЛЬНО — S3-команды для типа s3
python ~/.server-connections/ssh.py --s3-ls "minio-alias" bucket
python ~/.server-connections/ssh.py --s3-upload "minio-alias" "D:/file.txt" bucket/folder/file.txt
# ❌ НЕПРАВИЛЬНО — Redis это НЕ SSH
python ~/.server-connections/ssh.py "redis-alias" "INFO"
# ✅ ПРАВИЛЬНО
python ~/.server-connections/ssh.py --redis-info "redis-alias"
# ❌ НЕПРАВИЛЬНО — MariaDB это НЕ SSH
python ~/.server-connections/ssh.py "mariadb-alias" "SHOW DATABASES"
# ✅ ПРАВИЛЬНО
python ~/.server-connections/ssh.py --sql-databases "mariadb-alias"
```
## Общие команды
### Список серверов (безопасный — alias, тип, группа, ключ, заметки)
```bash
python ~/.server-connections/ssh.py --list
```
### Информация о сервере (безопасная — без IP/логина/пароля/порта)
```bash
python ~/.server-connections/ssh.py --info ALIAS
```
### Статус всех серверов (alias + тип + online/offline)
```bash
python ~/.server-connections/ssh.py --status
```
Проверяет каждый сервер по его типу: SSH-подключение, SQL-коннект, Redis PING, HTTP health-check и т.д.
### Обновить заметки сервера
```bash
python ~/.server-connections/ssh.py --set-note ALIAS "описание сервера"
```
### Удалить сервер
```bash
python ~/.server-connections/ssh.py --remove ALIAS
```
**Спроси подтверждение у пользователя перед удалением!**
### Добавить сервер
```bash
python ~/.server-connections/ssh.py --add ALIAS IP PORT USER PASSWORD [--type ssh|telnet|mariadb|mssql|postgresql|redis|grafana|prometheus|winrm|rdp|s3] [--note "описание"] [--database DB] [--token TOKEN]
```
- Автоматически устанавливает SSH-ключ после добавления
- Обновляет `~/.ssh/config`
- **Спроси у пользователя все параметры перед добавлением!**
- Тип сервера по умолчанию — ssh. Для других типов (mariadb, redis и т.д.) — добавь через GUI
## SSH-команды (тип: ssh)
### Выполнить команду на сервере
```bash
python ~/.server-connections/ssh.py ALIAS "command"
```
Пример: `python ~/.server-connections/ssh.py investor "uptime"`
### Выполнить команду БЕЗ sudo
```bash
python ~/.server-connections/ssh.py ALIAS --no-sudo "command"
```
### Загрузить файл на сервер (ЕДИНСТВЕННЫЙ правильный способ)
```bash
python ~/.server-connections/ssh.py ALIAS --upload "D:/path/local/file" //remote/path/file
```
**ВАЖНО (Windows/Git Bash):** remote path ОБЯЗАТЕЛЬНО с двойным слешем `//home/...`, `//tmp/...`. Одинарный `/` будет сконвертирован Git Bash в Windows-путь и сломает SFTP.
**НИКОГДА не используй echo/base64/cat/stdin для передачи файлов — только `--upload`!**
### Скачать файл с сервера (ЕДИНСТВЕННЫЙ правильный способ)
```bash
python ~/.server-connections/ssh.py ALIAS --download //remote/path/file "D:/path/local/file"
```
Remote path тоже с `//`.
**НИКОГДА не используй scp/rsync/cat для скачивания — только `--download`!**
### Установить SSH-ключ на сервер
```bash
python ~/.server-connections/ssh.py ALIAS --install-key
```
### Проверить доступность сервера
```bash
python ~/.server-connections/ssh.py ALIAS --ping
```
## SQL-команды (типы: mariadb, mssql, postgresql)
### Выполнить SQL-запрос
```bash
python ~/.server-connections/ssh.py --sql ALIAS "SELECT * FROM users LIMIT 10"
```
### Список баз данных
```bash
python ~/.server-connections/ssh.py --sql-databases ALIAS
```
### Список таблиц
```bash
python ~/.server-connections/ssh.py --sql-tables ALIAS
python ~/.server-connections/ssh.py --sql-tables ALIAS mydb
```
## Redis-команды (тип: redis)
### Выполнить Redis-команду
```bash
python ~/.server-connections/ssh.py --redis ALIAS "GET mykey"
python ~/.server-connections/ssh.py --redis ALIAS "SET mykey myvalue"
```
### Информация о Redis
```bash
python ~/.server-connections/ssh.py --redis-info ALIAS
```
### Поиск ключей (SCAN)
```bash
python ~/.server-connections/ssh.py --redis-keys ALIAS "user:*"
```
## S3-команды (тип: s3) — MinIO, AWS S3, любое S3-совместимое хранилище
**MinIO = тип `s3`.** Когда пользователь говорит "MinIO" или "S3" — используй ТОЛЬКО `--s3-*` команды.
**НЕ пытайся** выполнять shell-команды (`ls`, `mkdir`, `cat`) на S3-серверах — это не SSH!
**Папки в S3 не существуют** — это префиксы. "Создать папку" = загрузить файл с префиксом в ключе (например `bucket/folder/file.txt`).
### Список бакетов
```bash
python ~/.server-connections/ssh.py --s3-buckets ALIAS
```
### Список объектов
```bash
python ~/.server-connections/ssh.py --s3-ls ALIAS bucket
python ~/.server-connections/ssh.py --s3-ls ALIAS bucket/prefix/
```
### Загрузить файл в S3
```bash
python ~/.server-connections/ssh.py --s3-upload ALIAS "D:/local/file" bucket/key
```
### Скачать файл из S3
```bash
python ~/.server-connections/ssh.py --s3-download ALIAS bucket/key "D:/local/file"
```
### Удалить объект
```bash
python ~/.server-connections/ssh.py --s3-delete ALIAS bucket/key
```
### Получить ссылку на файл (presigned URL)
```bash
python ~/.server-connections/ssh.py --s3-url ALIAS bucket/key
python ~/.server-connections/ssh.py --s3-url ALIAS bucket/key 86400
```
По умолчанию ссылка действует 1 час (3600 сек). Второй аргумент — время жизни в секундах (например 86400 = 24 часа).
### Создать бакет
```bash
python ~/.server-connections/ssh.py --s3-create-bucket ALIAS bucket-name
```
### Типичный workflow: "создай папку и залей файл"
```bash
# 1. Посмотри бакеты
python ~/.server-connections/ssh.py --s3-buckets ALIAS
# 2. "Создать папку" = просто загрузить файл с нужным путём (prefix)
python ~/.server-connections/ssh.py --s3-upload ALIAS "D:/file.txt" mybucket/newfolder/file.txt
# 3. Проверить
python ~/.server-connections/ssh.py --s3-ls ALIAS mybucket/newfolder/
# 4. Получить ссылку
python ~/.server-connections/ssh.py --s3-url ALIAS mybucket/newfolder/file.txt
```
## Grafana-команды (тип: grafana)
### Список дашбордов
```bash
python ~/.server-connections/ssh.py --grafana-dashboards ALIAS
```
### Список оповещений
```bash
python ~/.server-connections/ssh.py --grafana-alerts ALIAS
```
## Prometheus-команды (тип: prometheus)
### Выполнить PromQL-запрос
```bash
python ~/.server-connections/ssh.py --prom-query ALIAS "up"
python ~/.server-connections/ssh.py --prom-query ALIAS "rate(http_requests_total[5m])"
```
### Список целей (targets)
```bash
python ~/.server-connections/ssh.py --prom-targets ALIAS
```
### Список оповещений
```bash
python ~/.server-connections/ssh.py --prom-alerts ALIAS
```
## WinRM-команды (тип: winrm)
### PowerShell
```bash
python ~/.server-connections/ssh.py --ps ALIAS "Get-Process"
python ~/.server-connections/ssh.py --ps ALIAS "Get-Service | Where-Object {$_.Status -eq 'Running'}"
```
### CMD
```bash
python ~/.server-connections/ssh.py --cmd ALIAS "dir C:\\"
```
## Альтернативный способ (только SSH с установленным ключом)
```bash
unset SSH_ASKPASS && unset DISPLAY && ssh ALIAS "command"
```
## Поведение
- **Auto-sudo** (SSH): если user на сервере не root — команды автоматически оборачиваются в `sudo -S`, пароль подаётся через stdin. Тебе НЕ нужно добавлять `sudo` в команду
- **--no-sudo** (SSH): если команда не требует root (например `ls`, `cat`), используй `--no-sudo` для скорости
- **Windows SSH — автосанитизация**: при подключении к Windows серверам (определяется по alias/notes/os) Linux-команды автоматически транслируются в Windows-эквиваленты. Можно спокойно писать `ls`, `cat`, `grep`, `ps`, `df` — скрипт сам переведёт в `dir`, `type`, `Select-String`, `Get-Process`, и т.д. Pipe-цепочки (`cat file | grep error`) автоматически оборачиваются в PowerShell. Кодировка принудительно UTF-8 (`chcp 65001`). Команды `powershell ...`, `pwsh ...`, `cmd /c ...` проходят без изменений (passthrough). `sudo` автоматически удаляется, `chmod`/`chown` пропускаются с предупреждением
- **Timeout**: 120 секунд на SSH-команду, 10 секунд на SQL/Redis/HTTP-запросы, 15 секунд на подключение
- **SSH-ключ**: пробуется первым, fallback на пароль если ключ не подходит
- **Прогресс**: upload/download файлов >=1MB показывают 25/50/75% milestone, итог с размером/временем/скоростью
- **Тип сервера**: определяется автоматически из конфигурации. `--list` показывает тип каждого сервера
## Правила
- Отвечай на русском языке
- Показывай результат каждой операции
- При ошибках — объясняй причину и предлагай решение
- Если timeout — предложи проверить VPN/firewall/панель хостера
- Файлы создаваемые на сервере должны иметь права 664 (owner+group rw)
- При вопросе о серверах — СНАЧАЛА `--list`, потом `--info ALIAS` если нужны детали
- SQL-запросы: используй `LIMIT` для больших таблиц, чтобы не перегружать вывод
- Redis: используй SCAN, а не KEYS для больших баз
## КРИТИЧНО — Передача файлов
**ВСЕГДА используй `--upload` / `--download` для передачи файлов.** Это SFTP-протокол с автоматическими фичами:
- **Файлы >10MB:** chunked upload с resume — при обрыве продолжит с того места
- **Retry:** adaptive retry — до 30 попыток для больших файлов (exponential backoff, min 5s)
- **SHA256 верификация:** автоматическая проверка целостности после загрузки
- **Atomic rename:** запись в .part файл → проверка → переименование
- **Keepalive:** SSH keepalive каждые 15 секунд — не обрывается NAT/роутером
- **Прогресс:** 25/50/75% для файлов >1MB
- **Resume:** при повторном запуске `--upload` автоматически продолжает с .part файла (не начинает заново)
- **Windows SSH:** SHA256 через PowerShell `Get-FileHash`, пути автоматически нормализуются
```bash
# Загрузить файл на сервер (SFTP)
python ~/.server-connections/ssh.py ALIAS --upload "D:/local/file" //remote/path/file
# Скачать файл с сервера (SFTP)
python ~/.server-connections/ssh.py ALIAS --download //remote/path/file "D:/local/file"
```
**Поведение при обрыве:** соединение оборвалось → ждёт 5-30 сек → переподключается → проверяет .part файл на сервере → дозаливает с того места. Если файл полностью залит — проверяет SHA256 → atomic rename `.part` → финальный файл. Работает даже на нестабильных каналах (тестировано: 250MB через 6 reconnect'ов).
**ЗАПРЕЩЕНО** использовать shell-команды как **способ передачи файлов** на/с сервера:
- `echo "длинный_контент" > remote_file` — обрежет данные, сломает бинарники
- `base64` чанки через exec_command — ненадёжно, ломается на больших файлах (exit 127)
- `cat local_file | ssh` или stdin-пайпы — не работает через Paramiko exec_command
- Любые "креативные" shell-методы переноса содержимого файлов
**Это НЕ запрещает** использовать `echo`, `cat`, `base64` как обычные команды на сервере:
- `ALIAS "echo hello"` — OK (выполнение команды)
- `ALIAS "cat /etc/hosts"` — OK (чтение файла на сервере)
- `ALIAS "base64 -d config.b64 > config.bin"` — OK (операция на сервере)
**Если нужно передать файл на сервер** — используй `--upload`. Если файл уже существует локально — заливай напрямую. Если нужно создать новый файл с нуля — создай локально (Write tool), потом `--upload`.
**Если нужно прочитать файл с сервера** — используй `ALIAS "cat /path/file"` для маленьких текстовых, или `--download` для больших/бинарных.