Files
ssh-access-tui/docs/ADMIN_GUIDE.md
T

210 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-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`, а **набрать вручную короткую случайную строку**, которую
инструмент показывает на экране подтверждения (например `kqzvm-482`) — она
каждый раз новая. Неверный ввод просто откатывает к полю ввода с пояснением
«не совпадает», ничего не меняя; `esc` отменяет действие полностью в любой
момент. Это защита именно от «промахнулся мимо enter» — набрать чужую
случайную строку по ошибке невозможно.
## Главное меню
```
Пользователи — создать / заблокировать / разблокировать / удалить
Хосты и сервисы — общий каталог адресов и портов (один раз на всех)
Группы — какие хосты из каталога входят в каждую группу
Экспорт архивов — сгенерировать ключи и .7z для доставки
Аудит / кто в сети — активные сессии и журнал подключений
Выход
```
Имена хостов, сервисов и групп должны быть без пробелов (латиница, цифры,
`. _ -`) — они попадают в конфиг и в `authorized_keys`; инструмент откажет с
понятной ошибкой, если ввести имя с пробелом.
## Модель: каталог → группы → пользователи
Хосты и их сервисы (порты) описываются **один раз** в общем каталоге
(«Хосты и сервисы»), а не заново для каждой группы. Группа — это просто
отметка галочками, какие хосты каталога в неё входят (все сервисы такого
хоста включаются целиком). Если у вас в разных группах фигурируют одни и те
же хосты/сервисы — их не нужно набивать повторно, только отметить нужные
для очередной группы. Пользователь состоит в одной или нескольких группах;
его реальный доступ — объединение сервисов всех хостов всех его групп.
## Сценарий 1: новый сотрудник, у которого уже есть роль/группа доступа
Обычно каталог и группы настраивают заранее (или один раз добавляют то,
чего не хватает), потом заводят пользователей пачками.
1. **Хосты и сервисы** → `n` → имя хоста (например `db-prod-1`), адрес (как
виден с jump-хоста), описание (необязательно) → `enter`. Сразу
открывается список сервисов этого хоста (изначально пуст).
2. `n` → имя сервиса (например `ssh` или `web-api`), порт на хосте
(например `22` или `7888`), описание (необязательно) → `enter`. Повторите
`n` для каждого сервиса на этом хосте.
3. `esc` — назад к списку хостов; повторите шаги 1-2 для остальных хостов,
затем `esc` — в главное меню. Если хост/сервис уже существует и нужно
только поправить адрес/порт/описание — `e` вместо `n` на нужной записи
(можно поменять и имя — все группы, которые ссылались на старое имя,
автоматически обновятся).
4. **Группы** → `n` → имя группы (например `team-billing`), описание
(необязательно) → `enter`.
5. Выбрать группу → `enter` → отметить `space` нужные хосты из каталога →
`enter` сохранить. Список сервисов этих хостов достаётся группе целиком.
6. **Пользователи** → `n` → имя пользователя (латиницей, будущий Linux-логин)
и комментарий (например ФИО) → `enter`.
7. Отметить `space` нужные группы (можно несколько) → `enter`.
Это уже создаёт системный Linux-аккаунт (без пароля, без интерактивного
шелла) и запись в состоянии. **Ключ ещё не выдан** — статус в списке
пользователей покажет «ключ не выдан».
8. **Экспорт архивов** → отметить `space` только что созданного пользователя
(или `a` — отметить всех, удобно при пакетном найме) → `enter`. Для
пользователей без ключа архив генерируется сразу, без лишних вопросов —
это не деструктивное действие. Инструмент сгенерирует ключ, пропишет
`permitopen=` под текущие сервисы группы и соберёт `.7z`, показав **один
общий пароль на всю партию** — он показывается один раз,
запишите/скопируйте сразу.
9. Передайте каждому пользователю его архив (файл, путь показан на экране,
лежит в `export_dir`) любым каналом, а пароль от архива — **отдельным**
каналом (голосом, в личку) и по возможности не всем одним и тем же
сообщением в общем чате.
10. Пользователь распаковывает архив на Windows по инструкции
`INSTRUCTIONS.txt` внутри архива — она на простом русском языке, без
технических терминов: положить файлы в папку, ввести одну команду и
держать окно открытым, дальше список «такой адрес у вас локально → что
это → где реально находится», составленный под конкретные сервисы этого
пользователя.
## Сценарий 1а: изменить группы уже существующего пользователя
**Пользователи** → выбрать пользователя → `g` → отметить/снять `space`
нужные группы → `enter`. Если у пользователя уже выдан ключ, инструмент
сразу пересоберёт его `permitopen=` под новый набор сервисов — доступ
меняется немедленно, без переотправки архива и **без замены ключа**
(изменение групп никогда не ротирует ключ).
Если хотите, чтобы у пользователя появился ещё и обновлённый клиентский
`config` с новыми адресами для новых сервисов (иначе он про них просто не
узнает, хотя доступ уже есть) — **Пользователи** → выбрать пользователя →
`c` («обновить конфиг»). Это генерирует маленький архив только с `config` +
`INSTRUCTIONS.txt` (без ключа — ключ у пользователя уже есть и остаётся тем
же), пользователю нужно только подменить файл `config`. Не требует
подтверждения — ключ и доступ этим действием не меняются, это не
деструктивно.
Полный экспорт (сценарий 1, шаги 8-9) тоже сработает и даст то же самое
плюс заново выпустит ключ (с подтверждением строкой, раз это перевыпуск) —
используйте `c`, когда переиздание ключа не нужно.
## Сценарий 2: добавили новый сервис/хост, поменялся адрес или порт
- Новый сервис на существующем хосте: **Хосты и сервисы** → выбрать хост →
`enter` → `n`.
- Новый хост: **Хосты и сервисы** → `n`, затем добавить ему сервисы.
- Хост сменил адрес, сервис — порт, нужно поправить описание, или
переименовать: `e` на нужной записи. Переименование хоста автоматически
обновляет ссылки на него во всех группах, которые его используют — группы
не «отваливаются» молча.
Любое из этих изменений сразу обновляет `permitopen=` в `authorized_keys`
**всех активных пользователей всех групп**, ссылающихся на этот хост, —
доступ появляется немедленно, без каких-либо действий на стороне
пользователя. Клиентский конфиг пользователя (его `~/.ssh/config`) при этом
не обновляется автоматически — для этого используйте **Пользователи** → `c`
(«обновить конфиг», см. сценарий 1а).
**Группы** → выбрать группу → `enter` — там же можно снять/добавить
привязку группы к хостам каталога (не создавая и не удаляя сами хосты).
Удаление хоста из каталога, сервиса на хосте или целой группы (`d` в
соответствующем списке) — все три действия **деструктивны** (мгновенно
отбирают доступ у всех затронутых пользователей) и требуют набрать
случайную строку подтверждения: экран покажет, что именно удаляется,
сколько пользователей это коснётся, и в каких группах используется
(для хоста/сервиса).
## Сценарий 3: сотрудник уволился
1. **Пользователи** → выбрать пользователя → `l` (заблокировать) → набрать
строку подтверждения, которую покажет экран → `enter`.
Блокировка — это одновременно: блокирует пароль аккаунта, устанавливает
немедленный срок истечения аккаунта (`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#бэкап-и-аварийное-восстановление).
Коротко: состояние (каталог хостов/сервисов, группы, пользователи,
публичные ключи, статусы) — git-репозиторий, бэкапится часовым таймером в
удалённый git. На новом хосте: поднять `ssh-access-tui`, влить `state.yaml`
из бэкапа, создать системные Linux-аккаунты для активных пользователей,
выпустить им новые ключи через **Экспорт архивов** (старые приватные ключи
специально нигде не хранятся — это не баг, см. архитектурный документ).
## Что не делает эта версия (нужно руками)
- Не удаляет `.7z` из `export_dir` после доставки — сделайте это сами,
когда получатель подтвердил, что распаковал архив (это касается и
архивов от «обновить конфиг», хоть они и не содержат ключ).
- Не обновляет клиентский `~/.ssh/config` пользователя автоматически при
появлении нового сервиса/хоста в его группе — это ручной шаг («обновить
конфиг», сценарий 1а), права доступа на сервере при этом обновляются
немедленно и без участия администратора (см. сценарий 2).
- Не поддерживает одновременную работу нескольких администраторов —
рассчитан на одного за раз (см. «Конкурентность» в ARCHITECTURE.md).