Files
ssh-access-tui/docs/ADMIN_GUIDE.md
T
2026-07-22 15:14:44 +03:00

192 lines
16 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-access-tui` и типовым сценариям.
Архитектурные решения и модель угроз — в [ARCHITECTURE.md](ARCHITECTURE.md).
## Запуск
```sh
sudo ssh-access-tui
```
Требует root (создаёт/блокирует системных пользователей, правит
`authorized_keys`). Инструмент рассчитан на **одного** администратора
одновременно на хосте — если кто-то ещё уже открыл TUI, вторая сессия
получит ошибку про занятую блокировку состояния (`state.lock`), а не молча
перезапишет чужие изменения.
Навигация везде: стрелки/`j`/`k` — перемещение по списку, `enter` —
выбрать/подтвердить, `esc` — назад, `ctrl+c` — жёсткий выход в любой момент
(без каких-либо предупреждений — только для аварийных случаев). Обычный
выход через пункт меню «Выход» или `q` в главном меню предупредит, если
есть созданные, но ни разу не экспортированные пользователи (у них ещё нет
ключа) — можно выйти всё равно (`enter`/`y`) или вернуться (`esc`/`n`).
Любое деструктивное действие (блокировка/удаление пользователя, удаление
хоста или сервиса) сначала показывает отдельный экран подтверждения с
пояснением последствий — ничего не происходит до `enter`/`y`; `esc`/`n`
отменяет без каких-либо изменений.
## Главное меню
```
Пользователи — создать / заблокировать / разблокировать / удалить
Группы и хосты — какие внутренние хосты кому разрешены
Экспорт архивов — сгенерировать ключи и .7z для доставки
Аудит / кто в сети — активные сессии и журнал подключений
Выход
```
Имена групп, хостов и сервисов должны быть без пробелов (латиница, цифры,
`. _ -`) — они попадают в конфиг и в `authorized_keys`; инструмент откажет с
понятной ошибкой, если ввести имя с пробелом.
## Сценарий 1: новый сотрудник, у которого уже есть роль/группа доступа
Обычно сначала настраивают группу (один раз), потом заводят пользователей в
неё пачками. Иерархия: **группа** → **хосты** → **сервисы (порты) на хосте**
— на одном хосте может быть несколько сервисов (например, `ssh` на 22 и
`web-api` на 7888), каждый добавляется отдельно.
1. **Группы и хосты** → `n` → ввести имя группы (например `team-billing`) →
`enter`.
2. Выбрать группу → `enter`, попасть в список хостов группы (изначально
пуст).
3. `n` → заполнить: имя хоста (короткое, например `db-prod-1`), адрес (как
виден с jump-хоста) → `tab` между полями → `enter`. Сразу после этого
попадаете в список сервисов этого хоста (тоже изначально пуст).
4. `n` → заполнить сервис: имя (например `ssh` или `web-api`), порт на
хосте (например `22` или `7888`), описание (необязательно) → `enter`.
Повторите `n` столько раз, сколько сервисов есть на этом хосте.
5. `esc` — назад к списку хостов группы; повторите шаги 3-4 для остальных
хостов группы, затем `esc` дважды — назад в главное меню.
6. **Пользователи** → `n` → имя пользователя (латиницей, будущий Linux-логин)
и комментарий (например ФИО) → `enter`.
7. Отметить `space` нужные группы (можно несколько — эффективный доступ
пользователя = объединение сервисов всех хостов всех отмеченных групп) →
`enter`.
Это уже создаёт системный Linux-аккаунт (без пароля, без интерактивного
шелла) и запись в состоянии. **Ключ ещё не выдан** — статус в списке
пользователей покажет «ключ не выдан».
8. **Экспорт архивов** → отметить `space` только что созданного пользователя
(или `a` — отметить всех, удобно при пакетном найме) → `enter`. Список
сразу показывает у каждого пользователя, будет ли выдан новый ключ или
существующий будет **перевыпущен** (актуально, если случайно попадёт в
выборку уже работающий пользователь).
9. Экран подтверждения: для тех, у кого ключ уже был, явно предупредит, что
старый архив перестанет работать — только после `enter`/`y` (либо `esc`/`n`
для отмены, тогда не создаётся и не меняется вообще ничего) инструмент
сгенерирует ключ, пропишет `permitopen=` под текущие сервисы группы и
соберёт `.7z`, показав **один общий пароль на всю партию** — он
показывается один раз, запишите/скопируйте сразу.
10. Передайте каждому пользователю его архив (файл, путь показан на экране,
лежит в `export_dir`) любым каналом, а пароль от архива — **отдельным**
каналом (голосом, в личку) и по возможности не всем одним и тем же
сообщением в общем чате.
11. Пользователь распаковывает архив на Windows по инструкции
`INSTRUCTIONS.txt` внутри архива — она уже на простом русском языке,
без технических терминов: просто список "локальный адрес → какой это
сервис → куда он реально ведёт", составленный под конкретные разрешённые
сервисы этого пользователя.
## Сценарий 1а: изменить группы уже существующего пользователя
**Пользователи** → выбрать пользователя → `g` → отметить/снять `space`
нужные группы → `enter`. Если у пользователя уже выдан ключ, инструмент
сразу пересоберёт его `permitopen=` под новый набор сервисов — доступ
меняется немедленно, без переотправки архива и **без замены ключа**
(изменение групп никогда не ротирует ключ).
Если хотите, чтобы у пользователя появился ещё и обновлённый клиентский
`config` с новыми `LocalForward` для новых сервисов (иначе он про них
просто не узнает, хотя доступ уже есть) — **Пользователи** → выбрать
пользователя → `c` («обновить конфиг»). Это генерирует маленький архив
только с `config` + `INSTRUCTIONS.txt` (без ключа — ключ у пользователя уже
есть и остаётся тем же), пользователю нужно только подменить файл `config`.
Не требует подтверждения — ключ и доступ этим действием не меняются, это не
деструктивно.
Полный экспорт (со сценария 1, шаги 8-9) тоже сработает и даст то же самое
плюс заново выпустит ключ — используйте `c`, когда переиздание ключа не
нужно (обычный случай при простом изменении групп).
## Сценарий 2: добавили новый сервис/хост существующей группе
1. **Группы и хосты** → выбрать группу → `enter`.
2. Либо `n` — новый хост (затем добавить ему хотя бы один сервис), либо
выбрать существующий хост → `enter` → `n` — новый сервис на нём.
Это сразу обновляет `permitopen=` в `authorized_keys` **всех активных
пользователей** этой группы — доступ появляется немедленно, без каких-либо
действий на стороне пользователя. Клиентский конфиг пользователя (его
`~/.ssh/config`) при этом не обновляется автоматически — если хотите, чтобы
у пользователя появилась готовая строка `LocalForward` для нового сервиса, а
не только "голый" доступ на сервере, используйте **Пользователи** → `c`
(«обновить конфиг») — ключ при этом не меняется (см. сценарий 1а).
Удаление сервиса или целого хоста (`d` в соответствующем списке) — оба
действия **деструктивны** (мгновенно отбирают доступ у всех пользователей
группы) и требуют подтверждения: экран покажет, что именно удаляется и
скольких пользователей это коснётся, `enter`/`y` подтверждает, `esc`/`n`
отменяет без каких-либо изменений.
## Сценарий 3: сотрудник уволился
1. **Пользователи** → выбрать пользователя → `l` (заблокировать) → экран
подтверждения объяснит, что произойдёт → `enter`/`y`.
Блокировка — это одновременно: блокирует пароль аккаунта, устанавливает
немедленный срок истечения аккаунта (`chage -E 1`) и комментирует его ключ в
`authorized_keys` — три независимых механизма, чтобы блокировка не зависела
от одного из них. Статус в списке сменится на `locked`. Это **обратимо**.
Если сотрудник вернулся — `u` (разблокировать) на том же пользователе:
снимает блокировку аккаунта и восстанавливает его ключ в `authorized_keys`
с текущими правами групп. Разблокировка не деструктивна — подтверждения не
требует, срабатывает сразу.
Полное удаление аккаунта (`d`) — **необратимо** (`userdel -r`, домашняя папка
стирается) и тоже требует подтверждения (экран явно предупредит, что это
необратимо и что для временного отключения лучше использовать блокировку).
Используйте удаление только для окончательного оффбординга, не для
временной блокировки.
## Сценарий 4: проверить, кто сейчас подключён / посмотреть историю
**Аудит / кто в сети** показывает:
- «Сейчас в сети» — список активных SSH-сессий (по процессам `sshd:
user [priv]`, а не по `who`, потому что форвардинг-сессии без
интерактивного терминала не создают обычных login-записей);
- «Последние события» — журнал подключений/отключений, который в фоне
собирает `ssh-access-tui-audit.service` из `journalctl`, независимо от
ротации системного журнала.
`r` — обновить оба списка. Если журнал подключений пуст, хотя пользователи
явно заходили — проверьте, что фоновый сервис запущен:
`systemctl status ssh-access-tui-audit.service`.
## Сценарий 5: перенос на новый хост / хост умер
См. подробности в [ARCHITECTURE.md](ARCHITECTURE.md#бэкап-и-аварийное-восстановление).
Коротко: состояние (`groups`, `users`, публичные ключи, статусы) —
git-репозиторий, бэкапится часовым таймером в удалённый git. На новом хосте:
поднять `ssh-access-tui`, влить `state.yaml` из бэкапа, создать системные
Linux-аккаунты для активных пользователей, выпустить им новые ключи через
**Экспорт архивов** (старые приватные ключи специально нигде не хранятся —
это не баг, см. архитектурный документ).
## Что не делает эта версия (нужно руками)
- Не удаляет `.7z` из `export_dir` после доставки — сделайте это сами,
когда получатель подтвердил, что распаковал архив (это касается и
архивов от «обновить конфиг», хоть они и не содержат ключ).
- Не обновляет клиентский `~/.ssh/config` пользователя автоматически при
появлении нового сервиса/хоста в его группе — это ручной шаг («обновить
конфиг», сценарий 1а), права доступа на сервере при этом обновляются
немедленно и без участия администратора (см. сценарий 2).
- Не поддерживает одновременную работу нескольких администраторов —
рассчитан на одного за раз (см. «Конкурентность» в ARCHITECTURE.md).