From 216af78d4d80571d92b64e055d13f20548ca60c0 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Fri, 5 Jun 2026 15:42:27 +0800 Subject: [PATCH] sshkeeper: add comprehensive user guide (docs/guide.md) --- README.md | 4 + docs/guide.md | 688 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 692 insertions(+) create mode 100644 docs/guide.md diff --git a/README.md b/README.md index e7d85c0..24e8ef9 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,10 @@ Commands that need secrets ask for the master password in that process. Adding `password` or `key_passphrase` profiles asks for the master password before storing the secret. +## Руководство + +Подробная инструкция с примерами сценариев: [docs/guide.md](docs/guide.md) + ## TUI Running `sshkeeper` without arguments opens the TUI. diff --git a/docs/guide.md b/docs/guide.md new file mode 100644 index 0000000..bb55ad9 --- /dev/null +++ b/docs/guide.md @@ -0,0 +1,688 @@ +# sshkeeper — Руководство пользователя + +## Содержание + +1. [Что такое sshkeeper](#что-такое-sshkeeper) +2. [Установка](#установка) +3. [Первый запуск](#первый-запуск) +4. [TUI — основной интерфейс](#tui--основной-интерфейс) +5. [Управление серверами](#управление-серверами) +6. [Маршруты и бастионы](#маршруты-и-бастионы) +7. [Port Forwards и Tunnels](#port-forwards-и-tunnels) +8. [CLI команды](#cli-команды) +9. [Vault — хранилище секретов](#vault--хранилище-секретов) +10. [Сценарии использования](#сценарии-использования) +11. [Справка по клавишам](#справка-по-клавишам) + +--- + +## Что такое sshkeeper + +sshkeeper — это консольный менеджер SSH-подключений для Linux. Он хранит профили серверов, секреты (пароли, фразы от ключей) и запускает системный `ssh` с нужными опциями. + +**Чем sshkeeper НЕ является:** +- Это не Ansible — он не настраивает серверы и не пушит файлы +- Это не замена SSH — он использует системный `/usr/bin/ssh` + +**Что он делает:** +- Хранит профили серверов в локальной SQLite-базе +- Хранит пароли в зашифрованном vault (XChaCha20-Poly1305) +- Управляет маршрутами (бастионы, цепочки прыжков) +- Управляет port forwards (локальные, удалённые, SOCKS) +- Запускает туннели в фоне с отслеживанием PID +- Предоставляет TUI (текстовый интерфейс) и CLI + +**Стек технологий:** +- Go 1.25+ +- Bubble Tea (TUI framework) +- Cobra (CLI framework) +- SQLite (modernc.org/sqlite) +- XChaCha20-Poly1305 (шифрование vault) +- Argon2id (KDF для мастер-пароля) + +**Исходники:** `git.mirv.top:mirivlad/sshkeeper` + +--- + +## Установка + +### Из релиза + +```bash +tar -xzf sshkeeper_v0.2.0_linux_amd64.tar.gz +chmod +x sshkeeper-linux-amd64 +sudo install -m 0755 sshkeeper-linux-amd64 /usr/local/bin/sshkeeper +``` + +### Из исходников + +```bash +git clone git@git.mirv.top:mirivlad/sshkeeper.git +cd sshkeeper +go build -o ~/.local/bin/sshkeeper . +``` + +Или через скрипт: +```bash +./build.sh # сборка в bin/ +./release.sh # сборка релизных архивов в dist/ +``` + +**Требования:** Go 1.25+, Linux x86_64, системный OpenSSH. + +--- + +## Первый запуск + +При первом запуске sshkeeper создаёт конфигурацию, базу данных и vault: + +```bash +sshkeeper +``` + +Вы увидите приветствие и запрос на создание мастер-пароля: + +``` +Welcome to sshkeeper! +No vault found. Let's create one. + +Create master password: ******** +Repeat master password: ******** + +Vault created and unlocked for this command. You're ready to go! +``` + +**Важно:** запомните мастер-пароль. Без него секреты не восстановить. + +После создания vault откроется главный экран TUI со списком серверов (пока пустым). + +--- + +## TUI — основной интерфейс + +Запуск TUI — просто `sshkeeper` без аргументов. + +### Главный экран + +``` +sshkeeper 0 servers +Vault unlocked | 0 OK | 0 FAIL + + NAME ALIAS ROUTE AUTH GROUP STATUS + + No servers yet. Press Ctrl+A to add one. + + Enter: connect | Ctrl+X: actions | Ctrl+A: add | Ctrl+E: edit + Ctrl+F: search | Ins: select | ?: help | Ctrl+Q: quit +``` + +**Столбцы:** +- **NAME** — отображаемое имя сервера +- **ALIAS** — уникальный идентификатор +- **ROUTE** — маршрут подключения: + - ` direct → user@host:port` — прямое подключение + - `→ bastion → user@host:port` — через бастион + - `→ bastion → … → user@host:port` — через цепочку +- **AUTH** — метод аутентификации (key/password/agent/key+phrase) +- **GROUP** — группа сервера +- **STATUS** — результат последнего теста (OK/FAIL/?) + +**Навигация:** +- `↑/↓` — перемещение по списку +- `Enter` — подключиться к серверу +- `Ctrl+A` — добавить сервер +- `Ctrl+E` — редактировать сервер +- `Ctrl+X` — меню действий +- `Ctrl+F` — поиск +- `Ins` — выбрать/снять выбор (для групповых операций) +- `?` или `F1` — полная справка +- `Ctrl+Q` — выход + +### Экран помощи + +Нажмите `?` или `F1` на любом экране: + +``` +sshkeeper — Help + + Enter Connect to server + ↑/↓ Navigate list + Tab/↓ Next field + Shift+Tab/↑ Previous field + / Open dropdown picker + Esc Back / Cancel + Ctrl+A Add server + Ctrl+E Edit server + Ctrl+W Manage port forwards + Ctrl+X Action menu + ? This help screen + Ctrl+Q Quit +``` + +--- + +## Управление серверами + +### Добавление сервера + +1. Нажмите `Ctrl+A` на главном экране +2. Заполните поля: + +``` +Add Server + + Alias: mail.kp + Display Name: Production mail + Host: mail.example.org + Port: 22 + User: root + Auth Method: key + Identity File: ~/.ssh/id_ed25519 + Route hops: bastion + Group: KP + Notes: Main mail server + Startup Command: tmux attach -t ops + Tags: prod, mail + + [ Test ] [ Save ] + + Tab/↓: next | ↑: prev | /: pick list | Enter: select | Esc: back +``` + +**Навигация по форме:** +- `Tab` или `↓` — следующее поле +- `Shift+Tab` или `↑` — предыдущее поле +- `/` на поле Auth Method — выбрать из списка (password/key/key_passphrase/agent) +- `/` на поле Group — выбрать из существующих групп +- `Enter` на кнопке Test — проверить подключение +- `Enter` на кнопке Save — сохранить +- `Esc` — отмена + +### Редактирование сервера + +1. Выберите сервер стрелками +2. Нажмите `Ctrl+E` +3. Отредактируйте поля +4. Нажмите `Enter` на Save + +### Удаление сервера + +1. Выберите сервер стрелками +2. Нажмите `Ctrl+X` (меню действий) +3. Выберите "Delete" +4. Подтвердите: `Enter` или `Y` — да, `Esc` или `N` — нет + +### Тест подключения + +1. Выберите сервер стрелками +2. Нажмите `Ctrl+X` → "Test connection" +3. Результат отобразится в столбце STATUS (OK/FAIL) + +### Поиск + +1. Нажмите `Ctrl+F` +2. Введите запрос (поиск по alias, name, host, user, group, notes, tags) +3. `Enter` — применить фильтр +4. `Esc` — сбросить + +--- + +## Маршруты и бастионы + +### Прямое подключение + +Сервер подключается напрямую: + +``` +ROUTE: direct → root@web.example.org:22 +``` + +### Через бастион + +Сервер доступен через один jump host: + +``` +ROUTE: → bastion → root@internal.web:22 +``` + +### Цепочка прыжков + +Сервер доступен через несколько jump hosts: + +``` +ROUTE: → bastion → dmz-gw → … → root@secure.internal:22 +``` + +### Настройка маршрута + +**Через TUI:** +1. Добавьте/редактируйте сервер +2. В поле "Route hops" введите бастионы через запятую: `bastion,dmz-gw` +3. Или введите адрес напрямую: `user@bastion.example.com:2222` + +**Через CLI:** +```bash +sshkeeper route set web --jumps bastion +sshkeeper route set prod --jumps bastion,dmz-gw +sshkeeper route show web +sshkeeper route clear web +``` + +--- + +## Port Forwards и Tunnels + +### Ключевое различие + +- **Port Forward** — сохранённое правило проброса порода. Просто конфигурация, не запускает процесс. +- **Tunnel** — запущенный SSH-процесс, который активирует один или несколько forwards. + +Аналогия: forward — это рецепт, tunnel — это готовое блюдо. + +### Типы forwards + +| Тип | Описание | Пример | +|-----|----------|--------| +| **Local** | Порт на вашей машине → сервис за SSH-сервером | Локальный 5432 → удалённый PostgreSQL | +| **Remote** | Порт на SSH-сервере → сервис на вашей машине | Удалённый 8080 → локальный dev-сервер | +| **SOCKS** | Локальный SOCKS-прокси через SSH | Браузер → SOCKS → интернет через SSH-сервер | + +### Управление forwards через TUI + +1. Выберите сервер на главном экране +2. Нажмите `Ctrl+X` → "Manage port forwards" +3. Откроется список forwards: + +``` +Port Forwards — web + + NAME TYPE LISTEN TARGET ON + Local PostgreSQL Local 127.0.0.1:15432 127.0.0.1:5432 yes + Web Admin Local 127.0.0.1:18080 internal.web:80 yes + SOCKS Proxy SOCKS 127.0.0.1:1080 SOCKS yes + + Selected + Port 127.0.0.1:15432 on this machine will be forwarded through web to 127.0.0.1:5432. + -L 127.0.0.1:15432:127.0.0.1:5432 + -o ExitOnForwardFailure=yes + + Ctrl+A: add | Ctrl+E/Enter: edit | Ctrl+D: delete | Esc: back +``` + +**Действия:** +- `Ctrl+A` — добавить forward +- `Enter` или `Ctrl+E` — редактировать выбранный +- `Ctrl+D` — удалить (с подтверждением) +- `Esc` — назад + +### Добавление forward + +1. Нажмите `Ctrl+A` на экране forwards +2. Выберите тип (1/2/3 или Tab): + +``` +Add Port Forward + + Name: Local PostgreSQL + Description: optional + + Type + ▸ 1. Local port on my machine → service on SSH server + 2. Remote port on SSH server → service on my machine + 3. SOCKS local dynamic SOCKS proxy through SSH + + Listen Address: 127.0.0.1 + Listen Port: 15432 + Target Host: 127.0.0.1 + Target Port: 5432 + + Preview + -L 127.0.0.1:15432:127.0.0.1:5432 + -o ExitOnForwardFailure=yes + + [ Save ] + + Tab/↓: next | ↑: prev | 1/2/3: select type | Enter: save | Esc: back +``` + +**Поля зависят от типа:** +- **Local:** Listen Address, Listen Port, Target Host, Target Port +- **Remote:** Remote Listen Addr, Remote Listen Port, Local Target Host, Local Target Port +- **SOCKS:** Listen Address, Listen Port (target поля скрыты) + +**По умолчанию Listen Address = `127.0.0.1`** (только локальный доступ). Если введёте `0.0.0.0`, появится предупреждение. + +### Запуск туннеля + +**Через TUI:** +1. Выберите сервер +2. Нажмите `Ctrl+X` → один из вариантов: + - **Connect with tunnels** — SSH-сессия + все активные forwards + - **Start tunnels only** — туннель на переднем плане, без shell + - **Start tunnels in background** — туннель в фоне с PID + +**Через CLI:** +```bash +# SSH-сессия с туннелями +sshkeeper tunnel web + +# Только туннель (foreground) +sshkeeper tunnel web --forward-only + +# Туннель в фоне +sshkeeper tunnel web --background +``` + +### Управление туннелями + +**Через TUI:** +1. Нажмите `Ctrl+X` → "Manage tunnels" +2. Список запущенных туннелей: + +``` +Tunnel Manager + + Tunnel to web PID 12345 running 2m30s + Tunnel to prod PID 12346 running 1m15s + + Ctrl+D: stop | Ctrl+R: refresh | Esc: back +``` + +**Через CLI:** +```bash +sshkeeper tunnel list +sshkeeper tunnel stop +``` + +--- + +## CLI команды + +### Серверы + +```bash +# Добавление +sshkeeper add web --host 10.0.0.10 --user deploy --auth key +sshkeeper add prod --host 10.0.0.20 --user root --auth password +sshkeeper add bastion --host bastion.example.org --user admin --auth key_passphrase --identity-file ~/.ssh/id_rsa + +# Интерактивный режим +sshkeeper add + +# Просмотр +sshkeeper list +sshkeeper show web +sshkeeper search prod + +# Подключение +sshkeeper connect web +sshkeeper c web # короткая форма + +# Выполнение команды +sshkeeper run web "uptime" + +# Тест подключения +sshkeeper test web + +# Редактирование +sshkeeper edit web --tags prod,web --startup-command "tmux attach -t ops" + +# Удаление +sshkeeper delete web +``` + +### Маршруты + +```bash +sshkeeper route set web --jumps bastion +sshkeeper route set prod --jumps bastion,dmz-gw +sshkeeper route show web +sshkeeper route clear web +``` + +### Port Forwards + +```bash +# Добавление +sshkeeper forward add web --name "Local PostgreSQL" --type local --local-port 15432 --remote-addr 127.0.0.1 --remote-port 5432 +sshkeeper forward add bastion --name "SOCKS Proxy" --type dynamic --local-port 1080 + +# Список +sshkeeper forward list web + +# Удаление +sshkeeper forward delete web 1 +``` + +### Tunnels + +```bash +sshkeeper tunnel web # SSH + туннели +sshkeeper tunnel web --forward-only # Только туннель +sshkeeper tunnel web --background # Фоновый туннель +sshkeeper tunnel list # Список туннелей +sshkeeper tunnel stop # Остановить +``` + +### Группы и шаблоны + +```bash +sshkeeper group list +sshkeeper group rename old new +sshkeeper group delete name + +sshkeeper template list +sshkeeper template add uptime "uptime" +sshkeeper template delete uptime +sshkeeper run-template web uptime +``` + +### Vault + +```bash +sshkeeper vault status +sshkeeper vault unlock +sshkeeper vault list +sshkeeper vault delete web ssh_password +sshkeeper vault change-password +``` + +### Импорт/Экспорт + +```bash +sshkeeper import # Импорт из ~/.ssh/config +sshkeeper export # Экспорт в stdout +``` + +--- + +## Vault — хранилище секретов + +Vault хранит SSH-пароли и фразы от ключей в зашифрованном виде. + +**Шифрование:** XChaCha20-Poly1305, KDF: Argon2id (64 MiB, 3 iterations) + +**Когда нужен мастер-пароль:** +- `connect`, `c` — для подключения с password/key_passphrase аутентификацией +- `run`, `run-template` — для выполнения команд +- `test` — для тестирования +- `edit`, `delete` — для редактирования секретов +- `vault` команды + +**Когда НЕ нужен:** +- `list`, `show`, `search` — только метаданные +- `add` с auth=key или auth=agent +- `export`, `ssh-config` + +--- + +## Сценарии использования + +### Сценарий 1: Подключение к серверу через бастион + +```bash +# 1. Добавляем бастион +sshkeeper add bastion --host bastion.example.org --user admin --auth key + +# 2. Добавляем внутренний сервер с маршрутом через бастион +sshkeeper add web --host 10.0.0.10 --user deploy --auth key +sshkeeper route set web --jumps bastion + +# 3. Подключаемся +sshkeeper connect web +# Автоматически: ssh -J bastion deploy@10.0.0.10 +``` + +### Сценарий 2: Локальный доступ к удалённой базе данных + +```bash +# 1. Добавляем сервер +sshkeeper add db --host db.internal --user postgres --auth key + +# 2. Создаём forward +sshkeeper forward add db --name "PostgreSQL" --type local --local-port 15432 --remote-addr 127.0.0.1 --remote-port 5432 + +# 3. Запускаем туннель в фоне +sshkeeper tunnel db --background +# ✓ Tunnel started [12345] PID 67890 → db + +# 4. Подключаемся локально +psql -h 127.0.0.1 -p 15432 -U myuser mydb + +# 5. Когда не нужен — останавливаем +sshkeeper tunnel stop 12345 +``` + +### Сценарий 3: SOCKS-прокси для браузера + +```bash +# 1. Добавляем сервер +sshkeeper add jump --host jump.example.org --user me --auth key + +# 2. Создаём SOCKS forward +sshkeeper forward add jump --name "SOCKS" --type dynamic --local-port 1080 + +# 3. Запускаем туннель +sshkeeper tunnel jump --background + +# 4. Настраиваем браузер: SOCKS5 127.0.0.1:1080 +``` + +### Сценарий 4: Цепочка прыжков + +```bash +# Сервер за двумя бастионами +sshkeeper add secure --host 10.10.10.10 --user root --auth key +sshkeeper route set secure --jumps bastion,dmz-gw + +# Подключение +sshkeeper connect secure +# Автоматически: ssh -J bastion,dmz-gw root@10.10.10.10 +``` + +### Сценарий 5: Групповые операции + +```bash +# В TUI: выбрать несколько серверов (Ins), затем: +# Ctrl+X → Run template → выбрать шаблон +# Команда выполнится на всех выбранных серверах +``` + +--- + +## Справка по клавишам + +### Главный экран + +| Клавиша | Действие | +|---------|----------| +| `Enter` | Подключиться к серверу | +| `Ctrl+A` | Добавить сервер | +| `Ctrl+E` | Редактировать сервер | +| `Ctrl+F` | Поиск | +| `Ctrl+X` | Меню действий | +| `Ins` | Выбрать/снять выбор | +| `?` / `F1` | Помощь | +| `Ctrl+Q` | Выход | + +### Меню действий (Ctrl+X) + +- **Connect** — стандартное SSH-подключение +- **Connect with tunnels** — SSH + все активные forwards +- **Start tunnels only** — туннель без shell +- **Start tunnels in background** — фоновый туннель +- **Manage port forwards** — управление forwards +- **Manage tunnels** — список туннелей +- **Manage route** — настройка маршрута +- **Test connection** — проверка подключения +- **Edit** — редактирование сервера +- **Delete** — удаление (с подтверждением) + +### Формы (добавление/редактирование) + +| Клавиша | Действие | +|---------|----------| +| `Tab` / `↓` | Следующее поле | +| `Shift+Tab` / `↑` | Предыдущее поле | +| `/` | Выбрать из списка (Auth Method, Group) | +| `Enter` | Действие / переход | +| `Esc` | Назад / отмена | + +### Список forwards + +| Клавиша | Действие | +|---------|----------| +| `↑/↓` | Навигация | +| `Ctrl+A` | Добавить | +| `Enter` / `Ctrl+E` | Редактировать | +| `Ctrl+D` | Удалить (с подтверждением) | +| `Esc` | Назад | + +### Список туннелей + +| Клавиша | Действие | +|---------|----------| +| `Ctrl+D` / `s` | Остановить туннель | +| `Ctrl+R` / `r` | Обновить список | +| `Esc` | Назад | + +### Диалог подтверждения + +| Клавиша | Действие | +|---------|----------| +| `Enter` / `Y` | Да | +| `Esc` / `N` | Нет | + +--- + +## Расположение данных + +| Данные | Путь | +|--------|------| +| Конфиг | `~/.config/sshkeeper/config.toml` | +| База данных | `~/.local/share/sshkeeper/sshkeeper.db` | +| Vault | `~/.local/share/sshkeeper/vault.bin` | +| Туннели | `~/.local/share/sshkeeper/tunnels.json` | +| OpenSSH config | `~/.ssh/config.d/sshkeeper.conf` | + +Если заданы `XDG_CONFIG_HOME` или `XDG_DATA_HOME`, данные хранятся в соответствующих поддиректориях. + +--- + +## Сборка и тестирование + +```bash +# Тесты +go test ./... + +# Сборка +go build -o bin/sshkeeper . + +# Или через скрипты +./build.sh # сборка в bin/ +./release.sh # релизные архивы в dist/ +``` + +## Лицензия + +MIT. См. [LICENSE](LICENSE).