192 lines
16 KiB
Markdown
192 lines
16 KiB
Markdown
# Руководство администратора
|
||
|
||
Практическое руководство по экранам `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).
|