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